一、ORM(Object Relation Mapping)
ORM即对象关系映射,说白了就是将面向对象编程语言里的对象与数据库关联起来的一种技术,主要解决对象-关系的映射,如下表:面向对象的概念 | 面向关系的概念 |
类 | 表 |
对象 | 表的行(记录) |
属性 | 表的列(字段) |
ORM思想:将关系数据库表中的记录映射为对象,以对象的形式展现,即可把对数据库的操作转化为对对象的操作。
ORM主流框架:
- OrmLite(不是Android平台专用的ORM框架,它是Java ORM)
- SugarORM(是 Android 平台专用ORM)
- Active Record
- GreenDao(数据访问频繁时很好的选择)
二、greenDao3.0
greenDao是一种将对象映射到SQLite数据库的轻量且快速的ORM解决方案,3.0版本于2016.07.06发布,最大的变化是采用注解的方式通过编 译生成Java数据对象和DAO对象,将java object和SQLite Database关联起来。
优点:1.存取速度快(每秒可操作数千个实体)
2.支持数据库加密(支持android原生SQLite,也支持SQLCipher,即在SQLite基础上加密)
3.轻量级(代码库仅100k大小)
4.支持缓存(能够将使用的过的实体存在缓存中,下次使用时可以直接从缓存中取,这样可以使性能提高N个数量级)
5.代码自动生成(根据modle类自动生成实体类(entities)和Dao对象,并且Dao对象是根据entities类量身定做的并且一 一对应)
三、greenDao3.0的使用
1.了解greenDao的几个核心类
DaoMaster:
- 是greenDao的入口也是greenDao顶级对象,对于一个指定的表单持有数据库对象(SQLite数据库)并且能够管理DAO类,能够创建表和删除表。
- 其内部类OpenHelper 与DevOpenHelper是创建SQlite数据库的SQLiteOpenHelper的具体实现。
- 对于一个指定的表单可以管理所有的Dao 对象。
- 也能够对实体类执行 insert ,load,update,refresh,delete操作。
- DaoSession也能跟踪 identity scope:即session查询后的实体会存在缓存中,并给该实体生成一个flag来追踪该实体,下 次再次查询时会直接从缓存中取出来而不是从数据库中取出来。
- 能够持久访问和查询实体类。
- 比起DaoSession有更多的持久化方法 count, loadAll,insertInt等等。
构建Model类:Molde类需要用java类来定义并且可以通过greenDao中的注释来表明Model中的每个属性在数据库的中该如何定义,然后点击Make project选项greenDao就会自动生成DaoMaster,DaoSession,和DAOS类,生成的代码会保存在预先在build.gradle中配置的位置。
2.添加配置
打开project/build.gradle文件,在dependencies闭包中添加greenDao生产代码插件:
dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
classpath 'org.greenrobot:greendao-gradle-plugin:3.1.0'
}
同样打开app/build.gradle文件,添加如下内容:
apply plugin: 'org.greenrobot.greendao'
dependencies {
compile 'org.greenrobot:greendao:3.1.0'
}
greendao {
//数据库schema版本,也可以理解为数据库版本号
schemaVersion 1
//设置DaoMaster 、DaoSession、Dao包名
daoPackage 'com.greendao.gen'
targetGenDir 'src/main/java'
//设置DaoMaster 、DaoSession、Dao目录
//设置生成单元测试目录
}
3.创建一个实体类及注释
@Entity
public class User {
@Id
private Long id;
@Property(nameInDb = "NAME")
private String name;
private String sex;
@Property(nameInDb = "SEX")
}
@Property(nameInDb = "AGE")
private int age;
Make Project编译项目,User实体类会自动编译,生成get、set方法和构造方法并在指定的文件夹下生成DaoMater、DaoSession、UserDao三个文件夹:
基本属性注释:
@Entity:告诉GreenDao 该Bean类需要持久化。只有使用 @Entity 注释的Bean类才能被dao类操作
@Property :可以自定义一个该属性在数据库中的名称,默认情况下数据库中该属性名称是Bean对象中的属性名但是不是以驼峰式而是以大写与下划线组合形式来命名的比如:customName将命名为 CUSTOM_NAME。注意:外键不能使用该属性。
@NotNull :确保属性值不会为null值。
@Transient :使用该注释的属性不会作为数据表中的一个字段。
索引注释:
主键限制每个实体类都应该有一个Long型属性作为主键,如果你不想用Long型作为主键,你可以使用一个唯一索引(使用 @Index(unique = true)注释使普通属性改变成唯一索引属性)属性作为关键属性。
4.获取操作实体类的UserDao
在获取UserDao之前,首先要获取DaoSession,一般在application中执行:
public class MyApplication extends Application {
public static MyApplication instance;
private DaoMaster.DevOpenHelper openHelper;
private static String dbNAME ="DB-test";
private SQLiteDatabase db;
public void onCreate() {
private DaoMaster daoMaster;
private DaoSession daoSession;
@Override
private void setgreenDao() {
super.onCreate();
instance=this;
setgreenDao();
}
daoMaster=new DaoMaster(db);
openHelper=new DaoMaster.DevOpenHelper(this,dbNAME);
db=openHelper.getWritableDatabase();
public DaoSession getDaoSession(){
daoSession=daoMaster.newSession();
}
public static MyApplication getInstance(){
return instance;
}
}
return daoSession;
}
这里创建一个数据库管理者单例,进行CRUD操作:
public class DBManager {
private static DBManager instance;
private UserDao userDao;
public DBManager() {
userDao=MyApplication.getInstance().getDaoSession().getUserDao();
}
public static DBManager getInstance(){
if (instance==null){
synchronized (DBManager.class){
instance=new DBManager();
}
}
return instance;
}
/**
* 插入数据
* */
public void insertUser(User user){
userDao.insert(user);
}
/**
* 删除数据
* */
public void deleteUser(User user){
userDao.delete(user);
}
/**
* 更新数据
* */
public void updateUser(User user){
userDao.update(user);
}
/**
* 查询用户列表
* */
public List<User> queryUserList(){
QueryBuilder<User> qb=userDao.queryBuilder();
List<User> list=qb.list();
return list;
}
/**
* 查询用户列表
*/
public List<User> queryUserList(int age) {
QueryBuilder<User> qb = userDao.queryBuilder();
qb.where(UserDao.Properties.Age.gt(age)).orderAsc(UserDao.Properties.Age);
List<User> list = qb.list();
return list;
}
}
查询语句:
eq():==
noteq():!=
gt(): >
lt():<
ge:>=
le:<=
like():包含
between:俩者之间
in:在某个值内
notIn:不在某个值内
分页查询:
limit(int): 限制查询的数量;
offset(int): 每次返回的数量; offset不能单独使用;
5.测试程序:
DBManager dbManager=DBManager.getInstance();
for (int i=0;i<5;i++){
User user=new User();
user.setName("第"+i+"人");
user.setSex("女");
user.setAge(5*(i+1));
dbManager.insertUser(user);
}
List<User> userList = dbManager.queryUserList();
for (User user:userList){
Log.e("TAG", "onCreate: "+user.getName()+"="+user.getSex()+"="+user.getAge() );
}
测试结果: