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. Bootstrap常用表单布局

    参考链接: https://blog.csdn.net/shuai_wy/article/details/78978023

  2. ddt源码修改:HtmlTestRunner报告依据接口名显示用例名字

    背景是这样的: 自己写了一套接口自动化的框架,其中使用unittest + ddt + excel作为数据驱动模式的应用,使用HtmlTetstRunner来生成测试用例. 一切看起来很完美. 但是, ...

  3. HDU - 1035

    wa了一遍,炸了两遍 (1)迷宫题中的模拟题.只需要简单代码就可以ac.如果程序有问题,最后就会卡死,出现runtime error. (2)边界问题一定要小心,数组是从0开始的,就要考虑r--会不会 ...

  4. Beta 冲刺(5/7)

    目录 摘要 团队部分 个人部分 摘要 队名:小白吃 组长博客:hjj 作业博客:beta冲刺(5/7) 团队部分 后敬甲(组长) 过去两天完成了哪些任务 ppt制作中 数据集标注 接下来的计划 制作p ...

  5. 《利用Python进行数据分析·第2版》

    <利用Python进行数据分析·第2版> 第 1 章 准备工作第 2 章 Python 语法基础,IPython 和 Jupyter第 3 章 Python 的数据结构.函数和文件第 4 ...

  6. JAVA Scanner的简单运用

    package Code428; import java.util.Scanner; /*Scanner 可以实现键盘输入数据 引用的步骤1.import 包路径.类名称只有java.lang包下的内 ...

  7. web---资源的下载及中文乱码问题

    1.html网页,超链接交由Servlet处理 <!DOCTYPE html> <html lang="en"> <head> <meta ...

  8. 2-2、安装Filebeat

    安装filebeat 第1步:安装Filebeat 开始之前:如果尚未安装Elastic Stack,请立即执行此操作. 请参阅Getting started with the Elastic Sta ...

  9. JSON字符串自动转换

    package com.zkn.newlearn.json; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObj ...

  10. Docker 学习4 Docker容器虚拟化网络概述

    一.docker 虚拟化网络概述 1.OVS: OpenVSwitch,不仅能模拟二层网络,还能模拟三层网络,或者VLAN,VXLAN,流控 SDN软件定义网络技术等. 2.overlay netwo ...