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实体映射的更多相关文章

  1. 8.2 使用Fluent API进行实体映射【Code-First系列】

    现在,我们来学习怎么使用Fluent API来配置实体. 一.配置默认的数据表Schema Student实体 using System; using System.Collections.Gener ...

  2. 开源实体映射框架EmitMapper介绍

    开源实体映射框架EmitMapper介绍   综述       EmitMapper是一个开源实体映射框架,地址:http://emitmapper.codeplex.com/.       Emit ...

  3. EntityFramework 实体映射到数据库

    EntityFramework实体映射到数据库 在Entity Framework Code First与数据表之间的映射方式实现: 1.Fluent API映射 通过重写DbContext上的OnM ...

  4. EF Code First:实体映射,数据迁移,重构(1)

    一.前言 经过EF的<第一篇>,我们已经把数据访问层基本搭建起来了,但并没有涉及实体关系.实体关系对于一个数据库系统来说至关重要,而且EF的各个实体之间的联系,实体之间的协作,联合查询等也 ...

  5. EF Code First:实体映射

    二.实体映射 实体与数据库的映射可以通过DataAnnotation与FluentAPI两种方式来进行映射: (一) DataAnnotation DataAnnotation 特性由.NET 3.5 ...

  6. 10.1.翻译系列:EF 6中的实体映射【EF 6 Code-First系列】

    原文链接:https://www.entityframeworktutorial.net/code-first/configure-entity-mappings-using-fluent-api.a ...

  7. 【译】第23节---Fluent API - 实体映射

    原文:http://www.entityframeworktutorial.net/code-first/configure-entity-mappings-using-fluent-api.aspx ...

  8. 关于AutoMApping 实体映射

    安装AutoMapping包 把订单实体映射成订单DTO实体 .ReverseMap()加上这个方法后 下面自定义 映射规则  第一个就是来源对象 第二个就是目标对象 https://www.cnbl ...

  9. abp 修改abp.zero的实体映射类,使生成的表和字段为大写状态

    在我们项目中,由于涉及到报表配置管理,可以通过一段sql快捷的配置出一个报表页面.部分sql会与abp框架的一些系统表做关联查询,而abp的映射类没有单独设置表和字段的名称,默认用类名和属性名,区分大 ...

随机推荐

  1. L2-005 集合相似度 (25 分) (STL——set)

    链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805070149828608 题目: 给定两个整数集合,它们的相似度 ...

  2. Spring框架中的org.springframework.context.annotation.Import注解类

    @Import注解的作用和在使用spring的xml配置时用到的<import/>类似.但应注意是@Import在使用时必须要保证能被IOC容器扫描到,所以通常它会和@Configurat ...

  3. Win 10 系统下研华采集卡Advantech Navi SDK虚拟demo设备安装方法

    研华的DAQNavi是其采集卡设备的.net编程SDK,安装了其通讯工具Navigator后,可以添加虚拟采集卡 demo device. 在Win10上,执行添加操作时,可能会出现添加失败,这是由于 ...

  4. 爬虫 http原理,梨视频,github登陆实例,requests请求参数小总结

    回顾:http协议基于请求响应的方式,请求:请求首行 请求头{'keys':vales} 请求体 :响应:响应首行,响应头{'keys':'vales'},响应体. import socket soc ...

  5. Linux性能调优之gprof和oprofile

    为了更好的优化程序性能,我们必须找到性能瓶颈点,“好钢用在刀刃上”才能取 得好的效果,否则可能白做工作. 为了找到关键路径,我们可以使用profilng技术,在linux平台上,我们可以使用gprof ...

  6. php 过滤表单提交

    list($addressId,$couponId,$payType,$useIntegral,$mark,$combinationId,$pinkId,$seckill_id,$formId,$ba ...

  7. 初学python之路-day08前期总结

    # 1# 计算机原理:控制器 运算器 存储器 input设备 output设备 IO流# 三大核心:CPU 内存 硬盘 # 内存分布:栈区 与 堆区# 如二进制与十进制的转换,如1111转成十进制为1 ...

  8. C# 高级编程02----手动创建C#程序

    在日常工作中使用C# 开发的时候,通常使用宇宙第一神器VS进行开发.为了了解编译过程,这里采用文本编辑器的方式编写一个C#程序 一.创建一个C#程序 1.使用记事本工具创建一个名为First.cs的文 ...

  9. log4j配置,输出sql到控制台

    网上的 # Global logging configuration log4j.rootLogger=ERROR, stdout # log4j.logger后面跟着的是项目dao包路径,里面全部都 ...

  10. SQL Server 创建索引

    索引的简介: 索引分为聚集索引和非聚集索引,数据库中的索引类似于一本书的目录,在一本书中通过目录可以快速找到你想要的信息,而不需要读完全书. 索引主要目的是提高了SQL Server系统的性能,加快数 ...