Spring 的 JdbcTemplate 不太好用,所以我做了个扩展

79 阅读3分钟

众所周知,Spring的核心卖点在于IOC和AOP,甚至在十几年前Java界流行只用它的这两个特性,所以出现了struts,spring,hibernate/mybatis 的组合,后来struts和hibernate渐渐淡出舞台,SpringMVC已经完全替代了struts,到此Spring可以说基本上已经统一了JavaWeb领域,只是还剩下持久层还没被他拿下来。

我个人认为主要原因在于两点:

  1. 国人比较喜欢写SQL而不是玩ORM,之前hibernate被淘汰就足以说明了,所以spring-data-jpa 在国内根本吃不开。
  2. 虽然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做了一些扩展,让他用起来更方便,主要有以下几点:

  1. 在SQL里面支持 {属性名} 占位符
  2. 根据第一点,大家应该能推测出来,在传参方面支持了实体对象和Map
  3. 单表的增删改查操作不需要写SQL
  4. 天然支持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);

其他

如果想了解更多信息可以访问官方:magician-io.com