官网地址: https://www.summer-data.com
代码库地址:https://gitee.com/hahan2020/summer-data
summer-data 是什么?
summer-data
设计用于替代 mybatis 和 hibernate 。从个人角度挑一些它们和 spring jdbc-template 的缺点,这些缺点是我创作summer-data
的原因。
- mybatis
- 需要学习 XML 带来的语法,另外 XML 在处理带有逻辑的动态 SQL 时乏力。
- 也需要拼装 SQL,容易出错
- hibernate
- 用力过猛,数据库操作中间隔着一层 java,隔靴搔痒的感觉
- 更新数据需要先查询数据,然后再更新,很不理解这种设计
- spring jdbc-template
- 拼写 SQL 比较麻烦且容易出错,其它方面都挺好的
认识summer-data
假设有2个表
我们通过 Table 子类将这2个表的投射到 Java 。
@TableName("t_prod")
public class Prod extends Table {
@AutoGenerated
public IntegerColumn res_id;
@MaxLength(100)
public StringColumn prod_name;
@MaxLength(100)
public StringColumn prod_desc;
}
@TableName("t_prod_detail")
public class ProdDetail extends Table {
@AutoGenerated
public IntegerColumn prod_res_id;
public IntegerColumn res_id;
@MaxLength(100)
public StringColumn detail_name;
}
注意:所有的表要继承Table类,字段设定成public 。
持久化
Prod t1 = new Prod();
t1.prod_name.setValue("walker");
// insert into t_prod(prod_name) values('walker');
t1.insert();
// update t_prod set prod_name='walker' where res_id='123';
t1.updateBy(t1.id.eq("123"));
// delete from t_prod where res_id='123';
t1.deleteBy(t1.res_id.eq("123"));
单表查询
Prod t1 = new Prod();
Jql jql = new Jql()
.select(t1)
.from(t1)
.where(t1.res_id.in(1, 2, 3))
.order(t1.prod_name.desc());
// 返回 Map 结构
List<Map<String, Object>> list = jql.queryForMap();
// 返回 Object
List<Prod> prodList = jql.queryForObject(Prod.class);
联合查询
定义一个 VTO 类,存放查询数据
public class ProdVTO {
public String prod_name;
public String prod_desc;
public Integer prod_res_id;
public Integer res_id;
public String detail_name;
}
业务代码
Prod t1 = new Prod();
ProdDetail t2 = new ProdDetail();
Jql jql = new Jql()
.select(t1.prod_name, t1.prod_desc, t2)
.from(t1)
.join(t2).on(t1.res_id.eq(t2.prod_res_id))
.where(t1.prod_name.isNotNull())
.and(t1.prod_name.like("中文"))
.or(t1.res_id.in(1, 2, 3))
.order(t2.detail_name.desc());
// 返回 Map
List<Map<String, Object>> list = jql.queryForMap();
// 返回 Object
List<ProdVTO> list = jql.queryForObject(ProdVTO.class);
上面的 Jql 最终都会转成如下sql执行:
SELECT t1.prod_name, t1.prod_desc, t2.*
FROM t_prod t1
JOIN t_prod_detail t2 ON t1.res_id = t2.prod_res_id
WHERE t1.prod_name IS NOT NULL
AND t1.prod_name LIKE '%中文%'
OR t1.res_id IN (1, 2, 3)
ORDER BY t2.detail_name DESC
也可以用 java 的双大括号语法。
Jql jql = new Jql(){{
select(t1.prod_name, t1.prod_desc, t2);
from(t1);
join(t2).on(t1.res_id.eq(t2.prod_res_id));
where(t1.prod_name.isNotNull());
and(t1.prod_name.like("中文"));
or(t1.res_id.in(1, 2, 3));
order(t2.detail_name.desc());
}};
链式写法和双大括号写法都可以,选哪个看项目组编码规范和个人习惯。
summer-data 的特点
- 优点
- 借助 IDE 拼写 Jql 全程有提示,速度飞快
- 在编译阶段就能检查拼写错误
- 支持 Java 的重构。表改名、字段改名没有任何心里负担,比如 Prod 的表名从
t_prod
改成t_prod_new
,只需要修改 Prod 类的注解即可。 - 异构数据库支持,在执行阶段 Jql 会根据数据库的不同,生成相应的 SQL 执行。
summer-data
更注重开发效率和开发体验,有些时候它看上去并不优雅。
- 字段定义给 Jql 让步,比如: varchar 字段使用 StringColumn ,而不是 String。
- 字段访问范围给 Jql 让步,所有字段定义访问范围都是 public 。
- pojo 为 Jql 让步,所有表都继承 Table 。
summer-data
追求简单、自然、高效,希望你能喜欢它。