一、
Room数据库是google官方提供的数据库,属于ORM库。
Room与其他ORM框架对比有以下优点:
@Query
和@Entity
等,它不仅检查语法问题,还会检查是否有该表,这就意味着几乎没有任何运行时错误的风险
implementation "android.arch.persistence.room:runtime:1.1.1" kapt "android.arch.persistence.room:compiler:1.1.1"
room:compiler库有人用 annotationProcessor引入,这个引入可能导致报错:Unable to load class com.google.auto.common.BasicAnnotationProcessor
如果用kapt,如果你的项目支持kotlin,需要引入支持kotlin的插件
引入room库,我们即将开发第一个demo的使用
1.1:Entity=表库实体对象
1.2:Dao:=查询模块,也就是sql语句,DDL和DML语言的控制类
1.3Database=数据库类
我们都知道数据库的表是字段关联数据。这个就很好理解,一条记录就是一个对象的熟悉,所以,我们创建一个表,就可以用Entity来标记。
如下:
@Entity(tableName = "user_db") public class UserEntity { /** * @Entity 实体类的标注,将会在数据库映射成对应的表结构,tableName不写,将会是实体类默认 * @PrimaryKey 主键 * @ColumnInfo 字段属性对应列的关系 没有该注解时,属性名将一一对应字段名 * @Ignore 属性值将不会序列化为字段 */ @ColumnInfo(name = "age", typeAffinity = ColumnInfo.INTEGER) public int age; @ColumnInfo(name = "name") public String name = ""; @ColumnInfo(name = "address") public String address = ""; @ColumnInfo(name = "mobile") public String mobile = ""; @PrimaryKey(autoGenerate = true) public int id; }
我们创建了一个UserEntity实体,定义了一些数据。指定了主键和其他栏的基本信息
如果我们没有设备ColumnInfo,那么被实例化如表的name就是字段的name,如果你要重新对熟悉在表中定义新的字段,那么可以如下
@ColumnInfo(name = "m_mobile")
public String mobile = "";
如果设置主键:
@PrimaryKey(autoGenerate = true)
public int id;
主键设置好了,入库以后,主键是自增,
有人会问typeAffinity属性是什么意思?我们都知道如果没注明入库数据格式,默认都是String,如果想指定数据;类型,可以通过typeAffinity来标记
默认是:UNDEFINED
@Entity(tableName = "user_db"):指定该类为表,并指定一个表名(tableName )。
正常上面的信息基本可以满足正常的需求。
Dao在Java中是对数据的访问。在这边也是一样,提供对数据库的访问与操作,是对接口的修饰。
@Dao public interface UserDao { @Query("select * from user_db") public ListqueryAll(); @Query("select * from user_db where id=:id") public UserEntity findUserById(int id); @Update() public void updateUser(UserEntity entity); @Insert(onConflict = OnConflictStrategy.REPLACE) public long[] inserUser(UserEntity... entities); @Delete public void deleteUser(UserEntity entity); }
这里面提供了对数据的基本操作如下,
1.Query提供了查询,在Dao类创建之前,先处理好Entity表,因为在Dao操作中,如果引用了表,会自动去关联Entity的tabname,
2.查询:在写条件查询时,字段连接参数如下
id=:id,表中的字段名=:参数,不是我们写的id=id。
3.插入Insert:onConflict冲突解决机制,onConflict = OnConflictStrategy.REPLACE
public @interface OnConflictStrategy { /** * OnConflict strategy constant to replace the old data and continue the transaction. */ int REPLACE = 1; /** * OnConflict strategy constant to rollback the transaction. */ int ROLLBACK = 2; /** * OnConflict strategy constant to abort the transaction. */ int ABORT = 3; /** * OnConflict strategy constant to fail the transaction. */ int FAIL = 4; /** * OnConflict strategy constant to ignore the conflict. */ int IGNORE = 5; }
可以根据你的业务,自行添加标记。
其他可自行研究
数据库的创建:@Database(entities = {UserEntity.class}, version = 1)
entities 括号里是表,就是我们用entity注入的标。最后一个参数是版本号。
这里一张数据至少有一个表,括号里可以是多张表,这个表必须集成RoomDatabase,是一个抽象类,如下:
@Database(entities = {UserEntity.class}, version = 1) public abstract class MyRoomDataBase extends RoomDatabase { public abstract UserDao getUserDao(); }
我们创建了一个自己的数据库,里面有一张表,在该数据库中,又创建了一个抽象的Dao,用来对数据的操作。
以上三大核心已介绍完,接下来我们要做一个核心的操作,就是对项目进行build。如果项目执行成功,将会对Database和Dao类生成新的Impl类,如下:
对数据的动态创建,和对dao的生成。具体代码大家可自行去创建然后查看
自动生成一些数据库的操作类还有就是我们定义了DDL操作方法,这些就是对sql语句的自动生成
如果这两个类生成完,那我们的数据库基本完成。如果没有生成,那只有说明我们引用的有用。即使你去操作这些数据库,你也无法执行成功。
连接数据库:
MyRoomDataBase dataBase = Room.databaseBuilder(this, MyRoomDataBase.class, "userDataBase").build();
Context:直接传入
Classklass:是数据库类@Databasex修饰的类
name:数据库名字
创建成功后才可以去操作数据库
Dao操作数据都需要在子线程完成,因为Dao比较耗时,直接在UI线程操作,会报错。
UserEntity entity = new UserEntity(); entity.address = "江苏南京"; entity.age = 12; entity.mobile = "110"; entity.name = "张傻"; if (dataBase == null) { showToast("数据库初始化失败"); return; } new Thread(new Runnable() { @Override public void run() { dataBase.getUserDao().inserUser(entity); } }).start();
开:创建好也就是开启了
关:dataBase.close()
是否打开:dataBase.isOpen()
数据库名字: dataBase.getOpenHelper().getDatabaseName()
数据库版本号:dataBase.getOpenHelper().getReadableDatabase().getVersion()
配置自己的事物:dataBase.beginTransaction();dataBase.endTransaction();
对数据库的操作:可以通过创建databse来管理。
以上基本就完成了对room数据库的基本操作