众所周知,Spring 的核心卖点在于 IOC 和 AOP,甚至在十几年前 Java 界流行只用它的这两个特性,所以出现了 struts,spring,hibernate/mybatis 的组合,后来 struts 和 hibernate 渐渐淡出舞台,SpringMVC 已经完全替代了 struts,到此 Spring 可以说基本上已经统一了 JavaWeb 领域,只是还剩下持久层还没被他拿下来。
我个人认为主要原因在于两点:
- 国人比较喜欢写 SQL 而不是玩 ORM,之前 hibernate 被淘汰就足以说明了,所以 spring-data-jpa 在国内根本吃不开。
- 虽然 spring 提供了写 SQL 的工具类 JdbcTemplate,但是它确实不太好用。
关于 SQL 应该放哪
有时候我们冷静下来想一想,既然都要写 SQL 了,真的有必要把它放到 XML 里吗?把它作为一个字符串写在代码里不好吗?Java 的 String 早就有了这种写法。
String sql = """
select
id,
name,
age
from
m_user_info
where
age > {age}
""";
整条 SQL 一目了然,不需要大量的 append,当然了,根据参数拼接条件还是避免不了,但是这种情况即使写在 XML 里也是有一堆 if else 的,而且追踪起来不如代码方便
把 SQL 作为一个字符串传给某个方法,从而进行数据库的增删改查操作,这种写法大家肯定不陌生,事实上大部分框架都是支持的,只是用得少而已,这其中当然包括 spring 的 JdbcTemplate。
那么,我们是不是可以这么认为?如果不玩 ORM 是不是可以放弃 Mybatis 了?直接用 JdbcTemplate 就行了,【写好 SQL】 -> 【传进去】 -> 【得到结果】,简简单单完成任务。
进入正题
我今天要讲的是一个工具包,它里面就对 JdbcTemplate 做了一些扩展,让他用起来更方便,主要有以下几点:
- 在 SQL 里面支持 {属性名} 占位符
- 根据第一点,大家应该能推测出来,在传参方面支持了实体对象和 Map
- 单表的增删改查操作不需要写 SQL
- 天然支持 MySql 分页
以下用几个示例来演示一下
单表插入
ParamPO paramPO = new ParamPO();
paramPO.setUserName("a");
paramPO.setUserEmail("test@qq.com");
int result = MagicDBUtils.get(jdbcTemplate).insert("表名", paramPO);
单表修改数据
// 构建修改条件
ConditionBuilder conditionBuilder = ConditionBuilder.createCondition()
.add("id = ?", 10)
.add("and name = ?", "bee");
// 构建修改数据
ParamPO paramPO = new ParamPO();
paramPO.setUserName("a");
paramPO.setUserEmail("test@qq.com");
// 执行修改
int result = MagicDBUtils.get(jdbcTemplate).update("表名", paramPO, conditionBuilder);
单表删除数据
// 构建删除条件
ConditionBuilder conditionBuilder = ConditionBuilder.createCondition()
.add("id = ?", 10);
// 执行删除
int result = MagicDBUtils.get(jdbcTemplate).delete("表名", conditionBuilder);
单表查询数据
// 构建查询条件
ConditionBuilder conditionBuilder = ConditionBuilder.createCondition()
.add("id > ?", 10)
.add("and (name = ? or age > ?)", "bee", 10)
.add("order by create_time", Condition.NOT_WHERE);
// 执行查询
List<parampo> result = MagicDBUtils.get(jdbcTemplate).select("表名", conditionBuilder, ParamPO.class);
自定义 SQL 查询
ParamPO paramPO = new ParamPO();
paramPO.setId(5);
paramPO.setUserName("a");
// 采用{}占位符的写法
List<parampo> result = MagicDBUtils.get(jdbcTemplate).selectList("select * from xt_message_board where id > {id} and user_name != {user_name}", paramPO, ParamPO.class);
// 采用 ? 占位符的写法
List<parampo> result = MagicDBUtils.get(jdbcTemplate).selectList("select * from xt_message_board where id > ? and user_name != ?", new Object[]{5, "a"}, ParamPO.class);
分页查询
// 查询条件
ParamPO paramPO = new ParamPO();
paramPO.setId(5);
paramPO.setUserName("a");
// 查询参数
PageParamModel pageParamModel = new PageParamModel();
pageParamModel.setCurrentPage(1);
pageParamModel.setPageSize(10);
pageParamModel.setParam(paramPO);
// 使用默认countSql查询
PageModel<parampo> pageModel = MagicDBUtils.get(jdbcTemplate).selectPage("select * from xt_message_board where id > {id} and user_name != {user_name}", pageParamModel, ParamPO.class);
// 使用自定义countSql查询
String countSql = "自己定义countSql";
PageModel<parampo> pageModel = MagicDBUtils.get(jdbcTemplate).selectPageCustomCountSql("select * from xt_message_board where id > {id} and user_name != {user_name}", countSql, pageParamModel, ParamPO.class);
其他
如果想了解更多信息可以访问官方:https://magician-io.com