Skip to content

DAO操作

Frank Wen edited this page Aug 25, 2018 · 23 revisions

对象-文档映射中那样,给实体类加上了注解,并且实现了BuguEntity接口,接下来就可以使用BuguDao类操作该实体了。

BuguDao构造函数

你需要编写自己的Dao,如FooDao,来操作Foo相关的数据。FooDao需要继承自BuguDao,并且,在FooDao的构造函数中,需要传递Foo.class,如下:

public class FooDao extends BuguDao<Foo> {
    public FooDao(){
        super(Foo.class);
    }
}

插入

BuguDao中有如下方法可用于插入数据:

public WriteResult insert(T t)

public WriteResult insert(List<T> list)  //批量插入

public WriteResult save(T t)  //如果t中没有ID值,则为插入,若有ID值,则为修改。用户自定义ID除外。

其中,当使用save(obj)方法时,如果obj中的id值为null,则实际执行插入操作;如果obj中的id值不为null,则实际执行修改操作。(@Id的type=IdType.USER_DEFINE的情况除外)

例:

Foo foo = new Foo();
foo.setName("Frank");
foo.setLevel(10);

FooDao dao = new FooDao();
dao.save(foo);
String id = foo.getId();  //保存至数据库后,foo中有id值了

删除

public void drop()  //删除整个Collection

public WriteResult remove(T t)

public WriteResult remove(String id)

public WriteResult remove(List<String> idList)  //批量删除

public WriteResult remove(String key, Object value)  //按条件删除

public WriteResult remove(BuguQuery query)  //按条件删除

修改

对于修改过的对象,可以调用如下方法进行保存:

public WriteResult save(T t)

更新

mongoDB提供了大量的对数据记录进行直接更新的方法,这些方法实在太多了,因此bugu-mongo把这些方法集中到了一个类BuguUpdater中:

FooDao dao = new FooDao();
BuguUpdater updater = dao.update();

我们看看BuguUpdater类中有哪些方法:

/* 设置更新属性 */

public BuguUpdater<T> set(String key, Object value)

public BuguUpdater<T> set(Map<String, Object> map)

public BuguUpdater<T> unset(String key)

public BuguUpdater<T> unset(String... keys)

public BuguUpdater<T> inc(String key, Object value)

public BuguUpdater<T> mul(String key, Object value)

public BuguUpdater<T> addToSet(String key, Object value)

public BuguUpdater<T> push(String key, Object value)

public BuguUpdater<T> pushEach(String key, List valueList)

public BuguUpdater<T> pull(String key, Object value)

public BuguUpdater<T> pullAll(String key, Object... valueArray)

public BuguUpdater<T> popFirst(String key)

public BuguUpdater<T> popLast(String key)

public BuguUpdater<T> min(String key, Object value)

public BuguUpdater<T> max(String key, Object value)

public BuguUpdater<T> bitwise(String key, int value, Bitwise bitwise)

/* 执行更新操作 */

public WriteResult execute(T t)  //更新某一条记录

public WriteResult execute(String id)  //更新某一条记录

public WriteResult execute(BuguQuery query)  //更新某些符合查询条件的记录

public WriteResult execute()  //更新全部记录

BuguUpdager支持连缀的书写形式,例如:

//把foo的name改成为Franky,并且把level值增加1
dao.update().set("name", "Franky").inc("level", 1).execute(foo);  

BuguUpdater有几个不同的execute方法,可以用于更新某一条记录、某些符合查询条件的记录、或者全部记录。例如:

dao.update().inc("level", 1).execute();  //把所有文档的level值增加1

BuguQuery query = dao.query().is("gender", "male");
dao.update().inc("level", 1).execute(query);  //把所有符合query查询条件的文档的level值增加1

Foo foo = ...
dao.update().inc("level", -1).execute(foo);  //把单个foo对象的level值减1

默认情况下,若需要执行更新的记录不存在,则更新操作不会起作用。在某些应用场合,如果需要执行更新的记录不存在,希望能自动创建一条记录,则可以通过setUpsert(true)来实现,如下:

//如果name为Frank的记录不存在,则会自动创建一条name为Frank、level为100的记录  
BuguQuery query = dao.query().is("name", "Frank");
dao.update.set("level", 100).setUpsert(true).execute(query);  

基本查询

BuguDao类中提供了一些基本的查询方法,如下:

/* 查询一个 */

public T findOne(String id)

public T findOne(String key, Object value)

/* 查询全部 */

public List<T> findAll()

public List<T> findAll(String orderBy)

public List<T> findAll(int pageNum, int pageSize)

public List<T> findAll(String orderBy, int pageNum, int pageSize)

/* 查询是否存在 */

public boolean exists(String id)

public boolean exists(String key, Object value)

/* 查询数目 */

public long count()

public long count(String key, Object value)

/* 查询某一字段的不重复值 */

public List distinct(String key)

高级查询

更高级的查询需要用到BuguQuery类。先看看BuguQuery类中有些什么方法:

/* 生成查询条件 */

public BuguQuery<T> is(String key, Object value)

public BuguQuery<T> notEquals(String key, Object value)

public BuguQuery<T> greaterThan(String key, Object value)

public BuguQuery<T> greaterThanEquals(String key, Object value)

public BuguQuery<T> lessThan(String key, Object value)

public BuguQuery<T> lessThanEquals(String key, Object value)

public BuguQuery<T> in(String key, Object... values)

public BuguQuery<T> in(String key, List list)

public BuguQuery<T> notIn(String key, Object... values)

public BuguQuery<T> notIn(String key, List list)

public BuguQuery<T> all(String key, Object... values)

public BuguQuery<T> size(String key, int value)

public BuguQuery<T> mod(String key, int divisor, int remainder)

public BuguQuery<T> existsField(String key)

public BuguQuery<T> notExistsField(String key){

public BuguQuery<T> regex(String key, String regex)

public BuguQuery<T> where(String whereStr)

/* 多个查询条件的AND、OR、NOR */

public BuguQuery<T> and(BuguQuery... querys)

public BuguQuery<T> or(BuguQuery... querys)

public BuguQuery<T> nor(BuguQuery... querys)

/* 设置查询参数 */

public BuguQuery<T> slice(String key, long num)

public BuguQuery<T> returnFields(String... fieldNames)

public BuguQuery<T> notReturnFields(String... fieldNames)

public BuguQuery<T> sort(String orderBy)

public BuguQuery<T> sortAsc(String key)

public BuguQuery<T> sortDesc(String key)

public BuguQuery<T> pageNumber(int pageNumber)

public BuguQuery<T> pageSize(int pageSize)

/* 返回查询结果 */

public T result()  //返回一个实体

public List<T> results()  //返回多个实体

public long count()

public boolean exists()

public List distinct(String key)

创建BuguQuery

通过调用BuguDao中的query()方法,就可以创建一个BuguQuery对象:

public class FooDao extends BuguDao<Foo> {
    public FooDao(){
        super(Foo.class);
    }
    ...
}

FooDao dao = new FooDao();
BuguQuery<Foo> q = dao.query();
...

用BuguQuery实现查询

支持连缀书写形式:

List<Foo> list = dao.query().greaterThan("level", 10).notEquals("name", "Frank").results();

支持分页:

List<Foo> list = dao.query().greaterThan("level", 10).notEquals("name", "Frank").pageNumber(1).pageSize(20).results();

支持指定返回、不返回某些字段:

//只返回id、name、level这三个字段
BuguQuery query1 = dao.query().greaterThan("level", 10).returnFields("name", "level") ;

//不返回detail、comments这两个字段
BuguQuery query2 = dao.query().greaterThan("level", 10).notReturnFields("detail", "comments");  

支持Entity对象作为查询条件:

FatherDao fDao = new FatherDao();
FatherFoo father = fDao.query().is("id", "4dcb4d1d3febc6503e4e5933").result();
Foo foo = dao.query().is("father", father).result();  //用FatherFoo对象作为查询条件

支持多个查询条件的AND、OR、NOR:

BuguQuery<Foo> q1 = dao.query().is("name", "Frank");
BuguQuery<Foo> q2 = dao.query().is("name", "Tom");
List<Foo> list = dao.query().or(q1, q2).results();

支持字符串形式的排序:

List<Foo> list = dao.query().in("name", "Frank", "John")
    .sort("{level:1, timestamp: -1}")
    .results();

关于排序的详细说明,请参考这里

如果是单个条件的排序,可以使用sortAsc()或sortDesc():

List<Foo> list = dao.query().is("gender", "Male")
    .sortDesc("age")  //按年龄倒序
    .results();

注意事项

1、对于数组、List、Set,在MongoDB中都被保存成数组,可以用push、pull等方法对其进行操作。

2、对数据库的更新操作,都有一个返回值WriteResult,代表了操作的结果。

3、使用DAO操作MongoDB时,应该使用数据库的字段名称,而不是Java的属性名称。

比如:

@Property(name="total_score")
private int totalScore;

那么,操作数据库的时候,应该是:

list = dao.query().is("total_score", 1000).results();    //注意:不是totalScore

一种较好的习惯是:尽量不设置@Property、@Embed、@EmbedList、@Ref、@RefList等注解的name属性,使得数据库的字段名称,与Java的属性名称,保持一致。