xUtils3 的数据库使用
xUtils3 的数据库使用
xUtils3 是一款 Android ORM 和 IOC 快速应用开发框架,源自于 Afinal,对 Afinal 进行了大量重构,功能上也比 Afinal 更加强大。包括四个模块分别是 DbUtils,ViewUtils, HttpUtils 和 BitmapUtils 模块。项目主要使用了 DbUtils 模块实现的 ORM 框架,主要需求是将类数据整个读取或存入 SQLite 数据库中。
基本知识
ORM 框架:
ORM(Object Relational Mapping)框架采用元数据来描述对象间的关系映射细节,只要提供了持久化类与表的映射关系,ORM 框架在运行时就能参照映射文件的信息,把对象持久化到数据库中。元数据是用来描述其它数据的数据 (data about other data),或者说是用于提供某种资源的有关信息的结构数据(structured data)。
DbUtils模块:
- Android中的 ORM 框架,一行代码就可以进行增删改查;
- 支持事务,默认关闭;
- 可通过注解自定义表名,列名,外键,唯一性约束,NOT NULL约束,CHECK约束等(需要混淆的时候请注解表名和列名);
- 支持绑定外键,保存实体时外键关联实体自动保存或更新;
- 自动加载外键关联实体,支持延时加载;
- 支持链式表达查询,更直观的查询语义
使用准备
导入依赖
Gradle 构建时添加如下依赖即可使用该开源库
compile 'org.xutils:xutils:3.5.0'
配置相关权限
使用 xUtils3 时需要在 manifest 里添加相关权限,主要是 xUtils3 的其他模块会用到。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
初始化 xUtils3 模块
xUtils3 需要在 Application 的 OnCreate() 方法中进行初始化,所以我们需要使用自定义一个继承 Application 的 App 类。
public class App extends Application{
@Override
public void onCreate() {
super.onCreate();
// 初始化 xUtil3
x.Ext.init(this);
x.Ext.setDebug(BuildConfig.DEBUG);
}
}
在 manifest 里面使用我们自己定义的 App 类,下面代码省略了其他内容。
<application
android:name=".App">
<!-- 四大组件 -->
</application>
使用 DbUtils 模块
使用步骤
- 使用注解创建数据表
- 使用 DaoConfig 进行数据库的信息配置
- x.getDb(daoConfig) 获取数据库实例进行增删改查
创建数据表
首先要知道是只有在你对数据库里面的操作涉及到这张表的操作时,会先判断当前的表是否存在,如果不存在,才会创建一张表,如果存在,才会进行相应的 CRUD 操作。
DbUtils 相关注解:
其中核心注解有两个,分别是 @Table
和 @Column
。
@Check check约束
@Column 列名
@Finder 一对多、多对一、多对多关系
@Foreign 外键
@Id 主键,当为 int 类型时,默认自增,非自增时,需要设置 id 的值
@NoAutoIncrement 不自增
@NotNull 不为空
@Table 表名
@Transient 不写入数据库表结构
@Unique 唯一约束
@Table
:有属性 name 和 onCreated 两个属性。name 属性决定了该实体类映射的数据库表名,而 onCreated 属性则可以用来添加表一级的属性或约束,例如创建联和唯一索引等。
@Column
:有 name、property、isId、autoGen 四个属性。name 属性决定了实体类属性对应的数据库字段名,property 属性可以用来添加数据库中字段一级的属性或约束条件例如 not null,索引等,isId 属性表示该字段是否是主键,默认为 false,autoGen 则表示为主键是否自增长,默认为 true,所以该字段只有在 isId 属性为 true 时有效。未加注 @Column
注解的字段将不映射 SQLite 字段。
示例:
@Table(name = "user")
public class User {
@Column(name = "id", isId = true)
private int id;
@Column(name = "name")
private String name;
@Column(name = "email")
private String email;
@Column(name = "time")
private Date time;
@Column(name = "date")
private java.sql.Date date;
// 此处省略 getter 和 setter
}
使用 DaoConfig 进行数据库的信息配置
- 设置数据库名
- 设置数据库版本
- 开启事务
- 设置数据库开启监听方法
- 设置数据库更新监听方法
当数据版本变化时,DbManager.DbUpgradeListener() 会被调用,可以在其中对表结构进行修改。当数据库打开时开启 WAL, 对写入加速提升巨大。
private DbManager.DaoConfig daoConfig;
private MyDBManager() {
daoConfig = new DbManager.DaoConfig()
.setDbName("dao.db")
.setDbVersion(1)
.setAllowTransaction(true)
.setDbOpenListener(new DbManager.DbOpenListener() {
@Override
public void onDbOpened(DbManager db) {
db.getDatabase().enableWriteAheadLogging();
}
})
.setDbUpgradeListener(new DbManager.DbUpgradeListener() {
@Override
public void onUpgrade(DbManager db, int oldVersion, int newVersion) {
// db.addColumn(...);
}
});
}
数据库的增删改查
保存类到数据库中:
// 此处省略了 MyDBManager 单例模式的实现
public boolean test() {
User user = new User();
user.setName("yy");
user.setEmail("12345678@qq.com");
user.setTime(new Date());
user.setDate(new java.sql.Date(System.currentTimeMillis()));
boolean ret = MyDBManager.getInstance().save(user);
return ret;
}
public boolean save(Object object) {
DbManager dbManager = x.getDb(daoConfig);
try {
dbManager.save(object);
return true;
} catch (DbException e) {
e.printStackTrace();
}
return false;
}
根据列名查找匹配的第一个值,把该行数据从数据库中读取到类中:
// 此处省略了 MyDBManager 单例模式的实现
public void test() {
User userFirst = (User) MyDBManager.getInstance()
.readFirst(User.class, "name", "xiao ming");
Log.v(LOG_TAG, "userFirst = " + userFirst.toString());
}
public Object readFirst(Class<?> entityType, String columnName, String columnValue) {
DbManager dbManager = x.getDb(daoConfig);
try {
WhereBuilder builder = WhereBuilder.b(columnName, "=", columnValue);
return dbManager.selector(entityType)
.orderBy("id", true).where(builder).findFirst();
} catch (DbException e) {
e.printStackTrace();
}
return null;
}
根据列名查找匹配的所有值的行数,并全部删除:
// 此处省略了 MyDBManager 单例模式的实现
public boolean test() {
ret = MyDBManager.getInstance().delete(User.class,
"name", "xiao ming");
return ret;
}
public boolean delete(Class<?> entityType, String columnName, String columnValue) {
boolean result;
DbManager dm = x.getDb(daoConfig);
try {
WhereBuilder builder = WhereBuilder.b(columnName, "=", columnValue);
dm.delete(entityType, builder);
result = true;
} catch (DbException e) {
result = false;
e.printStackTrace();
}
return result;
}
直接使用 SQL 语句:
DbManager dm = x.getDb(daoConfig);
// 执行查询语句
Cursor cursor= dm.execQuery("select * from user where id>=5;");
// 执行非查询语句
dm.execNonQuery("DROP TABLE user");