MyBatis增强工具pndao-帮你自动写SQL

原创
2016/10/31 00:09
阅读数 2.1W

pndao是票牛技术团队在使用的MyBatis增强工具,它可以根据一些方法约定,自动生成SQL。它在实际生产中减少了80%以上的重复SQL编写工作。

起因

作为Java后端开发,写DAO是个日常的不能再日常的工作。

这方面有很多工具,有重量级的Hibernate,轻量级的DbUtils、Spring JDBC等。其中MyBatis以接口声明来生成DAO,实现了接口与实现分离,并约定POJO来作为实体类,同时提供一些便捷的脚本扩展,是一套规范性和灵活性并存的方案,已经成为很多团队的首选。我用过很久MyBatis(iBatis),其实它从最开始到现在已经有不小的进步,但是仍然会被大量的复制字段、SQL拼写错误、记不得一些繁琐的语法困扰。

相信很多人都基于MyBatis写过daogen,MyBatis也提供了官方的插件MyBatis Generator,但是这些工具都是一次性生成DAO以及SQL,后期维护成本依然比较高,每次增减字段都需要手动改,如果有手写的SQL还要手动DIFF,也比较麻烦。

有一些新的框架,例如jFinal,其实已经集成了常用SQL生成这样的功能,但是一般会绑定自己的框架,使用成本比较高,迁移也很困难。

目前使用的这个版本的daogen支持MyBatis,并且能生成常用SQL,并且每次编译都会重新生成SQL,不仅省去一次性编码,也解决了维护的问题。经过一年的使用,基本上常用功能都已经能够覆盖。都是吃自己狗粮出来的,专为解决问题而生,没有半点花架子。

原理

pndao的原理并不复杂,是基于MyBatis的方法命名约定来生成SQL,并且写入MyBatis需要的XML。

写之前会判断是否已经存在XML或者注解,如果已经存在则略过此方法,所以无论是注解还是XML方式配置SQL都是兼容的。

有一点不同的是,这个是基于jsr269的编译期注解处理来实现的,所以其实整个方案跟MyBatis并没有强绑定,基于这种思路还可以做出其他很多有用的东西来。

以下是一个常见的DAO功能:

public class UserDaoTest extends AbstractTest{

	public static final int USER_ID = 1;

	@Autowired
	private UserDao userDao;

	@Test
	public void testInsertUser() throws Exception {
		User user = initUser();
		assertThat(userDao.insert(user)).isEqualTo(1);
	}

	@Test
	public void testFindUserById() throws Exception {
		User user = userDao.findById(USER_ID);
		assertThat(user).isNotNull();
	}

	@Test
	public void testUpdateUserName() throws Exception {
		assertThat(userDao.updateForUserName("用户13700000001",USER_ID)).isEqualTo(1);
	}
}

基于pndao,所有需要开发的DAO只有这些:

@DaoGen
public interface UserDao {

	int updateForUserName(@Param("userName") String userName, @Param("id") int id);

	int insert(User t);

	User findById(int id);

}

结合建表语句生成插件pngen,大部分场景只需编写一个模型类即可完成DAO层工作。

更多的东西可以看项目,地址:http://git.oschina.net/piaoniu/pndao

展开阅读全文
打赏
7
213 收藏
分享
加载中
个人还是习惯 Generator 多一点. 比如有这么一个表

drop table if exists `t_system_config`;
create table if not exists `t_system_config` (
`id` bigint(20) not null auto_increment,
`con_key` varchar(32) not null default '' comment '键',
`con_value` varchar(64) not null default '' comment '值',
`con_comment` varchar(128) default null comment '说明',
primary key (`id`)
) engine=myisam default charset=utf8mb4 comment='全局配置表';


如果想要生成这样的 sql 语句:
select count(*) from system_config where con_key = 'xxx' and con_value not in ('yyy', 'zzz')


对应的 Example 这么写:
SystemConfigExample example = new SystemConfigExample();
example.or().andConKeyEqualTo("xxx").andConValueNotIn(A.lists("yyy", "zzz"));
systemConfigMapper.countByExample(example);


null, not null, =, <>, >, >=, in, not in, between, not between 都可以用 example 轻松构造出来, 可能也就复杂一点的 or 不大好构建
2017/03/30 18:35
回复
举报
越来越像hibernate、别动摇直接用hibernate、hql、sql随便用,还折腾什么jdbc bt的
2016/11/03 10:20
回复
举报
生成sql的话,MyBatis官方就有MyBatis Generator啊。有什么不一样的地方吗?
2016/11/02 10:41
回复
举报
@魔力猫 用过 jooq 吗?
2016/11/02 10:03
回复
举报

引用来自“士别三日”的评论

我觉得sql就应该手写,用程序生成的既不好性能优化,又很难使用不同数据库的不同特性。
赞同
2016/11/01 19:21
回复
举报
黄亿华博主

引用来自“风中蜡烛”的评论

引用来自“士别三日”的评论

我觉得sql就应该手写,用程序生成的既不好性能优化,又很难使用不同数据库的不同特性。

我也赞成。好多工作几年的程序员用自动生成工具或者hibernate连基本的sql语句都不会写!我团队的小伙伴我要求必须手写sql。

sql是必备技能,我们稍微复杂的sql也是手写,所以这个只生成基本sql,为了写一个按主键查询就要拼齐几个字段这种就没啥意义了
2016/11/01 19:08
回复
举报
黄亿华博主

引用来自“sgq0085”的评论

能跨表关联查询么?

这个是手写的
2016/11/01 19:06
回复
举报
黄亿华博主
这个是手写的
2016/11/01 19:05
回复
举报
能跨表关联查询么?
2016/11/01 17:47
回复
举报

引用来自“士别三日”的评论

我觉得sql就应该手写,用程序生成的既不好性能优化,又很难使用不同数据库的不同特性。

我也赞成。好多工作几年的程序员用自动生成工具或者hibernate连基本的sql语句都不会写!我团队的小伙伴我要求必须手写sql。
2016/11/01 17:42
回复
举报
更多评论
打赏
26 评论
213 收藏
7
分享
返回顶部
顶部