热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:java对jdbc操作结果简单的映射封装

篇首语:本文由编程笔记#小编为大家整理,主要介绍了java对jdbc操作结果简单的映射封装相关的知识,希望对你有一定的参考价值。 1. 对jdbc做一个简单的封装,select可以返回一个javabe

篇首语:本文由编程笔记#小编为大家整理,主要介绍了java对jdbc操作结果简单的映射封装相关的知识,希望对你有一定的参考价值。



1. 对jdbc做一个简单的封装,select可以返回一个javabean对象,而不是resultset。主要用了反射。这是我之前写的代码,做了简单的修改。

  实现功能:a.对数据库的基本操作 增删改查

       b.对查询的单条记录返回一个指定类型的javabean对象,利用java反射,jdbc ResultSet类和ResultSetMetaData类

       c. 对查到的结果集返回一个List, 泛型

  数据源:用到的 数据库连接池是我自己简单实现的一个连接池:【java】简单实现数据库连接池,主要为了后续实现事务的简单实现

  用到的java知识 : 反射,泛型,jdbc

        



import
com.yeyeck.noob.ConnectionPollImpl;
import com.yeyeck.noob.IConnectionPool;
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 DBUtil {
public static int excuteUpdate(String sql, Object... objects) {
IConnectionPool connectionPool
= ConnectionPollImpl.getInstance();
Connection connection
= connectionPool.getConnection();
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 泛型返回
*
@return 返回单个对象
*/
public static T queryForObject(String sql, Class clazz, Object... objects) {
IConnectionPool connectionPool
= ConnectionPollImpl.getInstance();
Connection connection
= connectionPool.getConnection();
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 | IllegalAccessException | InstantiationException
| NoSuchFieldException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
}
finally {
close(preparedStatement, resultSet);
//记得关闭
}
return object;
}
/**
*查询多条记录
*
*
@param sql 查询语句
*
@param clazz 返回对象的class
*
@param objects 需要的参数,必须跟sql占位符的位置一一对应
*
@param 泛型返回
*
*
@return list
*/
public static List queryForList(String sql, Class clazz, Object... objects) {
IConnectionPool connectionPool
= ConnectionPollImpl.getInstance();
Connection connection
= connectionPool.getConnection();
PreparedStatement preparedStatement
= null;
ResultSet resultSet
= null;
List
list = new ArrayList<>();
try {
preparedStatement
= getStateMent(connection, sql, objects);
resultSet
= getResultSet(preparedStatement);
while (resultSet.next()) {
//调用 invokeObject方法,把一条记录封装成一个对象,添加到list中
list.add(invokeObject(resultSet, clazz));
}
}
catch (SQLException | IllegalAccessException | InstantiationException
| NoSuchFieldException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
}
finally {
close(preparedStatement, resultSet);
}
return list.size() > 0 ? list : null;
}
private static void close(PreparedStatement preparedStatement, ResultSet resultSet) {
try {
if(resultSet != null) {
resultSet.close();
}
if (preparedStatement != null) {
preparedStatement.close();
}
}
catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 把数据库中的一条记录通过反射包装成相应的Bean
*
@param resultSet
*
@param clazz
*
@param
*
@return
*
@throws IllegalAccessException
*
@throws InstantiationException
*
@throws SQLException
*
@throws NoSuchFieldException
*
@throws NoSuchMethodException
*
@throws InvocationTargetException
*/
private static T invokeObject(ResultSet resultSet, Class clazz) throws IllegalAccessException, InstantiationException,
SQLException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
T object
= clazz.getDeclaredConstructor().newInstance();
ResultSetMetaData metaData
= resultSet.getMetaData();
for (int i = 0, count = metaData.getColumnCount(); 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 {
PreparedStatement preparedStatement
= connection.prepareStatement(sql);
for (int i = 0, len = objects.length; 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);
}
}

其中用到的StringUtil的几个方法


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 ) {
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 ) {
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());
}
}

测试

1.测试用到的表


CREATE TABLE `t_user` (
`id`
int(11) NOT NULL AUTO_INCREMENT,
`username`
varchar(50) DEFAULT NULL,
`age`
int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE
=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 |

初始数据

测试代码


import java.util.List;
public class DBUtilTest {
public static void main(String[] args) {
List
users1 = DBUtil.queryForList("select * from t_user", User.class);
System.out.println(users1);
User user
= new User();
user.setUsername(
"刘能");
user.setAge(
12);
String sql1
= "insert into `t_user`(username, age) values (?, ?)";
System.out.println(
"insert 语句测试返回结果:" + DBUtil.excuteUpdate(sql1, user.getUsername(), user.getAge()));
List
users2 = DBUtil.queryForList("select * from t_user", User.class);
System.out.println(users2);
String sql2
= "delete from t_user where id = ?";
System.out.println(
"delete 语句测试返回结果:" + DBUtil.excuteUpdate(sql2, 3));
String sql3
= "update t_user set age = ? where id = ?";
System.out.println(
"update 语句测试返回结果:" + DBUtil.excuteUpdate(sql3, 100, 1));
String sql4
= "select * from t_user where id = ?";
User user2
= DBUtil.queryForObject(sql4, User.class, 2);
System.out.println(
"select 语句测试返回结果: " + user2 );
List
users3 = DBUtil.queryForList("select * from t_user", User.class);
System.out.println(users3);
}
}

测试结果


[User{id=1, username=\'小明\', age=100}, User{id=2, username=\'小红\', age=15}, User{id=4, username=\'小二\', age=12}, User{id=5, username=\'刘能\', age=12}]
insert 语句测试返回结果:
1
[User{
id=1, username=\'小明\', age=100}, User{id=2, username=\'小红\', age=15}, User{id=4, username=\'小二\', age=12}, User{id=5, username=\'刘能\', age=12}, User{id=6, username=\'二蛋\', age=99}]
delete 语句测试返回结果:
1
update 语句测试返回结果:
1
select 语句测试返回结果: User{id=2, username=\'小红\', age=15}
[User{
id=1, username=\'小明\', age=20}, User{id=2, username=\'小红\', age=15}, User{id=4, username=\'小二\', age=12}, User{id=6, username=\'二蛋\', age=99}]

数据库数据

 



推荐阅读
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
author-avatar
aofeng12_313
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有