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

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

最近因为事情比较多好久没写博客,一晃居然都几个月了。

之前随手写的Spring JdbcTemplate实现通用的泛型daospring整合quartz整合动态定时任务系列,没想到会有那么多人向我要源码和demo, 这里要说声抱歉了,因为之前写的时候并没有特地的整理及示范的demo,也因为博客一直没更新,差不多导致这两个文章都烂尾了,趁这段时间把它们完成吧。

先说说Spring JdbcTemplate实现通用的泛型dao吧。

其实最初的目的是因为我个人要开发网站,为了方便。

hibernate不怎么喜欢用,早先用的mybatis感觉总是要写sql的xml比较麻烦,想着能不能用一个轻量的类似db-utils的东西(不得不说多少有些受osc的影响), 刚好spring jdbc是个类似的实现,所以就简单封装了下,没想到发出来之后关注的人挺多,看来这方面还是有实际需求的。

看过我之前博客的人应该知道,前面我应该算是有两个版本的实现了,现在要说的,应该算是第三个版本。下面说说它们的区别。

第一个版本:

叫它一般的实现版本吧,每个实体类都需要对应一个dao,这个dao也算是通用实现的dao吧,继承于超类的泛型实现,典型的代码如下:

public class UserDaoImpl extends BaseDaoImpl
  implements UserDao {
}

缺点在于很多业务不强的实体在建立这个dao后,可能里面都没有实现内容,比较麻烦浪费。

另外对于in、!=或or等查询无能为力。

第二个版本:

第二个版本称作SuperDao吧,之前也有文章写过,下面是它的典型的查询代码:

List
  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);

黑名单、白名单、条件、排序等都是用dao来完成的,在业务职责划分上不怎么清晰,另外使用了ThreadLocal,并不是很好。

第三个版本:

也就是当前的版本,是听了群里一个朋友的建议,使用了类似Criteria的方式。将在后面做具体介绍。 

之所以不停的修改,主要原因还是在使用的过程中碰到了太多不方便的地方,只有切实使用过才知道。 

在这修改的过程当中,主要是围绕以下几个情况进行改进的,和上次SuperDao时是一致的:

1、查询时,需要某个字段不等于(column != value)某个值的时候。

2、查询时,需要某个字段等于多个值(column = value1 or column = value2)的时候。

3、需要以某个或多个字段特定排序的时候。

4、当表中有个字段比较大(clob等大字段及text等),查询时又不需要用到不想返回,节省性能时。

5、分页查询很不方便,当有以某个字段排序等要求时无法实现通用。

6、有时只需要更新某一个字段时,也需要new整个对象。

7、虽然通用,但是每个实体都需要建立一个号称通用的泛型dao,有些简单的dao里面就是空的,感觉很多余。

感受中最主要的就是这几个,其它就不列举了。如果你用过或封装过一些常规的通用dao,相信也会有这些感受。

目前的版本已经大致完成且使用了一段时间,感觉还算可以,总的来说有了以下改进:

1、解决了上面列出的所有问题,并且代码量反而更少更简洁了。

2、增加查询字段的黑白名单功能,要查哪些字段由你说了算。

3、单个字段的更新或查询可以直接set、where,不必再new整个对象,并且支持一个字段匹配多个值。

4、排序功能增强,多字段、升序降序自由组合。

5、方便强大的分页功能,无须额外操作,二三行代码搞定分页,自动判断数据库,无须指定。

6、不必再每个实体类对应建立一个继承于通用dao的dao了,一个dao自动判断操作所有表。

当然,这个dao封装的都是数据库通用的操作,对于某些数据库特有的操作来说,还需要自己去实现。

它的结构应该如下图:

![class][]

特有的操作由对应的子类去实现。

目前我用的比较多的数据库是Mysql,在使用过程中并没有碰到特有的需要封装的操作(分页在其它地方完成,下面会介绍),所以下面的介绍都是以JdbcDao类为主。

首先当然是来看一下dao的接口定义了,上代码:

public interface JdbcDao {
    public Long insert(Object entity);
    public Long insert(Criteria criteria);
    public void save(Object entity);
    public void save(Criteria criteria);
    public void update(Criteria criteria);
    public void update(Object entity);
    public void delete(Criteria criteria);
    public void delete(Object entity);
    public void delete(Class clazz, Long id);
    public void deleteAll(Class clazz);
    public  List queryList(Criteria criteria);
    public  List queryList(T entity);
    public  List queryList(T entity, Criteria criteria);
    public int queryCount(Object entity);
    public int queryCount(Criteria criteria);
    public int queryCount(Object entity, Criteria criteria);
    public  T get(Class clazz, Long id);
    public  T get(Criteria criteria, Long id);
    public  T querySingleResult(T entity);
    public  T querySingleResult(Criteria criteria);
}

方法就是一般的增删改查操作,可以看到每个方法都有entity和criteria的重载,在使用时可以根据实际情况任选其一。

这里先来几个简单的使用示例,还是直接贴上我的测试类吧,比较全相信一看就能明白:

/**
 * Created by liyd on 3/3/15.
 */
public class JdbcDaoTest extends BaseTest {
    @Autowired
    private JdbcDao jdbcDao;
    private User    user;
    @Before
    public void before() {
        user = new User();
        user.setUserName("liyd");
        user.setUserAge(20);
        user.setGmtCreate(new Date());
    }
    @Test
    public void insert() {
        Long id = jdbcDao.insert(user);
        System.out.println(id);
    }
    @Test
    public void insert2() {
        Criteria criteria = Criteria.create(User.class).set("userName", "liyd22")
            .set("userAge", 22).set("gmtCreate", new Date());
        Long id = jdbcDao.insert(criteria);
        System.out.println(id);
    }
    @Test
    public void save() {
        user.setUserId(-123L);
        jdbcDao.save(user);
    }
    @Test
    public void save2() {
        Criteria criteria = Criteria.create(User.class).set("userId", -122L)
            .set("userName", "liyd22").set("userAge", 22).set("gmtCreate", new Date())
            .set("gmtModify", new Date());
        jdbcDao.save(criteria);
    }
    @Test
    public void update() {
        user.setUserId(34L);
        user.setUserName("liyd34");
        user.setGmtCreate(null);
        user.setGmtModify(new Date());
        jdbcDao.update(user);
    }
    @Test
    public void update2() {
        Criteria criteria = Criteria.create(User.class).set("userName", "liydCriteria")
            .set("userAge", "18").where("userId", new Object[] { 34L, 33L, 32L });
        jdbcDao.update(criteria);
    }
    @Test
    public void delete() {
        User u = new User();
        u.setUserName("selfly");
        u.setUserAge(16);
        jdbcDao.delete(u);
    }
    @Test
    public void delete2() {
        Criteria criteria = Criteria.create(User.class).where("userName", new Object[] { "liyd2" })
            .or("userAge", new Object[] { 64 });
        jdbcDao.delete(criteria);
    }
    @Test
    public void delete3() {
        jdbcDao.delete(User.class, 25L);
    }
    @Test
    public void queryList() {
        User u = new User();
        u.setUserName("liyd");
        List<User> users = jdbcDao.queryList(u);
        for (User us : users) {
            System.out.println(us.getUserName() + " " + us.getUserAge());
        }
    }
    @Test
    public void queryList1() {
        List<User> users = jdbcDao.queryList(Criteria.create(User.class));
        for (User us : users) {
            System.out.println(us.getUserName() + " " + us.getUserAge());
        }
    }
    @Test
    public void queryList2() {
        PageControl.performPage(1, 2);
        Criteria criteria = Criteria.create(User.class).include("userName", "userId")
            .where("userName", new Object[] { "liyd" }).asc("userId");
        jdbcDao.queryList(criteria);
        List<User> users = PageControl.getPager().getList(User.class);
        for (User us : users) {
            System.out.println(us.getUserId() + " " + us.getUserName() + " " + us.getUserAge());
        }
    }
    @Test
    public void queryList3() {
        Criteria criteria = Criteria.create(User.class).exclude("userId")
            .where("userName", new Object[] { "liyd" }).asc("userId").desc("userAge");
        List<User> users = jdbcDao.queryList(criteria);
        for (User us : users) {
            System.out.println(us.getUserId() + " " + us.getUserName() + " " + us.getUserAge());
        }
    }
    @Test
    public void queryList4() {
        Criteria criteria = Criteria.create(User.class).where("userName", "like",
                new Object[]{"%liyd%"});
        User user1 = new User();
        user1.setUserAge(16);
        List<User> users = jdbcDao.queryList(user1, criteria.include("userId"));
        for (User us : users) {
            System.out.println(us.getUserId() + " " + us.getUserName() + " " + us.getUserAge());
        }
    }
    @Test
    public void queryList5() {
        List<User> users = jdbcDao.queryList(Criteria.create(User.class));
        for (User us : users) {
            System.out.println(us.getUserId() + " " + us.getUserName() + " " + us.getUserAge());
        }
    }
    @Test
    public void queryCount() {
        User u = new User();
        u.setUserName("liyd");
        int count = jdbcDao.queryCount(u);
        System.out.println(count);
    }
    @Test
    public void queryCount2() {
        Criteria criteria = Criteria.create(User.class).where("userName", new Object[]{"liyd"})
            .or("userAge", new Object[]{27});
        int count = jdbcDao.queryCount(criteria);
        System.out.println(count);
    }
    @Test
    public void get() {
        User u = jdbcDao.get(User.class, 23L);
        System.out.println(u.getUserId() + " " + u.getUserName() + " " + u.getUserAge());
    }
    @Test
    public void get2() {
        Criteria criteria = Criteria.create(User.class).include("userName");
        User u = jdbcDao.get(criteria, 23L);
        System.out.println(u.getUserId() + " " + u.getUserName() + " " + u.getUserAge());
    }
    @Test
    public void querySingleResult() {
        User u = new User();
        u.setUserName("liyd");
        u.setUserAge(16);
        u.setUserId(23L);
        u = jdbcDao.querySingleResult(u);
        System.out.println(u.getUserId() + " " + u.getUserName() + " " + u.getUserAge());
    }
    @Test
    public void querySingleResult2() {
        Criteria criteria = Criteria.create(User.class).where("userName", new Object[] { "liyd" })
            .and("userId", new Object[]{23L});
        User u = jdbcDao.querySingleResult(criteria);
        System.out.println(u.getUserId() + " " + u.getUserName() + " " + u.getUserAge());
    }
}

下一章将讲解实现的过程,待续。。。

[class]:

你可能感兴趣的内容
Spring 之 JMS 监听JMS消息 收藏,4396 浏览
Spring 之 JMS 基于JMS的RPC 收藏,3249 浏览
Spring的BeanFactory和FactoryBean 收藏,10398 浏览
1条评论
lighthouse 1年前
感谢楼主的分享。学习中!

selfly

交流QQ群:32261424
Owner