greenDao的最后总结实战

本文分三个部分来讲解和使用greendao数据库框架第一环境配置,第二创建实体以及官方推荐使用,第三业务逻辑增删改查。
创建一个你自己的项目这个相信大家都会就不详细讲解了,本人的开发工具是android studio所以下面所有的实例都是按照androidstudio来讲的,然后就是创建一个java代码模块截图如下:

创建好java后一定要添加依赖,这样就不会报错了依赖的添加在截图中
然后我们在我们创建的android工程中配置一下配置截图如下
greenDao的最后总结实战_第1张图片
greenDao的最后总结实战_第2张图片

sourceSets{
    main{
        java.srcDirs=['src/main/java','src/main/java-gen']
    }
}//这里是配置你的路径用于存放由 greenDAO 生成的 Bean、DAO、DaoMaster、DaoSession 等类。 
 compile 'de.greenrobot:greendao:2.0.0'//配置引入greenddao库

在gradle中配置好这两个后项目基本配置完成
首先讲解一下java工程中的这几个重要的类代码如下:

// 创建Schema对象
        // 构造方法第一个参数为数据库版本号
        // 第二个参数为自动生成的实体类将要存放的位置
        Schema schema = new Schema(1004, "com.example.db");
        // 添加需要创建的实体类信息的方法
        addNote(schema);
        try {
            // 创建实体类.第二个参数填Android Module的路径
            new DaoGenerator().generateAll(schema, "app/src/main/java-gen");//
        } catch (Exception e) {
            e.printStackTrace();
        }
 private static void addNote(Schema schema) {
        // 指定需要生成实体类的类名,类名确定了那么表名也是根据这个类名来自动命名的,例如下面这个,生成的表名叫做person_entity
        Entity entity = schema.addEntity("PersonEntity");
        // 指定自增长主键
        //entity.addIdProperty();
        entity.addStringProperty("userId").primaryKey().notNull().unique();
        // 添加类的属性,根据属性生成数据库表中的字段
        entity.addStringProperty("name");
        entity.addIntProperty("age");
        entity.addStringProperty("sex");
    }

还有其他的类型增加方法

entity.addShortProperty("");
entity.addIntProperty("");
entity.addFloatProperty("");
entity.addDoubleProperty("");
entity.addLongProperty("");
entity.addStringProperty("");
entity.addBooleanProperty("");
entity.addByteProperty("");
entity.addDateProperty("");
entity.addByteArrayProperty("");

当然我们还可以自己设置表明:
entity.setTableName(“test”);但是这个是没有必要的,因为框架会默认用大写字母加下划线的形式帮我们定义默认的表名
此框架提供了两种设置主键的方法:

 //entity.addIdProperty();//设置一个自增长的id属性或者这样
 entity.addStringProperty("userId").primaryKey().notNull().unique();//设置一个字符串id作为主键且不为空且唯一

这里解释一下数据库约束
表中会有一些约束条件,可以指定字段为主键,非空,唯一,也可以指定索引。

entity.addIntProperty("").isPrimaryKey()
entity.addStringProperty("").notNull();
entity.addIntProperty("").unique();
entity.addLongProperty("").index();

可以让实体类实现接口,继承父类,导入包

entity.implementsSerializable();
entity.implementsInterface("com.test.A");
entity.setSuperclass("com.test.B");
entity.addImport("com.test.B");

android工程里面的代码,这里我自己写了一个单类模式创建一个dbUtil的类代码如下

public class DbUtils {
    private  SQLiteDatabase db;
    // 管理者
    private  DaoMaster mDaoMaster;
    // 会话
    private  DaoSession mDaoSession;
    private UserDao userDao;
    // 对应的表,由java代码生成的,对数据库内相应的表操作使用此对象
    private static DbUtils dbUtils;
    private DbUtils(Context context) {
        initDatabase(context);
    }
    public static DbUtils getInstance(Context context) {
        if (dbUtils == null) {
            dbUtils = new DbUtils(context);}
        return dbUtils;
    }
    public void initDatabase(Context context){
        // 初始化就这个顺序,记着吧 ^_^
        // 此DevOpenHelper类继承自SQLiteOpenHelper,第一个参数Context,第二个参数数据库名字,第三个参数CursorFactory
        DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context, MyApp.dbName,null);
        db = helper.getWritableDatabase();
        mDaoMaster = new DaoMaster(db);
        mDaoSession = mDaoMaster.newSession();
        }
    public void insetUser(User user){//单条插入
        userDao=mDaoSession.getUserDao();
        userDao.insertOrReplace(user);
    }
    public void insetUsers(ArrayList users){//批量插入
        userDao=mDaoSession.getUserDao();
        userDao.insertOrReplaceInTx(users);
    }

}

这个类是对数据操作类,有了这个类我们就不需要每次都写一些重复代码了
最关键也是最重要,还是最不好理解的来了
数据库关系映射
一对一关系
举个列子
人跟身份证是一对一关系,人的属性,身份证的属性建表如下

人
Entity person = schema.addEntity("Person");
person.addIdProperty().primaryKey();
person.addStringProperty("name");
person.addDoubleProperty("height");
person.addDoubleProperty("weight");
身份证
Entity card = schema.addEntity("Card");
card.addIdProperty().primaryKey();
card.addStringProperty("num");
card.addStringProperty("address");

这样看来这两个实体是独立的,
然后加上这两句代码后数据库表之间就一对一关系
Property idcardPK = person.addLongProperty(“cardId”).getProperty();
person.addToOne(card, idcardPK);

Property personPK = card.addLongProperty(“personId”).getProperty();
card.addToOne(person, personPK);
表结构如图:
greenDao的最后总结实战_第3张图片greenDao的最后总结实战_第4张图片
对比两张表图,发现用户中存在身份证id,身份中存在用户id这就所以一一对应关系
稍微复杂一点也是平时用的最多的一个就是一对多关系,这里greendao 框架也提供了方法代码比如用户跟订单,一个用户可以有多个订单但是一个订单只能属于一个用户,代码理解如下:

 Entity order = schema.addEntity("Order");//订单实体类
        order.addStringProperty("orderId").primaryKey().notNull().unique();
        order.addStringProperty("num");
        order.addDoubleProperty("desc");
        Property userId = order.addStringProperty("userId").getProperty();
        entity.addToMany(order,userId);//用户中有多个订单
        order.addToOne(entity,userId);//订单只属于一个用户。一对多关系在数据库中就已经产生了

接下来就是最复杂的多对多关系了,这中关系平时用的比较少,但是我们也必须了解以及掌握这种关系
比如一个用户可以对应多个群,一个群里面可以存在多个用户
下面是群组实体,上面已经有了一个用户实体了,这里就不再多写

 Entity group=schema.addEntity("Group");//群组实体
        group.addStringProperty("groupName");
        group.addStringProperty("groupNum");
        group.addStringProperty("groupHeardUrl");

多对多关系都是要通过第三张表来实现的
代码如下:

  Entity ug = schema.addEntity("UserGroup");//多对多关系的第三张表实体类
        ug.addStringProperty("ugId").primaryKey().notNull().unique();
        Property userIds = ug.addStringProperty("userId").getProperty();
        Property groupIds = ug.addStringProperty("groupId").getProperty();
        ug.addToOne(entity,userIds);
        ug.addToOne(group, groupIds);
        entity.addToMany(ug, userIds);
        group.addToMany(ug,userIds);

这样表关系就差不多讲解完了
最后注意一个细节,不过本人认为很少用到
有时候,一张表中可能会有另一张表的两个外键,比如一个用户有头像,还有头像的缩略图,但是这两张图都是图像表中的。

Entity picture = schema.addEntity("Picture");
picture.addIdProperty().autoincrement();
picture.addStringProperty("url");

Entity user = schema.addEntity("User");
user.addIdProperty();
user.addStringProperty("account");

这时候我们如果使用

Property pictureId = user.addLongProperty("pictureId").getProperty();
Property thumbnailId = user.addLongProperty("thumbnailId").getProperty();
user.addToOne(picture,pictureId);
user.addToOne(picture,thumbnailId);

将会引起一个错误,因为User实体类中有两个引用指向Picture,但是如果不进行重命名的话这两个引用的名字就会是一样的,最终只会存在一个,为了解决这个问题,我们需要使用重载方法进行重命名

Property pictureId = user.addLongProperty("pictureId").getProperty();
Property thumbnailId = user.addLongProperty("thumbnailId").getProperty();
user.addToOne(picture,pictureId,"picture");
user.addToOne(picture,thumbnailId,"thumbnail");

最后就是我们经常使用的增删改查了
增加我这里介绍四中方法代码如下:

   userDao.insertOrReplace(user);//单条插入操作时如果id存在则替换
   userDao.insert(suer)//单条插入操作如果id存在则报错
   userDao.insertOrReplaceInTx(users);//批量插入式如果id存在则替换
   userDao.insertOrReplace(user)//批量插入式如果id存在则报错

删除操作我这里给出五种中操作代码如下:

  userDao.delete(user);//根据对象删除数据
  userDao.deleteInTx(users);//根据对象集合删除数据
  userDao.deleteAll();//删除全部数据
  userDao.deleteByKey("id");//通过id删除数据
  userDao.deleteByKeyInTx("ids");//通过id集合删除数据

修改操作我这里给出两种操作代码如下

     userDao.updateInTx(users);//根据对象集合批量修改用户信息
         userDao.update(user);//根据用户对象单个修改用户信息

查询操作也是最为复杂的操作这里给出一些查询方法:

        userDao=mDaoSession.getUserDao();
        userDao.load("id");//根据id查找相应的对象
        userDao.loadAll();//查找表中所有数据
        QueryBuilder qb=userDao.queryBuilder();
        qb.orderAsc(UserDao.Properties.Age);//排序查询
        qb.where( qb.and(UserDao.Properties.Name.eq("孙悟空10"), UserDao.Properties.Sex.eq("男")));//条件或语句
        qb.where( qb.or(UserDao.Properties.Name.eq("孙悟空10"),UserDao.Properties.Sex.eq("女")));//条件与语句
        List queryList2= qb.list();
        userDao.queryBuilder().list();//查询全部数据
        List queryList1=userDao.queryBuilder().where(UserDao.Properties.Name.eq("孙悟空19")).list();//一个条件查询

重要的查询通常需要几个实体类型(数据表)的数据。在SQL的世界里,你可以通过使用连接条件将两个以上的表链接起来实现查询。我们知道,一个实体User,它和另一个实体Address是一对多(one-to-many)的关系,我们想要查询住在“Sesame Street”的user。我们会使用user ID将Address实体加入User实体中,并且在Address实体中定义一个WHERE条件:
greenDAO官方文档翻译–使用教程
这个连接查询需要使用目标实体类作为一个参数,同时需要加入该目标实体的一个属性。在本例中,由于主键属性被默认使用,所以只需要定义Address实体的连接属性。换句话说,在users的结果集中,拥有一个等价于User实体ID的userId,同时也指定了一个街道名。
看完这篇文章我相信读者都可以很轻松的使用这个数据库框架了,认真阅读手活肯定不少。

你可能感兴趣的:(greenDao的最后总结实战)