SpringJDBC之RowMapper通用类
SpringJDBC无疑极大的方便了我们访问数据库,但是有一个小问题,每次查询操作返回的实体对象不一样,难道我们每次都要重新实现RowMapper吗?利用泛型,可以方便处理这样的操作。
开发环境:Windows10、eclipse、SpringJDBC4.3.7。文末含项目源码下载链接。
1、自我实现RowMapper
- /*
- * 文件名:LocalRowMapper.java
- * 版权:Copyright 2007-2017 517na Tech. Co. Ltd. All Rights Reserved.
- * 描述: LocalRowMapper.java
- * 修改人:xiaofan
- * 修改时间:2017年3月19日
- * 修改内容:新增
- */
- package com.zxiaofan.dubboProvidder.rowMapper;
- import java.lang.reflect.Field;
- import java.math.BigDecimal;
- import java.sql.ResultSet;
- import java.sql.ResultSetMetaData;
- import java.sql.SQLException;
- import java.sql.Timestamp;
- import java.util.Date;
- import java.util.HashMap;
- import org.springframework.jdbc.core.RowMapper;
- /**
- *
- * @author xiaofan
- */
- public class LocalRowMapper<T> implements RowMapper<T> {
- /**
- * 添加字段注释.
- */
- private Class<?> targetClazz;
- /**
- * 添加字段注释.
- */
- private HashMap<String, Field> fieldMap;
- /**
- * 构造函数.
- *
- * @param targetClazz
- * .
- */
- public LocalRowMapper(Class<?> targetClazz) {
- this.targetClazz = targetClazz;
- fieldMap = new HashMap<>();
- Field[] fields = targetClazz.getDeclaredFields();
- for (Field field : fields) {
- // 同时存入大小写,如果表中列名区分大小写且有列ID和列iD,则会出现异常。
- // 阿里开发公约,建议表名、字段名必须使用小写字母或数字;禁止出现数字开头,禁止两个下划线中间只出现数字。
- fieldMap.put(field.getName(), field);
- // fieldMap.put(getFieldNameUpper(field.getName()), field);
- }
- }
- /**
- * {@inheritDoc}.
- */
- @Override
- public T mapRow(ResultSet rs, int arg1) throws SQLException {
- T obj = null;
- try {
- obj = (T) targetClazz.newInstance();
- final ResultSetMetaData metaData = rs.getMetaData();
- int columnLength = metaData.getColumnCount();
- String columnName = null;
- for (int i = 1; i <= columnLength; i++) {
- columnName = metaData.getColumnName(i);
- Class fieldClazz = fieldMap.get(columnName).getType();
- Field field = fieldMap.get(columnName);
- field.setAccessible(true);
- // fieldClazz == Character.class || fieldClazz == char.class
- if (fieldClazz == int.class || fieldClazz == Integer.class) { // int
- field.set(obj, rs.getInt(columnName));
- } else if (fieldClazz == boolean.class || fieldClazz == Boolean.class) { // boolean
- field.set(obj, rs.getBoolean(columnName));
- } else if (fieldClazz == String.class) { // string
- field.set(obj, rs.getString(columnName));
- } else if (fieldClazz == float.class) { // float
- field.set(obj, rs.getFloat(columnName));
- } else if (fieldClazz == double.class || fieldClazz == Double.class) { // double
- field.set(obj, rs.getDouble(columnName));
- } else if (fieldClazz == BigDecimal.class) { // bigdecimal
- field.set(obj, rs.getBigDecimal(columnName));
- } else if (fieldClazz == short.class || fieldClazz == Short.class) { // short
- field.set(obj, rs.getShort(columnName));
- } else if (fieldClazz == Date.class) { // date
- field.set(obj, rs.getDate(columnName));
- } else if (fieldClazz == Timestamp.class) { // timestamp
- field.set(obj, rs.getTimestamp(columnName));
- } else if (fieldClazz == Long.class || fieldClazz == long.class) { // long
- field.set(obj, rs.getLong(columnName));
- }
- field.setAccessible(false);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return obj;
- }
- /**
- * 方法首字母大写.
- *
- * @param fieldName
- * 字段名.
- * @return 字段名首字母大写.
- */
- private String getFieldNameUpper(String fieldName) {
- char[] cs = fieldName.toCharArray();
- cs[0] -= 32; // 方法首字母大写
- return String.valueOf(cs);
- }
- }
定义一个LocalRowMapper<T> 类,implements RowMapper<T>,在这里需要注意fieldMap缓存字段名,由于不同的人表字段命名规则不一样,有的习惯于首字母小写,有的习惯于首字母大写。这里以阿里巴巴开发公约为准(【强制】表名、字段名必须使用小写字母或数字;禁止出现数字开头,禁止两个下划线中间只出现数字。数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑。)。如果你的表字段是大写开头,请注释掉fieldMap.put(field.getName(), field);同时放开fieldMap.put(getFieldNameUpper(field.getName()), field);这行的注释。
2、相关数据库表设计
- #建库字符编码为utf8的库studydb
- CREATE DATABASE IF NOT EXISTS StudyDB DEFAULT CHARACTER SET utf8;
- #建表user
- CREATE TABLE
- IF NOT EXISTS USER (
- id INT (10) NOT NULL auto_increment,
- userName VARCHAR (20) NOT NULL,
- age INT (4),
- addTime DATETIME,
- modifyTime TIMESTAMP,
- isDelete INT(4),
- PRIMARY KEY (id)
- ) ENGINE = INNODB DEFAULT CHARSET = utf8;
3、定义model
- package com.zxiaofan.dubboProvidder.model;
- import java.util.Date;
- /**
- * 用户表.
- *
- * @author xiaofan
- */
- public class UserDo {
- private String tableName;
- private Integer id;
- private String userName;
- private Integer age;
- private Date addTime;
- private Date modifyTime;
- private int isDelete;
- // get/set方法略
- @Override
- public String toString() {
- return "UserDo [tableName=" + tableName + ", id=" + id + ", userName=" + userName + ", age=" + age + ", addTime=" + addTime + ", modifyTime=" + modifyTime + ", isDelete=" + isDelete + "]";
- }
- }
此处加入了数据库没有的字段tableName,方便数据库操作时传入表名,同时重写了toString()方法,便于返回值查看。
3、数据库相关配置及注入jdbcTemplate
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
- http://code.alibabatech.com/schema/dubbo
- http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
- <!-- oracle.jdbc.driver.OracleDriver -->
- <bean id="dataSource"
- class="org.springframework.jdbc.datasource.DriverManagerDataSource">
- <property name="driverClassName" value="${jdbc.driver}">
- </property>
- <property name="url" value="${jdbc.url}">
- </property>
- <property name="username" value="${jdbc.username}"></property>
- <property name="password" value="${jdbc.password}"></property>
- </bean>
- <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
- abstract="false" lazy-init="false" autowire="default">
- <property name="dataSource">
- <ref bean="dataSource" />
- </property>
- </bean>
- </beans>
4、具体使用
- package com.zxiaofan.dubboProvidder.business.impl;
- import java.util.List;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.jdbc.core.JdbcTemplate;
- import org.springframework.stereotype.Component;
- import com.zxiaofan.dubboProvidder.business.IUserBusiness;
- import com.zxiaofan.dubboProvidder.model.UserDo;
- import com.zxiaofan.dubboProvidder.rowMapper.LocalRowMapper;
- /**
- *
- * @author xiaofan
- */
- @Component
- public class UserBusinessImpl implements IUserBusiness {
- @Autowired
- private JdbcTemplate jdbcTemplate;
- /**
- * {@inheritDoc}.
- */
- @Override
- public int insert(UserDo userDo) {
- String sqlStr = "insert into " + userDo.getTableName() + " (userName,age,addTime,isDelete) values(?,?,?,?)";
- int result = jdbcTemplate.update(sqlStr, userDo.getUserName(), userDo.getAge(), userDo.getAddTime(), userDo.getIsDelete());
- return result;
- }
- /**
- * {@inheritDoc}.
- */
- @Override
- public UserDo selectByID(UserDo userDo) {
- String sqlStr = "select * from " + userDo.getTableName() + " where id=?";
- List<UserDo> dos = jdbcTemplate.query(sqlStr, new LocalRowMapper(UserDo.class), userDo.getId());
- if (null != dos && !dos.isEmpty()) {
- return dos.get(0);
- }
- return null;
- }
- /**
- * {@inheritDoc}.
- */
- @Override
- public int update(UserDo userDo) {
- String sqlStr = "update " + userDo.getTableName() + " set userName=? where id=?";
- int result = jdbcTemplate.update(sqlStr, userDo.getUserName(), userDo.getId());
- return result;
- }
- /**
- * {@inheritDoc}.
- */
- @Override
- public int delete(UserDo userDo) {
- String sqlStr = "delete from " + userDo.getTableName() + " where userName=?";
- int result = jdbcTemplate.update(sqlStr, userDo.getUserName());
- return result;
- }
- }
注意 UserDo selectByID(UserDo userDo) 方法,jdbcTemplate.query(sqlStr, new LocalRowMapper(UserDo.class), userDo.getId());入参为sql、重写的LocalRowMapper、实际参数id,这里我们传入了返回实体对象UserDo的的类类型UserDo.class。待数据返回后将自动映射成我们的model。
下图是测试暴露的HTTP服务,详见另一篇博文《dubbo使用教程,可直接应用于企业开发》
源码地址:https://github.com/zxiaofan/OpenSource_Study/tree/master/dubbo/DubboProvider,以上代码来源于个人学习项目dubbo,项目OpenSource_Study下包含了本人各类开源软件、框架学习的相关demo,包含Apache、Thrift、Guava、quartz等项目,持续学习ing。
- 欢迎个人转载,但须在文章页面明显位置给出原文连接;
- 未经作者同意必须保留此段声明、不得随意修改原文、不得用于商业用途,否则保留追究法律责任的权利。
- 【 CSDN 】:csdn.zxiaofan.com
- 【GitHub】:github.zxiaofan.com
- 如有任何问题,欢迎留言。祝君好运!
- Life is all about choices!
- 将来的你一定会感激现在拼命的自己!
SpringJDBC之RowMapper通用类相关推荐
- 一劳永逸,iOS 网页视图控制器通用类封装
原文链接:http://www.jianshu.com/p/553424763585 随着 H5 的发展,在 iOS 开发中,网页视图的使用率逐渐提升,为了增加代码封装度.减轻开发负担,因此通常会对网 ...
- C#检测电脑的一些设置通用类(经典推荐)
此类能检测出电脑的cpu序列号,获取网卡硬件地址,获取IP地址,获取硬盘ID,操作系统的登录用户名,PC类型,物理内存,就这些了,够用吧,谁在有能获取电脑别的信息的类,跟贴啊,欢迎大家分享,打造一个超 ...
- DataTable转ListModel通用类
/// <summary> /// DataTable转List<Model>通用类[实体转换辅助类] /// </summary> public class Mo ...
- C#.NET操作数据库通用类(MS SQL Server篇)
下面给出了一个C#操作MS SQL Server 数据库的通用类,通过该类可以对数据库进行任何操作,包括执行SQL语句.执行存储过程.以下是其详细实现过程,希望大家共同修改优化之.稍后将介绍如何使用它 ...
- C#.NET操作数据库通用类
下面给出了一个C#操作MS SQL Server 数据库的通用类,通过该类可以对数据库进行任何操作,包括执行SQL语句.执行存储过程.以下是其详细实现过程,希望大家共同修改优化之.稍后将介绍如何使用它 ...
- 《WebForm开发系列高级篇》Item2导出EXCEL通用类(GridView,DataList,Repeater,DetailView)
1.导出效果图: 2.C#导出EXCEL通用类源代码: using System; using System.Data; using System.Configuration; using Syste ...
- Memcached通用类(基于enyim.com Memcached Client)
一.如果用官方提供的方法,在web.config里面配置好了各个参数和服务器IP.如下图: <?xml version="1.0"?> <configuratio ...
- C#:导入Excel通用类(CSV格式)
一.引用插件LumenWorks.Framework.IO.dll(CsvReader) 插件下载地址:https://pan.baidu.com/s/1X9Sl4bWTNHJOJb_v-KUndA ...
- 泛型类java_Java泛型 - 通用类( Generic Classes)
Java泛型 - 通用类( Generic Classes) 泛型类声明看起来像非泛型类声明,除了类名后跟一个类型参数部分. 泛型类的类型参数部分可以有一个或多个用逗号分隔的类型参数. 这些类称为参数 ...
最新文章
- Open3D 三维点云读取可视化、下采样、去除离群点、地面提取
- Ruby用SciTE输出中文报错问题解决
- windows 驱动和应用层的三种通信方式 r3到r0 DeviceIoControl 4种ioctl请求
- 皮一皮:前女友竟然说这种话...
- 设计模式六:适配器模式
- 【牛客 - 157D】插排树(dfs,树形dp)
- pandas用众数填充缺失值_python数据分析包|Pandas-02之缺失值(NA)处理
- mysql 语句 not_mysql sql语句 is not 用法是
- 数据库优化的几种方法
- Code[VS]1997 守卫者的挑战
- Qt 窗口置顶 | 和取消置顶
- vos3000下载java_昆石VOS3000_2.1.4.0完整安装包及安装脚本
- java batik_使用BATIK解析SVG生成PNG图片
- Python+KinectV2——PyKinect
- flask 将route放置在多个文件中的方法(蓝本)
- java视频教程,Java面试资料
- MySQL查询,关于日期和时间戳,查询时间的记录
- matlab 动态识别,基于matlab脸部动态特征的人脸表情识别程序
- LaTex常用公式和字母
- ssm中报错: Error resolving class. Cause: org.apache.ibatis.type.TypeException: Could not resolve type a