Data Mapper will map your database objects to real world objects used in your application and back the other way (from real work objects to database objects). You would use this as you may have properties on your database you don't want to show outside your app. An example may be a createdDate, timestamp, or an encrypted value in the database. So your models may look something like
UserDatabaseModel (This is whats in your database)
Id
Name
Email (stored encrypted in the database)
CreatedDate
Timestamp
UserViewModel (This is what you want to show your user)
Id
Name (shown not encrypted)
Email
Your mapper would be responsible for maping a UserDatabaseModel to a UserViewModel and unencrypting the email (showing an encrypted email address to a user is pointless). And back the other way mapping a UserViewModel to a UserDatabaseModel and encrypting the email to store in your database. The Mapper will handle this behind the scenes so you don't have to worry about calling encrypt/decrypt all the time.
Unit of work and repository both work together. Unit of work controls a unit of work, so if for example updating a user actually updates 2 tables in your database, you would only want to save the details if both tables save. You wrap this in your unit of work (like a transaction in sql). Your repository is responsible for CRUDs or any other database actions. You would define the code that gets a user from the database or updates a user in your repository.
So updating the database from your code might look something like:
try{
uow = new UnitOfWork //start a new database transaction
repo = new UserRepository
repo.UpdateUser //calls database
repo.UpdateUserAddress //calls database
uow.Save //commit the database transaction
} catch {
uow.Rollback //something went wrong, rollback transaction
}