DAO 操作
像对象-文档映射中那样,给实体类加上了注解,并且实现了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的属性名称,保持一致。