本文隶属于专题系列: 通用数据库访问层dexcoder-dal

注意:本组件已重构并全新发布,更加方便易于使用。代码全部开源,详情访问 Github仓库码云

之前写过一个基于spring JdbcTemplate的通用dao,以及它初步的改进版,有兴趣的可以看一下这个系列,记录了这个通用dao的编写过程。

改进版的通用dao之前已经初步介绍过,经过这段时间的使用以及用它开发了一个简单的站点,里面的很多方法进行了改近和重构,目前已经基本稳定。对于单表操作,基本能省去90%以上的sql代码甚至更多。

下面讲讲这个改进版通用dao的使用和实现过程。

改进版的通用dao把泛型的操作从类上移到了方法上,因此每个实体就不需要对应的一个所谓的通用dao了,一个通用dao操作所有的实体,这是最大的变化。

通用dao对所有的操作方法都提供了两种方式的操作,即传入实体和传入class,在不同的场合两种方式各有优势。

这里创建一张用户表作测试,多个表也是一样的。

创建测试表:

CREATE TABLE `USER` (
  `USER_ID` int(11) NOT NULL AUTO_INCREMENT,
  `USER_NAME` varchar(45) DEFAULT NULL,
  `USER_AGE` int(11) DEFAULT NULL,
  `GMT_CREATE` datetime DEFAULT NULL,
  `GMT_MODIFY` datetime DEFAULT NULL,
  PRIMARY KEY (`USER_ID`)
)

insert操作,自动生成主键,oracle等序列方式数据库指定序列名即可,会自动处理,看具体介绍

//方式一
User user = new User();
user.setUserName("liyd");
user.setUserAge(16);
user.setGmtCreate(new Date());
Long userId = superDao.insert(user);
//方式二
Long userId2 = superDao.set("userName", "liyd2").set("userAge", 16)
    .set("gmtCreate", new Date()).insert(User.class);
//方式三 也可混合使用,包括update等,不推荐,下面不再介绍
User user3 = new User();
user3.setUserAge(16);
user3.setGmtCreate(new Date());
Long userId3 = superDao.set("userName", "liyd3").insert(user3);

save操作,跟insert的区别是不会自动处理主键,由手工设置,这当你想临时插入一条标识记录时(如主键为负值),十分有用

//方式一
User user = new User();
user.setUserId(-1L);
user.setUserName("liyd");
user.setUserAge(16);
user.setGmtCreate(new Date());
superDao.save(user);
//方式二
superDao.set("userId",-2).set("userName", "liyd2").set("userAge", 16)
        .set("gmtCreate", new Date()).save(User.class);

update操作

//方式一
User user = new User();
user.setUserId(30L);
user.setUserName("selfly");
superDao.update(user);
//方式二
superDao.set("userName", "selfly2").where("userId", new Object[] { 32L })
    .update(User.class);

delete操作

//根据主键删除
superDao.deleteById(User.class, 29L);
//根据实体对象删除,会以不为空的属性值作为条件,不一定是主键
User user = new User();
user.setUserId(28L);
superDao.deleteByEntity(user);
//根据class对象删除
superDao.where("userId", new Object[] { 27L }).delete(User.class);

删除所有

这个采用了TRUNCATE的方式,因此删除所有后自增id也会从新开始。

superDao.deleteAll(User.class);

根据主健查询

User user = superDao.getById(User.class, 32L);

根据条件查询单个结果,当返回有多条记录时取第一条,没有时返回null

//方式一 会以实体对象不为null的属性值作为条件
User user = new User();
user.setUserId(32L);
user = superDao.querySingleResult(user);
//方式二
User user2 = superDao.where("userId", new Object[] { 32L }).querySingleResult(User.class);

列表查询

//方式一
User user = new User();
user.setUserName("liyd");
List<User> users = superDao.queryList(user);
//方式二
List<User> users2 = superDao.where("userName", new Object[] { "liyd" }).queryList(
    User.class);

查询所有记录

这个去掉了之前的findAll方法,用以下方式即可实现,当不指定任何条件时即返回所有。

List<User> users = superDao.include("userId").queryList(User.class);

记录数查询

//方式一
User user = new User();
user.setUserName("liyd");
int count = superDao.queryCount(user);
System.out.println(count);
//方式二
int count2 = superDao.where("userName", new Object[] { "liyd" }).queryCount(User.class);
System.out.println(count2);

上面是一些基本的查询,区别不大,下面是改进后区别于其它通用dao更方便的地方。

所有的组合方法使用都是通用的,可以自由组合,并不限于以下举例的几种。

查询白名单

以下查询将只返回userId,其它字段将被忽略。

这在你的表中有大内容字段时十分有用,不仅仅是blog等这种大字段。如文章列表查询时可以忽略文章内容将显著提高性能。

//方式一
List<User> users = superDao.include("userId").where("userId", new Object[] { 1L })
    .queryList(User.class);
//方式二
User user = new User();
user.setUserId(1L);
List<User> users1 = superDao.include("userId").queryList(user);

查询黑名单

跟白名单类似,以下查询将返回除了userName之外的所有字段。

当白名单和黑名单同时指定时,以白名单为准。

//方式一
List<User> users = superDao.exclude("userName").where("userId", new Object[] { 1L })
    .queryList(User.class);
//方式二
User user = new User();
user.setUserId(1L);
List<User> users1 = superDao.exclude("userName", "userAge").queryList(user);

指定操作符查询

这类查询只能以传入class的方式进行。操作符不指定时默认为=号。

以下查询中,指定了操作符,可以指定in、not in、>、<、>=、<=等各类操作符。

List<User> users = superDao.where("userId", "in", new Object[] { 17L, 18L, 19L })
            .queryList(User.class);
List<User> users2 = superDao.where("userId", ">=", new Object[] { 17L })
        .queryList(User.class);

or或and条件查询

可以自由组合进行。

List<User> users = superDao.where("userId", ">=", new Object[] { 17L })
    .and("userName", new Object[] { "liyd" }).or("userId", "<", new Object[] { 1L })
    .queryList(User.class);

排序

//方式一
User user = new User();
user.setUserName("liyd");
List<User> users = superDao.desc("userId").queryList(user);
//方式二
List<User> users2 = superDao.where("userName", new Object[] { "liyd" }).asc("userId")
    .queryList(User.class);

混合查询示例

List<User> users = superDao.include("userId")
    .where("userName", "in", new Object[] { "liyd", "selfly" })
    .and("userId", ">=", new Object[] { 17L }).or("userId", "<=", new Object[] { 1L })
    .asc("userId").queryList(User.class);
你可能感兴趣的内容
1条评论
ls2005nba 1年前
没有源码呀 大神能不能给一份完整的源码参考一下

selfly

交流QQ群:32261424
Owner