瞎j8封装第二版之数据层的封装
看了以前写的代码,对就是下面这个
觉得以前写的代码好烂啊!!!,重新理了一下思路,写得更规范和简练,应该效率也会高很多,用了一下下午写的连接池(半废品。。。)
下面直接上代码,代码很好理解,就是用了简单的反射,注解的部分我都写了注释
package jdbc; import util.StringUtil; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.*; import java.util.ArrayList; import java.util.List; public class DataUtil { public static int excuteUpdate(String sql, Object... objects) { Connection connection = ConnectionPool.getInstance().getCurrentConnection(); PreparedStatement preparedStatement = null; try { preparedStatement = getStateMent(connection, sql, objects); return preparedStatement.executeUpdate(); //执行sql并返回结果 } catch (SQLException e) { e.printStackTrace(); } finally { if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } } return 0; } /** * 查询单挑记录 * * @param sql 查询语句 * @param clazz 返回对象的class * @param objects 需要的参数,必须跟sql占位符的位置一一对应 * @param <T> 泛型返回 * @return 返回单个对象 */ public static <T> T queryForObject(String sql, Class<T> clazz, Object... objects) { Connection connection = ConnectionPool.getInstance().getCurrentConnection(); PreparedStatement preparedStatement = null; ResultSet resultSet = null; T object = null; try { preparedStatement = getStateMent(connection, sql, objects); resultSet = getResultSet(preparedStatement); if (resultSet.next()) { object = invokeObject(resultSet, clazz); } } catch (SQLException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } finally { close(preparedStatement, resultSet); //记得关闭 } return object; } /** *查询多条记录 * * @param sql 查询语句 * @param clazz 返回对象的class * @param objects 需要的参数,必须跟sql占位符的位置一一对应 * @param <T> 泛型返回 * * @return list */ public static <T> List<T> queryForList(String sql, Class<T> clazz, Object... objects) { Connection connection = ConnectionPool.getInstance().getCurrentConnection(); PreparedStatement preparedStatement = null; ResultSet resultSet = null; List<T> list = new ArrayList<T>(); try { preparedStatement = getStateMent(connection, sql, objects); resultSet = getResultSet(preparedStatement); while (resultSet.next()) { list.add(invokeObject(resultSet, clazz)); } } catch (SQLException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } finally { close(preparedStatement, resultSet); } return list.size() > 0 ? list : null; } private static void close(PreparedStatement preparedStatement, ResultSet resultSet) { try { if (preparedStatement != null) { preparedStatement.close(); resultSet.close(); } } catch (SQLException e) { e.printStackTrace(); } } private static <T> T invokeObject(ResultSet resultSet, Class<T> clazz) throws IllegalAccessException, InstantiationException, SQLException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException { T object = clazz.newInstance(); ResultSetMetaData metaData = resultSet.getMetaData(); for (int i = 0, count = metaData.getColumnCount(); i < count; i++) { String columnName = metaData.getColumnName(i + 1); //数据库返回结果的列名 String fieldName = StringUtil.camelName(columnName); //去掉列名中的下划线“_”并转为驼峰命名 Field field = clazz.getDeclaredField(fieldName); //根据字段名获取field String methName = setMethodName(fieldName); //拼set方法名 Class type = field.getType(); //获取字段类型 Method setMethod = clazz.getDeclaredMethod(methName, field.getType()); Object value = resultSet.getObject(i + 1); //获取字段值 setMethod.invoke(object, type.cast(value)); //强转并且赋值 } return object; } private static PreparedStatement getStateMent(Connection connection, String sql, Object... objects) throws SQLException { if (connection == null) { return null; } PreparedStatement preparedStatement = connection.prepareStatement(sql); for (int i = 0, len = objects.length; i < len; i++) { preparedStatement.setObject(i + 1, objects[i]); //给sql每个?占位符填上数据 } return preparedStatement; } private static ResultSet getResultSet(PreparedStatement statement) throws SQLException { if (statement == null) { return null; } else { return statement.executeQuery(); } } private static String setMethodName(String str) { return "set" + StringUtil.firstUpperCase(str); } }
用到了几个简单的字符串处理方法
package util; public class StringUtil { /** * 转为驼峰命名 * @param str * @return string */ public static String camelName(String str) { if (!isEmpty(str)) { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0, len = str.length(); i < len; i++) { if (str.charAt(i) == '_') { while (str.charAt(i + 1) == '_') { i++; } stringBuilder.append(("" + str.charAt(++i)).toUpperCase()); } else { stringBuilder.append(str.charAt(i)); } } return stringBuilder.toString(); } return str; } /** * 判断是否为空串 * * @param str * @return */ public static boolean isBlank(String str) { if (str != null && str.length() > 0) { for (int i = 0, len = str.length(); i < len; i++) { if (!Character.isSpaceChar(str.charAt(i))) { return false; } } } return true; } /** * 判断是否为空串 ?!!! 我怎么又写了个一样的方法?!!! * @param str * @return */ public static boolean isEmpty(String str) { return str == null || str.length() == 0; } /** * 将第一个字母替换为大写 * @param str * @return */ public static String firstUpperCase(String str) { return str.substring(0, 1).toUpperCase() + str.substring(1, str.length()); } }
下面开始是测试了
首先数据库
然后测试类,跟表结构对应的
package po; import java.util.Date; public class User { private Integer id; private Integer age; private String name; private Double score; private Date createTime; private Date updateTime; //set、get 方法均省略了,但是这个是必须的 }
测试代码
import java.util.List; public class Test { public static void main(String[] args) { String sql = "select * from t_user"; List<User> list = DataUtil.queryForList(sql,User.class); System.out.println("查询多条记录:" + list); System.out.println("******************************************************************"); sql = "select * from t_user where id = ?"; User user = DataUtil.queryForObject(sql,User.class,1); System.out.println("查询单条记录:" + user); System.out.println("******************************************************************"); sql = "insert into t_user(name,score,create_time,update_time) values(?,?,now(),now())"; int t = DataUtil.excuteUpdate(sql,"大牛",66.66); System.out.println("执行插入操作结果:"+t); } }
测试结果
太晚了,先到这了,有空把我的mybatis和ioc容器也瞎j8重写一下
转载请注明出处:
大王让我写代码 00:12:24
瞎j8封装第二版之数据层的封装的更多相关文章
- angular开发中对请求数据层的封装
代码地址如下:http://www.demodashi.com/demo/11481.html 一.本章节仅仅是对angular4项目开发中数据请求封装到model中 仅仅是在项目angular4项目 ...
- JDBC连接数据库方法的封装,以及查询数据方法的封装
(在上一篇文章中,我们详细的介绍了连接数据库的方法,以及eclipse操作数据库信息的相关方法,在这里我们将主要讲封装.) 主要内容: 一般的连接数据库测试 把连接数据库的方法封装成一个类和测试 一个 ...
- 瞎j8封装第二版之用xml文件来代理dao接口
也是重新整理了之前的那篇 模仿Mybatis用map per.xml实现Dao层接口的功能 话不多说直接上代码 首先是结构 依赖pom.xml <?xml version="1.0&q ...
- 瞎j8封装第二版之数据库连接池
写得很蛋疼,本来想支持多线程的,奈何对多线程和连接池理解着实太菜: 所以,起码是能拿到连接了... 但是还是不太懂这个连接池 我也是半抄别人的,以后再搞一搞这个吧. 先是配置文件 理想是很丰满的,奈何 ...
- python数据分析第二版:数据加载,存储和格式
一:读取数据的函数 1.读取csv文件 import numpy as np import pandas as pd data = pd.read_csv("C:\\Users\\Admin ...
- 计算器-- 利用re模块 利用函数封装 第二版
import re remove_parentheses = re.compile('\([^()]+\)') def Remove_Parentheses(obj, s): # 找到内层的括号并且返 ...
- 【类库】私房干货.Net数据层方法的封装
[类库]私房干货.Net数据层方法的封装 作者:白宁超 时间:2016年3月5日22:51:47 摘要:继上篇<Oracle手边常用70则脚本知识汇总>文章的发表,引起很多朋友关注.便促使 ...
- 手把手封装数据层之DButil数据库连接的封装
最近这段时间一直在用SSM框架做增删改查,突然想把以前还不会用框架的时候,综合百度和各种资料结合API文档抄袭而来的数据层的封装分享给大家.这边先封装一个DButil. 我这个封装就是烂大街的那种,没 ...
- 一只菜鸟的瞎J8封装系列的目录
因为这是一个系列...也就是我们所说的依赖关系.后面很多方法都是基于我前面封装的工具来进行的,所以我列一个目录供大家参考... 一只菜鸟的瞎J8封装系列 一.手把手封装数据层之DButil数据库连接 ...
随机推荐
- LayoutInflater 三种获得方式
LayoutInflater 作用是从外部加载一个xml布局文件. 获得 LayoutInflater 实例的三种方式: 1.LayoutInflater inflater = getLayoutIn ...
- 《Linux命令行与shell脚本编程大全》第十九章 初识sed和gawk
这两个工具能够极大简化需要进行的数据处理任务. 19.1 文本处理 能轻松实现自动格式化.插入.修改或删除文本元素的简单命令行编辑. sed和gawk就具备上述功能 19.1.1 sed编辑器 被称为 ...
- [C#]使用Gembox.SpreadSheet向Excel写入数据及图表
本文为原创文章.源代码为原创代码,如转载/复制,请在网页/代码处明显位置标明原文名称.作者及网址,谢谢! 开发工具:VS2017 语言:C# DotNet版本:.Net FrameWork 4.0及以 ...
- C++杂分析
class word{ public: word(){cout<<"word constructure \n";} word(int i){cout<<&q ...
- TCP/IP 协议栈 ------ ICMP
I C M P经常被认为是 I P层的一个组成部分.它传递差错报文以及其他需要注意的信息.I C M P报文通常被I P层或更高层协议( T C P或U D P)使用.一些I C M P报文把差错报文 ...
- PHP生成xml 无法识别或是无法读取或是浏览器不识别等问题
PHP 数组转XML函数如下 [PHP] 纯文本查看 复制代码 ? 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 ...
- javascript设计模式——组合模式
前面的话 在程序设计中,有一些和“事物是由相似的子事物构成”类似的思想.组合模式就是用小的子对象来构建更大的对象,而这些小的子对象本身也许是由更小的“孙对象”构成的.本文将详细介绍组合模式 宏命令 宏 ...
- Hibernate框架进阶(中篇)之多表关系
导读 Hibernate进阶主要分为上中下三篇,本文是中篇,主要讲解Hibernate框架中多表关系的实现.我们知道多表关系有一对一.一对多(多对一)和多对多三种关系.而1对1关系一般合并为一个表处理 ...
- VantPy自动化测试框架
1.必须要谈的一点,就是我们学习自动测试不是用来炫耀的,而是用来提升自身能力的. 2.这个框架不是通用框架,只是在这里灌输这个框架的思想,让每个人写框架都易如反掌 3.如果没有python基础的同学, ...
- Jarvis OJ- [XMAN]level2/3_x64-Writeup——64位简单栈溢出
两道64位栈溢出,思路和之前的32位溢出基本一致,所以放在一起 在这两道中体现的32位和64位的主要区别在于函数参数传递的方式 在32位程序运行中,函数参数直接压入栈中 调用函数时栈的结构为:调用函数 ...