【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 <T>   泛型返回
     * @return      返回单个对象
     */
    public static <T> T queryForObject(String sql, Class<T> 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 <T>   泛型返回
     *
     * @return list
     */
    public static <T> List<T> queryForList(String sql, Class<T> clazz, Object... objects) {
        IConnectionPool connectionPool = ConnectionPollImpl.getInstance();
        Connection connection = connectionPool.getConnection();
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        List<T> 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 <T>
     * @return
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws SQLException
     * @throws NoSuchFieldException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    private static <T> T invokeObject(ResultSet resultSet, Class<T> 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 < 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 {

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

其中用到的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 < 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());
    }
}

测试

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<User> 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<User> 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<User> 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}]

数据库数据

原文地址:https://www.cnblogs.com/yeyeck/p/9532688.html

时间: 2024-08-03 17:09:50

【java】对jdbc操作结果简单的映射封装的相关文章

Java使用Jdbc操作MySql数据库(一)

这个示例是Java操作MySql的基本方法. 在这个示例之前,要安装好MySql,并且配置好账户密码,创建一个logininfo数据库,在数据库中创建userinfo数据表.并且在表中添加示例数据. 一.首先将mysql-connector-java-5.1.26-bin.jar开发包复制到lib文件夹中,并且Build Path->Add Build Path. 二.创建User类,用于封装从数据库读出来的数据. 1 package com.mylx.database; 2 3 public

java通过jdbc操作Excel

ExcelAccess.java package test; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; public class ExcelAccess { public static void main(String[] args) { List<DataTableColumns> ls = new ArrayList<DataTableColumns>

Java:JDBC操作

内容:供程序员调用的接口与类,集成在java.sql和javax.sql包中,如:DriverManager类Connection接口Statement接口ResultSet接口 1.Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); 2.Connection conn = DriverManager.getConnection("jdbc:sqlserver://127.0.0.1:1433;data

1、Java通过JDBC操作Hive

0.概述 使用的都是CLI或者hive –e的方式仅允许使用HiveQL执行查询.更新等操作.然而Hive也提供客户端的实现,通过HiveServer或者HiveServer2,客户端可以在不启动CLI的情况下对Hive中的数据进行操作,两者都允许远程客户端使用多种编程语言如Java.Python向Hive提交请求,取回结果. HiveServer与HiveServer2的异同? HiveServer和HiveServer2都是基于Thrift.既然已经存在HiveServer为什么还需要Hiv

Java之JDBC操作

下载jar包: mysql-connector-java-5.1.44.jar 导入包: import java.sql.*; 源码如下: 1 /** 2 * 使用JDBC底层实现查询 3 */ 4 public static void queryWithJDBC() { 5 Connection conn = null; 6 PreparedStatement psmt = null; 7 ResultSet rs = null; 8 String jdbcUrl = "jdbc:mysql:

MySQL数据库学习笔记(八)----JDBC入门及简单增删改查数据库的操作

[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4050825.html 联系方式:[email protected] [正文]                                                                                                               

【Java编程】建立一个简单的JDBC连接-Drivers, Connection, Statement and PreparedStatement

本blog提供了一个简单的通过JDBC驱动建立JDBC连接例程,并分别通过Statement和PreparedStatement实现对数据库的查询.在下一篇blog中将重点比较Statement与PreparedStatement的差异. 1.为项目添加JDBC驱动 1)JDBC驱动下载 官方下载地址:mysql-connector-java-5.0.8.zip CSDN资料下载地址:mysql-connector-java-5.0.8.zip 2)为项目添加JDBC驱动 建立项目Java项目J

Java使用jdbc连接Sqlite数据库进行各种数据操作的详细过程

前言:      SQLite是遵守ACID 的关系型数据库管理系统,它包含在一个相对小的C库中.它是D.RichardHipp建立的公有领域项目.       不像常见的客户-服务器范例,SQLite引擎不是个程序与之通信的独立进程,而是连接到程序中成为它的一个主要部分.所以主要的通信协议是在编程语言内的直接API调用.这在消耗总量.延迟时间和整体简单性上有积极的作用.整个数据库(定义.表.索引和数据本身)都在宿主主机上存储在一个单一的文件中.它的简单的设计是通过在开始一个事务的时候锁定整个数

Java连接MySQL数据库及简单操作代码

1.Java连接MySQL数据库 Java连接MySql需要下载JDBC驱动MySQL-connector-java-5.0.5.zip(举例,现有新版本).然后将其解压缩到任一目录.我是解压到D盘,然后将其目录下的MySQL-connector-java-5.0.5-bin.jar加到classpath里,具体如下: "我的电脑"-> "属性" -> "高级" -> "环境变量",在系统变量那里编辑clas