[main]: Add mdp to lecture notes

This commit is contained in:
John Gatward committed 2026-10-08 13:07:18 +01:00
1 parent 283096a43d
commit 4f85b781ea
70 files changed
+2759

No files matched your search

+199
View File
@@ -0,0 +1,199 @@
# Room and MVVM
## ROOM
### Room Persistence Library
- An architecture component
- A database layer on top of SQLite
- Takes care of tasks that `SQLiteHelper` dealt with
- Like compile-time validation of SQL queries
- Allows us to think about objects with fields rather than tables with rows
#### Room Components
![image-20220107154928136](img/ad.png)
###### Database
- Contains a database holder
- A singleton serves as the main access point to persistent data
###### Entities
- Java classes that represent (or become) tables in the database
###### DAO
- Data Access Object (software design pattern)
- An abstract interface for accessing the database to retrieve a given entity
#### Database
An abstract class that
- Is annotated with `@Database`
- Extends `RoomDatabase`
- Lists the entities associated with the database
- Includes abstract methods that return DAO interfaces for the entities
Is generally implemented as a **singleton** to retrieve a reference to the database with the application context
- Returned by `RoomDatabase.databaseBuilder`
A more structured approach to the database lifecycle
- `onCreate`, `onOpen`, `onDestructiveMigration`
- When the database schema is modified, we must define a migration strategy
Room **does not** support database access on the main thread
- Queries could take a while, so they shouldn’t be done on the main/UI thread
#### Entity
- Plain old Java class
- Represents a table in the underlying database
- Sets of related fields
- Annotated to describe how to think about it in terms of the database
- Needs to have a `@PrimaryKey`
- Field names become column names, unless we annotate an alternate
- `@ColumnInfo(name = 'my_column_name')`
- `@Ignore` certain fields
- Embedded entities, 1-to-1 or 1-to-many relationships
- `@Embedded`, `@Relation`, `@Transaction`
#### DAOs
- Interface / Abstract class
- Common practice to have one DAO per entity
- Implementation is created at compile time
Specify convenience queries, annotated to tell Room what to do
- `@Insert` generates an implementation that inserts all parameters into the database in a single transaction.
- `@Update` updates a set of entities given as parameters using a query that matches against the primary key of each entity.
- If the entity is updated, it will update the underlying SQL database
- `@Query` read/write operations as something like a conventional database query.
- `@Delete` removes entities given as parameters.
### MVVM Architecture
![image-20220107160502350](img/ae.png)
VIEW (UI controller) is the V
ViewModel is the current state of the data needed to populate the view
Room is the model; it is all the data for the entire application
ViewModel $\subset$ (is a subset of) Room Database
NOTE: Room is just the database manager, others exist.
Repository - as far as the view model is concerned, it asks the repository for all data. It abstracts access to different possible back-ends. The view model doesn’t need to know how the data is stored, e.g. whether data is stored on `data/.cache` or on a web server `ftp://192.168.0.5`.
The repository is responsible for connecting to the website and downloading data into cache to support functionality when the internet drops out.
**All view models** get their data from the **same repository**
# Coding Example
```java
import androidx.room.Entity
@Entity(tableName = "myTable")
public class Record {
@PrimaryKey
@NonNull
@ColumnInfo(name = "name") // only needed if they don't match
public Record(@NonNull String name, String colour) {
this.name = name;
...
}
}
```
Interface DAO
```java
//Can be an abstract class or interface
//Room will generate the implementation based on this
import androidx.room.Doa;
@Dao
public interface RecordDao {
@Insert
void insert (Record r);
@Insert(onConflict = OnConflictStrategy.IGNORE)
void insertLots (Record... r);
@Query("DELETE FROM myTable")
void deleteALl();
@Query("SELECT * FROM myTable ORDER BY name ASC")
List<Record> getAlphaRecord();
@Query("SELECT * FROM myTable")
LiveData<List<Record>> getAlphaRecord();
//LiveData is lifecycle aware
}
```
Boilerplate database stuff
```java
import androidx.room.RoomDatabase;
@Database(entities = {Record.class}, version=1, exportScheme=false)
public abstract class myDatabase extends RoomDatabase {
public abstract RecordDao();
private static volatile myDatabase INSTANCE;
//as we're not allowed to query on the main thread
static final ExecutorService dbWriter = Executors.newFixedThreadPool(4);
//context needed to know file path
static myDatabase getDatabse(final Context context) {
if (INSTANCE == null) {
synchronised (myDatabase.class) {
INSTANCE = Room.databaseBuilder(
context.getApplicationContext(),
myDatabase.class, "myDatabase")
.fallbackToDestructiveMigration()
.build();
}
}
}
}
```
Main Activity
```java
public class MainActivity extends .. {
myDatabase db;
RecordDao rDao;
protected onCreate (...){
db = myDatabase(getApplicationContext());
rDao = db.recordDao();
}
public void addNewRecord(){
myDatabase.dbWriter.execute(() -> {
Record r = new Record ("data", "data");
rDao.insert(r);
})
}
}
```