前言:
在年前刚写的18年年终总结中,有提到使用了一个对JdbcTemplate封装了一层的NamedParameterJdbcTemplate。
下面是我对其进行的一些总结:
参数支持类:
SqlParameterSource :
可以使用SqlParameterSource实现作为来实现为命名参数设值,默认实现有 :
MapSqlParameterSource实现非常简单,只是封装了java.util.Map;
BeanPropertySqlParameterSource封装了一个JavaBean对象,通过JavaBean对象属性来决定命名参数的值。
EmptySqlParameterSource 一个空的SqlParameterSource ,常用来占位使用
查询方法:
1.返回Object类型的数据:
API: public < T > T queryForObject(String sql, Map<String, ?> paramMap, Class<T> requiredType)
API: public < T > T queryForObject(String sql, SqlParameterSource paramSource, Class<T> requiredType)
//示例:
Integer count = template.queryForObject("select count(1) from uos_staff a", new HashMap<>(), Integer.class);
String name = template.queryForObject( "select a.staff_id,a.staff_name from uos_staff a where staff_id = 220001 ", EmptySqlParameterSource.INSTANCE, String.class); //这里使用了EmptySqlParameterSource,用来做一个空的占位符
2.返回多行数据:
API: public < T> List< T> queryForList(String sql, Map<String, ?> paramMap, Class< T > elementType)
API: public < T> List< T> queryForList(String sql, SqlParameterSource paramSource, Class< T> elementType)
API: public < T> List< T> query(String sql, Map< String, ?> paramMap, RowMapper< T> rowMapper)
API: public < T> List< T> query(String sql, SqlParameterSource paramSource, RowMapper< T> rowMapper)
API: public < T> List< T> query(String sql, RowMapper< T> rowMapper)
//示例:
List< String> nameList = template.queryForList("select a.staff_id,a.staff_name from uos_staff", new HashMap<>(), String.class);
3.返回Map形式的单行数据
API: public Map< String, Object> queryForMap(String sql, Map< String, ?> paramMap)
API: public Map< String, Object> queryForMap(String sql, SqlParameterSource paramSource)
//示例:
Map< String, Object> studentMap = template.queryForMap("select a.staff_id,a.staff_name from uos_staff where staff_id = 220001", new HashMap<>());
更新方法:
1.使用Map作为参数
API: int update(String sql, Map<String, ?> paramMap)
//示例:
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("id", "666666");
paramMap.put("staffName", "测试人员1");
paramMap.put("staffId", 220009);
template.update( "insert into uos_staff(id,staff_id,staff_name) values (:id,:staffId,:staffName)",paramMap);
2.使用BeanPropertySqlParameterSource作为参数
API: int update(String sql, SqlParameterSource paramSource)
//示例(BeanPropertySqlParameterSource作为参数):
public class StaffDTO{
private String id;
private String staffId;
private String staffName;
//getter,setter...
}
StudentDTO dto=new StudentDTO();//这个DTO为传入数据
dto.setId("666667");
dto.setStaffId("220010");
dto.setStaffName("测试人员1");
template.update("insert into uos_staff(id,staff_id,staff_name) values (:id,:staffId,:staffName)",new BeanPropertySqlParameterSource(dto));
3.使用MapSqlParameterSource 作为参数
API: int update(String sql, MapSqlParameterSource mapSqlParameterSource)
//示例
MapSqlParameterSource mapSqlParameterSource = new MapSqlParameterSource()
.addValue("id", "666668")
.addValue("staffId", "220011")
.addValue("staffName", "测试人员2");
template.update("insert into uos_staff(id,staff_id,staff_name) values (:id,:staffId,:staffName)",mapSqlParameterSource);
项目实战实例
在项目中的话,可以将其进行二次封装,重写分页查询的方法,将查出来的key转为驼峰式、小写或者原样输出(针对Oracle默认转大写)等等。。
GitHub链接:NamedParameterJdbcTemplate项目应用-数据库基本操作统一入口
//分页查询实例代码(Page可以直接进行封装):
//在DAO中只要继承其即可。
Map resultMap = new HashMap<>();
int pageIndex = MapUtils.getIntValue(param, "pageIndex",1);
int pageSize = MapUtils.getIntValue(param, "pageSize",10);
try {
Page page = super.queryForPage(sql, param, pageIndex, pageSize);
resultMap.put("rows", page.getList());
resultMap.put("records", page.getTotalNumber());
resultMap.put("page", page.getCurrentPage());
resultMap.put("pageSize", page.getPageSize());
resultMap.put("total", page.getTotalPage());
} catch (SystemException | RequiredException | SQLException e) {
logger.error(e.getMessage(), e);
}
但是在二次封装完之后,存在一定的不足,遇到的话可以自行修改优化
1.一些参数类型不会自动转换,比如在查询,某条件例如员工ID,页面上为number类型,数据库为VARCHAR2类型,那么在查询时要加tochar(:staffId),即使在前端将其用引号括起来也不行!!!
2.上面封装完的查询,不管是普通查询还是分页查询,返回的都是Map、List<Map>...等这种类型,不再是面向对象,可以说是面向Map了,违反了面向对象的规范!!!
版权声明:本文为Jaiaxn原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。