JdbcTemplate实体映射
JdbcTemplate实体映射
如果你需要使用JdbcTemplate将查询的数据映射成Java POJO,那么这篇文章适合你。
一个例子入门
下面是一个将表中一行记录映射成Map的例子,也是JdbcTemplate默认提供的功能。
List<Map<String, Object>> result = jdbcTemplate.queryForList("select id, name, age from tbl");
然而,我们更希望得到的是下面这样的。
List<User> result = jdbcTemplate.queryForList("select id, name, age from tbl", User.class);
其中User中的属性与字段一一对应,还能自动将下划线转成驼峰。
开始
实现思路是通过反射将字段映射到对象对应的属性。
核心代码
public <T> List<T> queryForList(String sql, Class<T> clazz, Object... params) {
final List<T> result = new ArrayList<>();
jdbcTemplate.query(sql, params, rs -> {
try {
// 字段名称
List<String> columnNames = new ArrayList<>();
ResultSetMetaData meta = rs.getMetaData();
int num = meta.getColumnCount();
for (int i = 0; i < num; i++) {
columnNames.add(meta.getColumnLabel(i + 1));
}
// 设置值
do {
T obj = clazz.getConstructor().newInstance();
for (int i = 0; i < num; i++) {
// 获取值
Object value = rs.getObject(i + 1);
// table.column形式的字段去掉前缀table.
String columnName = resolveColumn(columnNames.get(i));
// 下划线转驼峰
String property = CamelCaseUtils.toCamelCase(columnName);
// 复制值到属性,这是spring的工具类
BeanUtils.copyProperty(obj, property, value);
}
result.add(obj);
} while (rs.next());
} catch (Exception e) {
throw new QueryException(e);
}
});
if (CollectionUtils.isEmpty(result)) {
return Collections.emptyList();
}
return result;
}
注意:
String columnName = resolveColumn(columnNames.get(i))
用来去掉字段的表前缀,比如t.id
替换成id
String property = CamelCaseUtils.toCamelCase(columnName)
用来将字段的下划线转成属性的驼峰形式,比如page_view
转换成pageView
BeanUtils.copyProperty(obj, property, value)
是用来复制值到对象的属性中,BeanUtils
是spring的工具类,经常会使用到
下面是两个工具方法或类。
去掉表前缀
之所以去掉表前缀,是为了避免在SQL中使用别名,导致SQL过长。
private String resolveColumn(String column) {
final int notExistIndex = -1;
int index = column.indexOf(".");
if (index == notExistIndex) {
return column;
}
return column.substring(index + 1);
}
字段下划线转成属性的驼峰
当然,下划线转驼峰有很多更好的实现,这里不限制。如下是一个实现:
public final class CamelCaseUtils {
private static final char SEPARATOR = '_';
private CamelCaseUtils() {
}
public static String toCamelCase(String input) {
if (input == null) {
return null;
}
input = input.toLowerCase();
int length = input.length();
StringBuilder sb = new StringBuilder(length);
boolean upperCase = false;
for (int i = 0; i < length; i++) {
char c = input.charAt(i);
if (c == SEPARATOR) {
upperCase = true;
} else if (upperCase) {
sb.append(Character.toUpperCase(c));
upperCase = false;
} else {
sb.append(c);
}
}
return sb.toString();
}
}
使用
接下来就可以愉快的映射成POJO了:
List<User> result = queryForList("select t.id, t.name, t.age, t.mobile_phone from tbl t where t.id < ?", User.class, 100L);
如果参数比较多,还是通过数组传入:
List<User> result = queryForList("select t.id, t.name, t.age, t.mobile_phone from tbl t where t.id < ?", User.class, new Object[]{100L});
下面定义POJO:
public class User implements Serializabl {
private Long id;
private String name;
private Integer age;
private String mobilePhone;
// 省略到getters、setters
}
补充
映射成一个值
在count时,我们是希望返回一个值的,接下来是将结果映射成一个值。
public <T> T queryOneColumn(String sql, Class<T> clazz, Object... params) {
T result;
if (ArrayUtils.isEmpty(params)) {
result = jdbcTemplate.queryForObject(sql, clazz);
} else {
result = jdbcTemplate.queryForObject(sql, params, clazz);
}
return result;
}
使用:
long total = queryOneColumn("select count(1) from tbl", Long.class);
JdbcTemplate实体映射的更多相关文章
- 8.2 使用Fluent API进行实体映射【Code-First系列】
现在,我们来学习怎么使用Fluent API来配置实体. 一.配置默认的数据表Schema Student实体 using System; using System.Collections.Gener ...
- 开源实体映射框架EmitMapper介绍
开源实体映射框架EmitMapper介绍 综述 EmitMapper是一个开源实体映射框架,地址:http://emitmapper.codeplex.com/. Emit ...
- EntityFramework 实体映射到数据库
EntityFramework实体映射到数据库 在Entity Framework Code First与数据表之间的映射方式实现: 1.Fluent API映射 通过重写DbContext上的OnM ...
- EF Code First:实体映射,数据迁移,重构(1)
一.前言 经过EF的<第一篇>,我们已经把数据访问层基本搭建起来了,但并没有涉及实体关系.实体关系对于一个数据库系统来说至关重要,而且EF的各个实体之间的联系,实体之间的协作,联合查询等也 ...
- EF Code First:实体映射
二.实体映射 实体与数据库的映射可以通过DataAnnotation与FluentAPI两种方式来进行映射: (一) DataAnnotation DataAnnotation 特性由.NET 3.5 ...
- 10.1.翻译系列:EF 6中的实体映射【EF 6 Code-First系列】
原文链接:https://www.entityframeworktutorial.net/code-first/configure-entity-mappings-using-fluent-api.a ...
- 【译】第23节---Fluent API - 实体映射
原文:http://www.entityframeworktutorial.net/code-first/configure-entity-mappings-using-fluent-api.aspx ...
- 关于AutoMApping 实体映射
安装AutoMapping包 把订单实体映射成订单DTO实体 .ReverseMap()加上这个方法后 下面自定义 映射规则 第一个就是来源对象 第二个就是目标对象 https://www.cnbl ...
- abp 修改abp.zero的实体映射类,使生成的表和字段为大写状态
在我们项目中,由于涉及到报表配置管理,可以通过一段sql快捷的配置出一个报表页面.部分sql会与abp框架的一些系统表做关联查询,而abp的映射类没有单独设置表和字段的名称,默认用类名和属性名,区分大 ...
随机推荐
- vue 生命周期详解
- Python中字符串二三事
首先说两个运算符: " == " 运算符测试值的等价性,递归地比较所有内嵌对象 " is " 表达式测试对象的同一性,测试两者是否为同一对象(是否为同一地址) ...
- 【转】子类会调用父类的@PostConstruct方法
如果一个类用@Service或@Component,那么只需要用@PostConstruct修饰某个方法,该方法能在类实例化的过程中自动执行,相当于类的构造函数.同时,具备了构造函数不具备的功能. @ ...
- 那什么时候会触发BFC呢?块级格式化上下文
<html>根元素: float的值不为none: overflow的值为auto.scroll或hidden: display的值为table-cell.table-caption和in ...
- Robot Framework学习笔记
robot framework 上个用例的输出作为下个用例的输入 (Set Global Variable的用法) 注意:如果直接在suite里定义变量,变量在suite里的用例里只能应用,修改的效果 ...
- mac下Android开发环境的配置
近似一天的时间,终于把Android环境配置好了. 总结:主要问题在于android的网站是国外,下载东西的时候需要vpn才可以.所以会出现各种各样的问题. 环境:Android Studio + S ...
- systemctl: command not found
可以使用service代替 service语法有一点区别 这里演示了错误语法和正确语法
- Nginx负载-nginx转发到Swoole服务器(nginx配置文件变更)
- eclipse集成maven插件
一.准备工作 1. 安装jdk并配置:https://www.cnblogs.com/diandiangui/p/10002100.html 2. 已安装好 maven并配置:https://www. ...
- 程序守护服务 Supervisor
一.什么是Supervisor? Supervisor是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启.它是通过fork ...