(一)GreenDao3.0的简单使用

GitHub地址

https://github.com/SharkChao/GreenDao

greenDao的gradle配置
(1)progect gradle

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.3'
        classpath 'org.greenrobot:greendao-gradle-plugin:3.2.1'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

(2)gradle中

apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao'
android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"
    greendao {
        schemaVersion 2
        targetGenDir 'src/main/java'
        daoPackage 'com.lenovo.sharkchao.hospital.greendao'
    }
    defaultConfig {
        applicationId "com.example.sharkchao.a"
        minSdkVersion 8
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.0.1'
    compile 'org.greenrobot:greendao:3.2.0'
    compile 'com.android.support:design:23.0.1'
    testCompile 'junit:junit:4.12'
}

一.@Entity:实体 在类中设置 可以创建与实体相关联的表


(1)schema = “myschema”, 当程序中有多个secema(数据库)时,可以选择我们想要的一个。
(2)active = true, 设置Entity是否是活动的。如果是活动的,那么他将有更新,删除,刷新的方法。
(3)nameInDb = “AWESOME_USERS”, 数据库中的表名,默认是实体类名。
(4)indexes = { @Index(value = “name DESC”, unique = trut) }, 索引
(5) createInDb = false, 是否会创建数据库表,默认是true 当多个实体映射一个表,或者表不在greenDao之内创建时为false。
(6)generateConstructors = true, 不管有没有有参函数,一个无参函数总是会创建
(7)generateGettersSetters = true 产生get,set方法。


(在成员变量前的注解)
(1)@Id(autoincrement = true) 主键自增长
(2)@NotNull 不为空
(3)@OrderBy(date desc) 降序
(4)@Transient 短暂的,不会持久化,因此不会生成数据库中的列
(5)@Property 参数,在数据库表中默认为如下格式customName—–CUSTOM_NAME
@Property(nameInDb = “USERNAME”) 固定格式如下
(6)@Unique private String name; 唯一约束
(7)Sqlite中主键必须是long类型,因此尽量添加一个附加属性
@Index(unique = true) Private String key;
(8)@ToOne:定义与另一个实体(一个实体对象)的关系(底下会有详解)
@ToMany:定义与多个实体对象的关系(底下会有详解)


二 查询表

List joes = userDao.queryBuilder()
  .where(Properties.FirstName.eq("Joe"))
  .orderAsc(Properties.LastName)
  .list();

1)orderAsc:升序排序
(1)orderDesc: 降序排序
(1)eq():==
(1)noteq():!=
(1)gt(): >
(1)t():<
(1)ge:>=
(1)le:<=
(1)like():包含
(1)between:俩者之间
(1)in:在某个值内
(1)notIn:不在某个值内

三 关联关系

1:1 @ToOne(joinProperty = “userId”)
通过外键来关联另一个实体。使用到的两个对象类为:
(User,Picture)
具体实例

@Entity
public class User {
    @Id
    private Long UserId;
    private long pictureId;
    @Property(nameInDb = "NAME")
    private String name;
    @Property(nameInDb = "AGE")
    private String age;
    @Property(nameInDb = "SEX")
    private String sex;
    @ToOne(joinProperty = "pictureId")//pictureId是我们需要关联的外键
    private Picture picture;
}
@Entity
public class Picture implements Serializable {
    private static final long serialVersionUID = 11;
    @Id
    private Long pictureId;
    private long userId;
    @Property
    private String pictureName;
    @Property(nameInDb = "width")
    private String width;
    @Property(nameInDb = "height")
    private String height;
    @ToOne(joinProperty = "userId")
   private User user;
}

需要注意的是:Intent传递对象需要用到:Serializable
必须把serialVersionUID 给带上,不然会报错。

1:n

@ToMany(referencedJoinProperty = "customerId")
joinProperties这个参数是referencedJoinProperty 参数的升级版
@ToMany(joinProperties = {
              @JoinProperty(name = "id", referencedName = "customerId")
      })

需要用到的两个实体类为:Customer .java 以及 Order.java

@Entity
public class Customer {
    @Id
    private Long id;
    @Property
    private String name;

//    @ToMany(referencedJoinProperty = "customerId")
    @ToMany(joinProperties = {@JoinProperty(name = "id", referencedName = "customerId")})
    @OrderBy("date ASC")
    private List<Order> orders;
}

@Entity
public class Order {
    @Id
    private Long id;
    @Property
    private Date date;
    private long customerId;
}

@ToMany(referencedJoinProperty = “customerId”),注解写在对应关系的一里边。
它这个注解默认的是customer的主键对应order的外键。
当我们不需要用一的主键对应N的外键时,我们可以自己定制
即:

@ToMany(joinProperties = {@JoinProperty(name = "id", referencedName = "customerId")})

即本类中的id对应其他类中的customerId


M:n

@JoinEntity 定义了N:M的映射关系。 创建三个实体类,其中一个为关联类。 需

要的三个实体类分别为:Order.java。product.java。JoinProductsWithOrders.java

@Entity
public class Order {
    @Id
    private Long id;
    @Property
    private Date date;
    private long customerId;
}

@Entity
public class Product {
    @Id
    private Long id;

    @ToMany
    @JoinEntity(
            entity = JoinProductsWithOrders.class,
            sourceProperty = "productId",
            targetProperty = "orderId"
    )
    private List<Order> ordersWithThisProduct;
}

@Entity
public class JoinProductsWithOrders {
    @Id
    private Long id;
    private Long productId;
    private Long orderId;
}

在类里边写toMany表示的是将此类当成唯一,他需要一个中间类生成的表来连接另外一个表(实体),
关键代码如下:

@ToMany
    @JoinEntity(
            entity = JoinProductsWithOrders.class,
            sourceProperty = "productId",
            targetProperty = "orderId"
    )
    private List<Order> ordersWithThisProduct;


查询数据

  1. 分页查询

limit(int): 限制查询的数量; offset(int): 每次返回的数量; offset不能单独使用; 查询与LazyList类

Query :
Query类表示一个查询能够执行很多次;而当通过QueryBuilder的任何查询方法(eg:list())来获取查询结果时,querybuilder都会
在其内部创建Query来执行查询语句的;如果执行多次查询应该使用Query对象; 如果只想获取一个结果时可以使用Query(or
QueryBuilder)中的unique()方法;

LazyList : 可以通过以下方法获取查询结果集合;

list() 缓存查询结果;list()类型一般为ArrayList

listLazy() 懒查询,只有当调用list()中的实体对象时才会执行查询操作并且只缓存第一次被查询的结果,需要关闭

listlazyUncached() 懒查询,只有当调用list()中的实体对象时才会执行查询操作并且不缓存;

listIterator()
对查询结果进行遍历,不缓存,需要关闭;后面三个类是LazyList中的方法,LazyList为了执行不同的缓存策略其内部持有数据库的cursor对象;一般情况下这三个方法执行完毕后会自动关闭cursor;但是防止在还没有执行完查询结果时,对象被终结cursor还是无法被关闭的情况发生,需要手动关闭close();

插入数据(保存数据),以一对多为例

新建两个实体类,news.java comment.java 关系为1:n

Entity
public class News {
    @Id
    private Long id;
    @Property
    private String title;
    @ToMany(joinProperties = {@JoinProperty(name = "id", referencedName = "newsId")})
    @OrderBy("commentDate ASC")
    private List<Comment> comment;
    @Property
    private String publishDate;
}

@Entity
public class Comment {
    @Id
    private Long id;
    @Property
    private String content;
    @Property
    private String commentDate;
    private Long newsId;
}
  /*** 保存新闻与评论数据,关系为1:n    
     */
    public void save(){
        //新建一条新闻
        News news1=new News();
        news1.setPublishDate(new Date()+"");
        news1.setTitle("这是第一条新闻");
        NewsDao newsDao =  GetDaoMaster.getDaoSession(BaseActivity.getCurrentActivity()).getNewsDao();
        newsDao.insert(news1);
        //新建两条评论
        Comment comment1=new Comment(null,"好评!",new Date()+"",news1.getId());
        Comment comment2=new Comment(null,"差评!",new Date()+"",news1.getId());
        CommentDao commentDao = GetDaoMaster.getDaoSession(BaseActivity.getCurrentActivity()).getCommentDao();
        commentDao.insert(comment1);
        commentDao.insert(comment2);

        //不需要提交吗????
        news1.getComment().add(comment1);
        news1.getComment().add(comment2);
        news1.setCommentCount(2+"");
    }

修改数据

 public void update(){

        //1.修改某个id的一条记录
       NewsDao newsDao =  GetDaoMaster.getDaoSession(BaseActivity.getCurrentActivity()).getNewsDao();
       News news = newsDao.queryBuilder().where(NewsDao.Properties.Id.eq("1")).build().unique();
        news.setTitle("修改之后的标题");
        newsDao.update(news);

        //2.修改符合某个约束条件的记录(修改title为"这是第一条新闻",commentcount>0的记录title字段为"今日iPhone6 Plus发布")
        NewsDao newsDao1 =  GetDaoMaster.getDaoSession(BaseActivity.getCurrentActivity()).getNewsDao();
        QueryBuilder qb=newsDao1.queryBuilder();
        qb.where(qb.and(NewsDao.Properties.Title.eq("这是第一条新闻"),NewsDao.Properties.CommentCount.gt("0")));
        News news1 = (News) qb.build().unique();
        news.setTitle("今日iPhone6 Plus发布");
        newsDao.update(news);

        //3.修改符合约束条件的记录(修改所有的title都为"今日iPhone6 Plus发布")
        NewsDao newsDao2 =  GetDaoMaster.getDaoSession(BaseActivity.getCurrentActivity()).getNewsDao();
        QueryBuilder qb2=newsDao2.queryBuilder();
        List<News>list = qb2.build().list();
        for (News n:
            list ) {
            n.setTitle("今日iPhone6 Plus发布");
        }
        newsDao2.updateInTx(list);//updateAll()?

        //4.将id=2的记录title修改为"今日iPhone6发布"
        NewsDao newsDao3 =  GetDaoMaster.getDaoSession(BaseActivity.getCurrentActivity()).getNewsDao();
        News news3 = newsDao3.queryBuilder().where(NewsDao.Properties.Id.eq("2")).build().unique();
        news.setTitle("今日iPhone6发布");
        newsDao3.update(news);

        //5.把news表中标题为“今日iPhone6发布”且评论数量大于0的所有新闻的标题改成“今日iPhone6 Plus发布”
        NewsDao newsDao4 =  GetDaoMaster.getDaoSession(BaseActivity.getCurrentActivity()).getNewsDao();
        QueryBuilder qb4 = newsDao4.queryBuilder();
        List<News>list4 = qb4.where(qb4.and(NewsDao.Properties.Title.eq("今日iPhone6发布"),NewsDao.Properties.CommentCount.gt("0"))).list();
        for (News n:
                list4 ) {
            n.setTitle("今日iPhone6 Plus发布");
        }
        newsDao4.updateInTx(list);//updateAll()?
    }

删除数据

 public void delete() {
   /*
    * 1.删除id为2的记录
    * 这不仅仅会将news表中id为2的记录删除,同时还会将其它表中以
    * news id为2的这条记录作为外键的数据一起删除掉,因为外键既
    * 然不存在了,那么这么数据也就没有保留的意义了
    * */
        NewsDao newsDao =  GetDaoMaster.getDaoSession(BaseActivity.getCurrentActivity()).getNewsDao();
        newsDao.deleteByKey(Long.getLong("2"));

        //2.news表中标题为“今日iPhone6发布”且评论数等于0的所有新闻都删除掉
        NewsDao newsDao2 =  GetDaoMaster.getDaoSession(BaseActivity.getCurrentActivity()).getNewsDao();
        QueryBuilder qb2 = newsDao2.queryBuilder();
        List<News>list2 = qb2.where(qb2.and(NewsDao.Properties.Title.eq("今日iPhone6发布"),NewsDao.Properties.CommentCount.eq("0"))).list();
       newsDao2.deleteInTx(list2);

        //3.想把表中的所有news数据删除掉
        NewsDao newsDao3 =  GetDaoMaster.getDaoSession(BaseActivity.getCurrentActivity()).getNewsDao();
        newsDao3.deleteAll();


       //4通过对象也可以删除持久化的数据
        NewsDao newsDao4 =  GetDaoMaster.getDaoSession(BaseActivity.getCurrentActivity()).getNewsDao();
        News news = newsDao4.queryBuilder().where(NewsDao.Properties.Id.eq("1")).build().unique();
        news.delete();

    }

查询数据

      public void select() {
        //-----------------------------------懒加载查询---------------------------------------------------
        //1.查询news表中id为1的这条记录
        NewsDao newsDao = GetDaoMaster.getDaoSession(BaseActivity.getCurrentActivity()).getNewsDao();
        News news = newsDao.queryBuilder().where(NewsDao.Properties.Id.eq("1")).unique();

        //2.获取news表中的第一条数据,最后一条数据
//       News news1=newsDao.queryBuilder().list().get()
//        News news2=newsDao.queryBuilder().offset();通过newsDao.count()方法


        //3.news表中id为1357的数据都查出来


        //4.查询news表中所有评论数大于零的新闻
        List<News> newsList4 = newsDao.queryBuilder().where(NewsDao.Properties.CommentCount.gt("0")).build().list();

        //5.也许你并不需要那么多的数据,而是只要title和content这两列数据。那么也很简单,我们只要再增加一个连缀就行了
        QueryBuilder<News>qb = newsDao.queryBuilder();

        //6.将查询出的新闻按照发布的时间倒序排列,即最新发布的新闻放在最前面
        List<News> newsList6 = newsDao.queryBuilder().orderDesc(NewsDao.Properties.PublishDate).build().list();


        //7.也许你并不希望将所有条件匹配的结果一次性全部查询出来,因为这样数据量可能会有点太大了,而是希望只查询出前10条数据
        List<News> newsList7 = newsDao.queryBuilder().orderDesc(NewsDao.Properties.PublishDate).limit(10).list();

        //8.刚才我们查询到的是所有匹配条件的前10条新闻,那么现在我想对新闻进行分页展示,翻到第二页时,展示第11到第20条新闻
        List<News> newsList8 = newsDao.queryBuilder().orderDesc(NewsDao.Properties.PublishDate).offset(10).limit(10).list();

        //------------------------------------激进查询-----------------------------------------------------

        //1.我们想要查询news表中id为1的新闻,并且把这条新闻所对应的评论也一起查询出来

        News news11 = newsDao.queryBuilder().where(NewsDao.Properties.Id.eq("1")).unique();
        List<Comment>list1 = news11.getComment();

       CommentDao commentDao=GetDaoMaster.getDaoSession(BaseActivity.getCurrentActivity()).getCommentDao();
        QueryBuilder<Comment>qb2 = commentDao.queryBuilder();
        qb2.join(News.class,CommentDao.Properties.NewsId);
        List<Comment>list2 = qb2.list();

        //查询订单日期为++的素有客户
            QueryBuilder<Customer> queryBuilder = getDaoSession(BaseActivity.getCurrentActivity()).getCustomerDao().queryBuilder();
            queryBuilder.join(Order.class, OrderDao.Properties.CustomerId)
                    .where(OrderDao.Properties.Date.eq(new Date()));
            List<Customer> order = queryBuilder.list();
            for (int i = 0; i < order.size(); i++) {
                System.out.println(order);
        }
        //当我需要姓名为++的订单的时候。
            QueryBuilder<Order> queryBuilder2 = getDaoSession(BaseActivity.getCurrentActivity()).getOrderDao().queryBuilder();
            queryBuilder2.join(Customer.class, CustomerDao.Properties.Id)//根据顾客的id链接
                    .where(CustomerDao.Properties.Name.eq("小明"));
            List<Order> order2 = queryBuilder2.list();

        //-----------------------------------原生查询-------------------------------------------------------
    }
}
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值