自制DbUtils.jar

一、自制DbUtils

一成不变的生活,太让人难受了,于是我便动手编写了个属于自己的Dbutils 。尽管是有"重复造轮子"一说,可是这让我成长了,让我认识到我和大牛之间的差距。
为了区别其它DbUtils.jar,我用DbUtils的全称DatabaseUtilities来命名文件,即"DatabaseUtilities.jar"

在这里插入图片描述

二、运行展示

1.使用SqlRunner对象进行查询操作

1.1 代码

package com.ytt.test;

import com.liurui.growth.*;
import com.ytt.domain.User;
import org.junit.Test;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Properties;

public class SqlRunnerTest {
    @Test
    public void testQuery() throws ClassNotFoundException, IOException, SQLException {
        Properties properties = new Properties();
        properties.load(ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties"));
        String driver = properties.getProperty("driver");
        String url = properties.getProperty("url");
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");
        Class.forName(driver);
        Connection connection = DriverManager.getConnection(url, username, password);
        //------------------------------------------------------------------------------------
        SqlRunner sqlRunner = new SqlRunner(connection);
        List<User> userList = sqlRunner.query("select * from user where name like ?",
                new BeanListHandler<User>(User.class), "%a%");

        User user = sqlRunner.query("select * from user where id=?",
                new BeanHandler<User>(User.class), 2);

        Map<String, Object> map = sqlRunner.query("select * from user where id=?",
                new MapHandler<User>(User.class), 30);

        List<Map<String, Object>> mapList = sqlRunner.query("select * from user where birthdate in(?,?)",
                new MapListHandler<User>(User.class), "1993-10-03","2000-10-10");
        //------------------------------------------------------------------------------------



        System.out.println("userList\r\n"+userList);
        System.out.println("user\r\n"+user);
        System.out.println("map\r\n"+map);
        System.out.println("mapList");
        for (Map<String, Object> stringObjectMap : mapList) {
            System.out.println(stringObjectMap);
        }
    }
}


1.2 运行结果

在这里插入图片描述

2. 使用SqlRunner对象进行删除操作

2.1 操作代码

package com.ytt.test;

import com.liurui.growth.*;
import com.ytt.domain.User;
import org.junit.Test;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.Properties;

public class SqlRunnerTest {
    @Test
    public void testQuery() throws ClassNotFoundException, IOException, SQLException {
        Properties properties = new Properties();
        properties.load(ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties"));
        String driver = properties.getProperty("driver");
        String url = properties.getProperty("url");
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");
        Class.forName(driver);
        Connection connection = DriverManager.getConnection(url, username, password);
        connection.setAutoCommit(false);//不自动提交事务,不作真正的删除操作
        //为了明显地看出删除的效果,这里查询两次
        //------------------------------------------------------------------------------------
        SqlRunner sqlRunner = new SqlRunner(connection);
        List<User> userList = sqlRunner.query("select * from user", new BeanListHandler<User>(User.class));
        System.out.println("userList\r\n" + userList);

        Integer row = sqlRunner.delete("delete from user where id in(?,?,?)", 25,26,27);
        System.out.println("删除id为25,26,27的记录");
        System.out.println("rows affected:\t" + row);

        userList = sqlRunner.query("select * from user", new BeanListHandler<User>(User.class));
        System.out.println("userList\r\n" + userList);

        //------------------------------------------------------------------------------------

    }
}

2.2 运行结果

在这里插入图片描述

3. 使用SqlRunner对象进行插入,批量插入操作

3.1 操作代码

package com.ytt.test;

import com.liurui.growth.*;
import com.ytt.domain.User;
import org.junit.Test;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.Properties;

public class SqlRunnerTest {
    @Test
    public void testQuery() throws ClassNotFoundException, IOException, SQLException {
        Properties properties = new Properties();
        properties.load(ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties"));
        String driver = properties.getProperty("driver");
        String url = properties.getProperty("url");
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");
        Class.forName(driver);
        Connection connection = DriverManager.getConnection(url, username, password);
        connection.setAutoCommit(false);//不自动提交事务
        //为了明显地看出插入记录的效果,
        // 先删除所有记录,
        // 再插入一条记录,查询一次,
        // 最后一次性插入三条记录,查询一次
        //------------------------------------------------------------------------------------
        SqlRunner sqlRunner = new SqlRunner(connection);
        Integer rows = sqlRunner.delete("delete from user");//删除所有记录
        System.out.println("删除所有记录");
        System.out.println("rows affected:\t"+rows);

        rows = sqlRunner.insert("insert into user(name) values(?)", "盖亚奥特曼");
        System.out.println("插入一条记录");
        System.out.println("rows affected:\t"+rows);
        List<User> userList = sqlRunner.query("select * from user", new BeanListHandler<User>(User.class));
        System.out.println("userList\r\n"+userList);

        Object[][] arguments=new Object[][]{
                {"梦比优斯奥特曼"},{"雷欧奥特曼"},{"迪加奥特曼"}
        };
        rows = sqlRunner.insertBatch("insert into user(name) values(?)", arguments);
        System.out.println("插入三条记录");
        System.out.println("rows affected:\t"+rows);
        userList = sqlRunner.query("select * from user", new BeanListHandler<User>(User.class));
        System.out.println("userList\r\n"+userList);
        //------------------------------------------------------------------------------------

    }
}

3.2 运行结果

在这里插入图片描述

4. 使用SqlRunner对象进行修改操作

4.1 操作代码

package com.ytt.test;

import com.liurui.growth.*;
import com.ytt.domain.User;
import org.junit.Test;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.Properties;

public class SqlRunnerTest {
    @Test
    public void testQuery() throws ClassNotFoundException, IOException, SQLException {
        Properties properties = new Properties();
        properties.load(ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties"));
        String driver = properties.getProperty("driver");
        String url = properties.getProperty("url");
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");
        Class.forName(driver);
        Connection connection = DriverManager.getConnection(url, username, password);
        connection.setAutoCommit(false);//不自动提交事务

        //------------------------------------------------------------------------------------
        SqlRunner sqlRunner = new SqlRunner(connection);
        Integer rows = sqlRunner.delete("delete from user");//删除所有记录
        System.out.println("删除所有记录");
        System.out.println("rows affected:\t"+rows);

        Object[][] arguments=new Object[][]{
                {"梦比优斯奥特曼"},{"雷欧奥特曼"},{"迪加奥特曼"}
        };
        rows = sqlRunner.insertBatch("insert into user(name) values(?)", arguments);
        System.out.println("插入三条记录");
        System.out.println("rows affected:\t"+rows);
        List<User> userList = sqlRunner.query("select * from user", new BeanListHandler<User>(User.class));
        System.out.println("userList\r\n"+userList);

        rows = sqlRunner.update("update user set name=?", "欧布奥特曼");
        System.out.println("修改所有记录,将name的值修改为'欧布奥特曼'");
        System.out.println("rows affected:\t"+rows);
        userList = sqlRunner.query("select * from user", new BeanListHandler<User>(User.class));
        System.out.println("userList\r\n"+userList);

        //------------------------------------------------------------------------------------

    }
}

4.2 运行结果

在这里插入图片描述

5. 使用SqlRunner对象操作聚合函数及查看系统变量

5.1 操作代码

package com.ytt.test;

import com.liurui.growth.*;
import com.ytt.domain.User;
import org.junit.Test;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;

public class SqlRunnerTest {
    @Test
    public void testQuery() throws ClassNotFoundException, IOException, SQLException {
        Properties properties = new Properties();
        properties.load(ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties"));
        String driver = properties.getProperty("driver");
        String url = properties.getProperty("url");
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");
        Class.forName(driver);
        Connection connection = DriverManager.getConnection(url, username, password);
        connection.setAutoCommit(false);//不自动提交事务

        //------------------------------------------------------------------------------------
        SqlRunner sqlRunner = new SqlRunner(connection);

        List<Map<String, Object>> mapList = sqlRunner.query("select * from user", new MapListHandler<>(User.class));
        System.out.println("查询所有记录");
        System.out.println("mapList");
        for (Map<String, Object> stringObjectMap : mapList) {
            System.out.println(stringObjectMap);
        }
        System.out.println("---------------------------------------------");
        Integer count = sqlRunner.query("select count(*) from user", new ScalarHandler<>(Integer.class));
        System.out.println("count(*)\t"+count);
        Date date = sqlRunner.query("select max(birthdate) from user", new ScalarHandler<Date>(Date.class));
        System.out.println("max(birthdate)\t"+date);
        Double maxBalance = sqlRunner.query("select max(balance) from user", new ScalarHandler<Double>(Double.class));
        System.out.println("max(balance)\t"+maxBalance);
        String transactionIsolation = sqlRunner.query("select @@transaction_isolation", new ScalarHandler<String>(String.class));
        System.out.println("transactionIsolation\t"+transactionIsolation);


        //------------------------------------------------------------------------------------

    }
}

5.2 运行结果

在这里插入图片描述

三、 结构和代码展示

1. 整体结构

在这里插入图片描述

2. 代码

2.1 两个接口

2.1.1 ResultSetHandler接口,用来处理ResultSet
package com.liurui.origin;

import java.sql.ResultSet;
import java.sql.SQLException;

public interface ResultSetHandler <T>{

    T handle(ResultSet resultSet) throws SQLException;
    
}

2.1.2 Runner 接口,用来处理SQL语句
package com.liurui.origin;

import java.sql.Connection;
import java.sql.SQLException;

public interface Runner {

    <T> T query(String sql, ResultSetHandler<T> resultSetHandler) throws SQLException;

    <T> T query(String sql, ResultSetHandler<T> resultSetHandler, Object... arguments) throws SQLException;

    <T> T query(Connection connection, String sql, ResultSetHandler<T> resultSetHandler) throws SQLException;

    <T> T query(Connection connection, String sql, ResultSetHandler<T> resultSetHandler, Object... arguments) throws SQLException;

    Integer delete(String sql, Object... arguments);

    Integer delete(String sql);

    Integer delete(Connection connection, String sql, Object... arguments);

    Integer delete(Connection connection, String sql);

    Integer insert(String sql, Object... arguments);

    Integer insert(String sql);

    Integer insert(Connection connection, String sql, Object... arguments);

    Integer insert(Connection connection, String sql);

    Integer insertBatch(String sql, Object arguments[][]);

    Integer insertBatch(String sql);

    Integer insertBatch(Connection connection, String sql, Object arguments[][]);

    Integer insertBatch(Connection connection, String sql);

    Integer update(String sql, Object... arguments);

    Integer update(Connection connection, String sql, Object... arguments);

    Integer update(String sql);

    Integer update(Connection connection, String sql);

    void close();

}

2.2 六个实现接口类

2.2.1 BeanHandler类

实现ResultSetHandler接口,将ResultSet中的数据封装在一个JavaBean类中,并返回JavaBean对象。
使用场景:当ResultSet只有一条数据库表记录时。

package com.liurui.growth;

import com.liurui.origin.ResultSetHandler;
import com.liurui.utilities.ResultSetProcessor;
import java.sql.ResultSet;


public class BeanHandler<T> implements ResultSetHandler<T> {
    private Class<T> beanClass;
    private ResultSetProcessor<T> resultSetProcessor;
    public BeanHandler(Class<T> beanClass)
    {
        this(beanClass,new ResultSetProcessor<T>());
    }
    public BeanHandler(Class<T> beanClass,ResultSetProcessor<T> resultSetProcessor)
    {
        this.beanClass=beanClass;
        this.resultSetProcessor=resultSetProcessor;
    }
    @Override
    public T handle(ResultSet resultSet) {
        if (resultSet == null)
            return null;
       return resultSetProcessor.getBean(resultSet,beanClass);
    }
}
2.2.2 BeanListHandler类

实现ResultSetHandler接口,将ResultSet中的数据封装在一个List集合中,并返回List对象。
使用场景:当ResultSet有多条数据库表记录时。

package com.liurui.growth;
import com.liurui.origin.ResultSetHandler;
import com.liurui.utilities.ResultSetProcessor;
import java.sql.ResultSet;
import java.util.List;

public class BeanListHandler<T> implements ResultSetHandler<List<T>> {
    private Class<T> beanClass;
    private ResultSetProcessor<T> resultSetProcessor;
    public BeanListHandler(Class<T> beanClass)
    {
        this(beanClass, new ResultSetProcessor<>());
    }
    public BeanListHandler(Class<T> beanClass, ResultSetProcessor<T> resultSetProcessor)
    {
        this.beanClass=beanClass;
        this.resultSetProcessor=resultSetProcessor;
    }

    @Override
    public List<T> handle(ResultSet resultSet){
        if(resultSet==null)
            return null;
        return resultSetProcessor.getBeanList(resultSet,beanClass);
    }
}

2.2.3 MapHandler类

实现ResultSetHandler接口,将ResultSet中的数据封装在一个Map<String, Object>集合中,并返回Map对象。
使用场景:当ResultSet有一条数据库表记录时。

package com.liurui.growth;

import com.liurui.origin.ResultSetHandler;
import com.liurui.utilities.ResultSetProcessor;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;

public class MapHandler<T> implements ResultSetHandler<Map<String,Object>> {
    private Class<T> beanClass;
    private ResultSetProcessor resultSetProcessor;
    public MapHandler(Class<T> beanClass)
    {
        this(beanClass,new ResultSetProcessor<>());
    }
    public MapHandler(Class<T> beanClass,ResultSetProcessor<T> resultSetProcessor) {
        this.beanClass=beanClass;
        this.resultSetProcessor=resultSetProcessor;
    }

    @Override
    public Map<String, Object> handle(ResultSet resultSet) throws SQLException {
       return resultSetProcessor.getMap(resultSet,beanClass);
    }
}

2.2.4 MapListHandler类

实现ResultSetHandler接口,将ResultSet中的数据封装在一个List<Map<String, Object>>集合中,并返回List对象。
使用场景:当ResultSet有多条数据库表记录时。

package com.liurui.growth;

import com.liurui.origin.ResultSetHandler;
import com.liurui.utilities.ResultSetProcessor;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

public class MapListHandler<T> implements ResultSetHandler<List<Map<String,Object>>> {
    private Class<T> beanClass;
    private ResultSetProcessor<T> resultSetProcessor;
    public MapListHandler(Class<T> beanClass)
    {
        this(beanClass,new ResultSetProcessor<T>());
    }
    public MapListHandler(Class<T> beanClass,ResultSetProcessor<T> resultSetProcessor)
    {
        this.beanClass=beanClass;
        this.resultSetProcessor=resultSetProcessor;
    }
    @Override
    public List<Map<String, Object>> handle(ResultSet resultSet) throws SQLException
    {
        return resultSetProcessor.getMapList(resultSet,beanClass);
    }
}

2.2.5 ScalarHandler类

实现ResultSetHandler接口,将ResultSet中的数据封装在一个指定的数据类型(主要有:java.sql.Date,String,Integer,Long,Double,Float)中,并返回指定数据类型的对象。
使用场景:执行SQL聚合函数后得到的ResultSet

package com.liurui.growth;

import com.liurui.origin.ResultSetHandler;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;

public class ScalarHandler<T> implements ResultSetHandler<T> {
    private final String columnName;//表中字段名
    private final Integer columnIndex;//表中字段索引,从1开始
    private Class<T> outcomeClass;//将查询出来的结果封装到指定类的Class

    public ScalarHandler(Class<T> outcomeClass, Integer columnIndex) {

        this(outcomeClass, null, columnIndex);
    }

    public ScalarHandler(Class<T> outcomeClass) {
        this(outcomeClass, null, 1);//为字段索引指定默认值1,即第一列
    }

    public ScalarHandler(Class<T> outcomeClass, String columnName) {
        this(outcomeClass, columnName, 1);//为字段索引指定默认值1
    }

    private ScalarHandler(Class<T> outcomeClass, String columnName, Integer columnIndex) {
        this.outcomeClass = outcomeClass;
        this.columnName = columnName;
        this.columnIndex = columnIndex;
    }

    @Override
    public T handle(ResultSet resultSet) throws SQLException {
        //不管有没有通过构造函数传入的参数为this.columnIndex赋值,this.columnIndex都会赋默认值1
        //而this.columnName必须由构造函数传入的参数为其赋值,否则this.columnName为null

        String outcomeString=null;
        try{
        if (resultSet.next()) {
            outcomeString = columnName == null ?
                    resultSet.getObject(columnIndex).toString() :
                    resultSet.getObject(columnName).toString();
            T entityObject = transform(outcomeClass, outcomeString);

            return entityObject;
        }
        }catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e)
        {
            e.printStackTrace();
        }

        return null;
    }

    private T transform(Class<T> toClass, String fromString) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        if(fromString.getClass()==toClass)
        {
            return (T)fromString;
        }
        Method valueOfMethod = toClass.getMethod("valueOf",String.class);//取出静态方法valueOf
        T entityObject =(T)valueOfMethod.invoke(null, fromString);
        return entityObject;
    }

}

2.2.6 SqlRunner类

实现Runner接口,执行SQL语句
使用场景:通过Connection对象,Sql语句, ,Sql语句的参数,指定的ResultSetHandler实现类,执行Sql语句,并根据指定的ResultSetHandler实现类,生成对应的返回值

package com.liurui.growth;

import com.liurui.origin.ResultSetHandler;
import com.liurui.origin.Runner;

import java.sql.*;

/*
    主操作类
    通过SqlRunner对象来执行SQL语句
*/
public class SqlRunner implements Runner {
    private Connection connection;
    private PreparedStatement preparedStatement;
    private ResultSet resultSet;

    public SqlRunner() {
    }

    public SqlRunner(Connection connection) {
        this.connection = connection;
    }

    private void fillArguments(PreparedStatement preparedStatement, Object... arguments)//给PreparedStatement填充参数
    {
        if (preparedStatement == null)
            return;
        if (arguments == null)
            return;
        ParameterMetaData parameterMetaData;
        try {
            parameterMetaData = preparedStatement.getParameterMetaData();
            int parameterCount = parameterMetaData.getParameterCount();
            if (parameterCount != arguments.length)
                return;
            for (int i = 0; i < parameterCount; i++) {
                preparedStatement.setObject(i + 1, arguments[i]);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private <T> T executeDQL(Connection connection, String sql, ResultSetHandler<T> resultSetHandler, Object... arguments)
    {

        T outcome = null;
        try {
            if ((this.connection == null || this.connection.isClosed()) && connection != null) {
                this.connection = connection;
            }
            if ((this.connection == null || this.connection.isClosed()) && connection == null) {
                throw new SQLException("There is no Database Connectivity");
            }
            if (sql == null || sql.trim() == "" || resultSetHandler == null)
                return null;
            this.preparedStatement = this.connection.prepareStatement(sql);
            fillArguments(this.preparedStatement,arguments);
            this.resultSet = this.preparedStatement.executeQuery();
            outcome = resultSetHandler.handle(resultSet);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return outcome;
    }

    @Override
    public <T> T query(String sql, ResultSetHandler<T> resultSetHandler) {
        return executeDQL(null, sql, resultSetHandler, null);
    }

    @Override
    public <T> T query(String sql, ResultSetHandler<T> resultSetHandler, Object... arguments) {
        return executeDQL(null, sql, resultSetHandler, arguments);
    }

    @Override
    public <T> T query(Connection connection, String sql, ResultSetHandler<T> resultSetHandler) throws SQLException {
        return executeDQL(connection, sql, resultSetHandler, null);
    }

    @Override
    public <T> T query(Connection connection, String sql, ResultSetHandler<T> resultSetHandler, Object... arguments) throws SQLException {
        return executeDQL(connection, sql, resultSetHandler, arguments);
    }

    private int executeDML(Connection connection, String sql, Object... arguments)
    {
        int affectedRow = 0;
        try {
            if ((this.connection == null || this.connection.isClosed()) && connection != null) {
                this.connection = connection;
            }
            if ((this.connection == null || this.connection.isClosed()) && connection == null) {
                throw new SQLException("There is no Database Connectivity");
            }
            if (sql == null || sql.trim() == "")
                return -1;
            this.preparedStatement = this.connection.prepareStatement(sql);
            fillArguments(this.preparedStatement, arguments);
            affectedRow = preparedStatement.executeUpdate();
            return affectedRow;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return affectedRow;
    }

    @Override
    public Integer delete(String sql, Object... arguments) {
        return executeDML(null, sql, arguments);
    }

    @Override
    public Integer delete(String sql) {
        return executeDML(null, sql, null);
    }

    @Override
    public Integer delete(Connection connection, String sql, Object... arguments) {
        return executeDML(connection, sql, arguments);
    }

    @Override
    public Integer delete(Connection connection, String sql) {
        return executeDML(connection, sql, null);
    }

    @Override
    public Integer insert(String sql, Object... arguments) {
        return executeDML(null, sql, arguments);
    }

    @Override
    public Integer insert(String sql) {
        return executeDML(null, sql, null);
    }

    @Override
    public Integer insert(Connection connection, String sql, Object... arguments) {
        return executeDML(connection, sql, arguments);
    }

    @Override
    public Integer insert(Connection connection, String sql) {
        return executeDML(connection, sql, null);
    }

    private int executeBatchDML(Connection connection, String sql, Object[][] arguments)
    {
        int affectedRow = 0;
        try {
            if ((this.connection == null || this.connection.isClosed()) && connection != null) {
                this.connection = connection;
            }
            if ((this.connection == null || this.connection.isClosed()) && connection == null) {
                throw new SQLException("There is no Database Connectivity");
            }
            if (sql == null || sql.trim() == "")
                return -1;
            this.preparedStatement = this.connection.prepareStatement(sql);
            if(arguments!=null)
            {
                for (int i = 0; i < arguments.length; i++) {
                    fillArguments(this.preparedStatement, arguments[i]);
                    this.preparedStatement.addBatch();
                }
            }
            affectedRow = preparedStatement.executeBatch().length;
            return affectedRow;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return affectedRow;
    }

    @Override
    public Integer insertBatch(String sql,Object arguments[][])
    {
        return executeBatchDML(null, sql, arguments);
    }

    @Override
    public Integer insertBatch(String sql) {
        return executeBatchDML(null,sql,null);
    }

    @Override
    public Integer insertBatch(Connection connection, String sql, Object arguments[][])
    {
        return executeBatchDML(connection,sql,arguments);
    }

    @Override
    public Integer insertBatch(Connection connection, String sql) {
       return executeBatchDML(connection,sql,null);
    }

    @Override
    public Integer update(String sql, Object... arguments) {
        return executeDML(null, sql, arguments);
    }

    @Override
    public Integer update(String sql) {
        return executeDML(null, sql, null);
    }

    @Override
    public Integer update(Connection connection, String sql) {
        return executeDML(connection, sql, null);
    }

    @Override
    public Integer update(Connection connection, String sql, Object... arguments) {
        return executeDML(connection, sql, arguments);
    }

    public void close(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet) {
        try {
            if (connection != null && !connection.isClosed())
                connection.close();
            if (preparedStatement != null && !preparedStatement.isClosed())
                preparedStatement.close();
            if (resultSet != null && !resultSet.isClosed())
                resultSet.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void close(Connection connection) {
        close(connection, this.preparedStatement, this.resultSet);
    }


    @Override
    public void close() {
        close(this.connection, this.preparedStatement, this.resultSet);
    }


}

2.3 两个工具类

2.3.1 BeanUtilities

该类中都是静态方法,用作bean和map之间的转换

package com.liurui.utilities;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;


public class BeanUtilities {
    /*
            该Map用作缓冲,Key存储JavaBean的全限定类名,Value存储JavaBeanClass中Field对象的List集合
    */
    private final static Map<String, List<Field>> bufferMap=new TreeMap<>();
    /*
        使用内省获取JavaBeanClass中所有的Field对象
        传入参数:JavaBean的Class对象
        返回参数:装载JavaBeanClass中所有Field对象的List集合
    */
    public static <T> List<Field> getBeanFieldList(Class<T> beanClass)
    {
        if(bufferMap.containsKey(beanClass.getName()))//若Map的Key中已存储JavaBean的全限定类名
        {
            return bufferMap.get(beanClass.getName());//则直接返回已装载JavaBeanClass中所有Field对象的List集合
        }
        BeanInfo beanInfo;
        String property;
        Method writeMethod;
        Method readMethod;
        Field field;
        List<Field> fieldList = null;
        try {
            beanInfo = Introspector.getBeanInfo(beanClass);//运用内省
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            fieldList = new ArrayList<>();
            for (PropertyDescriptor propertyDescriptor : propertyDescriptors) //遍历Field描述器或属性描述器
            {
                property = propertyDescriptor.getName();//获取Field的名字
                writeMethod = propertyDescriptor.getWriteMethod();//Field对应的写方法
                readMethod = propertyDescriptor.getReadMethod();//Field对应的读方法
                if (writeMethod != null && readMethod != null) //排除getClass()方法
                {
                    field = beanClass.getDeclaredField(property);//由Field的名字取出Field对象
                    field.setAccessible(true);//暴力反射
                    fieldList.add(field);
                }
            }
        } catch (IntrospectionException | NoSuchFieldException ex) {
            ex.printStackTrace();
        }
        bufferMap.put(beanClass.getName(),fieldList);
        return fieldList;
    }

    public static <T> Map<String, Object> beanToMap(T beanObject, Class<T> beanClass)
    {
        if (beanObject == null || beanClass == null)
            return null;
        List<Field> beanFieldList = getBeanFieldList(beanClass);//通过JavaBeanClass获取其所有的Field对象的List集合
        Map<String, Object> beanMap = null;
        try
        {
            beanMap = new TreeMap<>();
            for (Field field : beanFieldList)//遍历List
            {
                beanMap.put(field.getName(), field.get(beanObject));//取出Field对象的名字和Field在JavaBean对象中对应的值
            }
        }catch (IllegalAccessException e)
        {
            e.printStackTrace();
        }
        return beanMap;
    }


    public static <T> T mapToBean(Map<String, Object> map, Class<T> beanClass) {
        if (map == null || beanClass == null)
            return null;
        if (map.size() == 0)
            return null;
        T beanObject = null;
        try {
            beanObject = beanClass.getConstructor().newInstance();//通过反射,创建JavaBean对象
            List<Field> beanFieldList = getBeanFieldList(beanClass);通过JavaBeanClass获取其所有的Field对象的List集合
            for (Field field : beanFieldList) //遍历List
            {
                field.set(beanObject,map.get(field.getName()));//为JavaBean对象的每一个Field赋值
            }
        } catch (InstantiationException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        return beanObject;
    }
}


2.3.2 ResultSetProcessor

该类中主要用来处理ResultSet,供ResultSetHandler的实现类使用

package com.liurui.utilities;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


public class ResultSetProcessor<T> {

    public List<T> getBeanList(ResultSet resultSet, Class<T> beanClass)
    {
        ResultSetMetaData resultSetMetaData;
        List<T> beanList = null;
        String fieldName;
        Object value;
        T beanObject;
        Field declaredField;
        try {
            resultSetMetaData = resultSet.getMetaData();
            int columnCount = resultSetMetaData.getColumnCount();
            beanList = new ArrayList<>();
            while (resultSet.next()) //不论ResultSet对象中有一个还是多个记录,都遍历它,
            {
                beanObject = beanClass.getConstructor().newInstance();//创建存储数据库表记录的JavaBean对象
                for (int i = 0; i < columnCount; i++)
                {
                    fieldName = resultSetMetaData.getColumnLabel(i + 1);
                    value = resultSet.getObject(i + 1);
                    declaredField = beanClass.getDeclaredField(fieldName);
                    declaredField.setAccessible(true);
                    declaredField.set(beanObject, value);//将表中记录的每一列的值存储于JavaBean的属性中
                }
                beanList.add(beanObject);//将JavaBean对象装入List集合中
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //若ResultSet对象有一条记录,那么List对象的size为1,若ResultSet对象有10条记录,那么List对象的size为10
        //若ResultSet对象没有记录,那么List对象的size为0
        return beanList;
    }

    public T getBean(ResultSet resultSet, Class<T> beanClass)
    {
       return BeanUtilities.mapToBean(getMap(resultSet,beanClass),beanClass);
    }

    public Map<String,Object> getMap(ResultSet resultSet, Class<T> beanClass)
    {
        List<T> beanList = getBeanList(resultSet, beanClass);
        if(beanList==null || beanList.size()==0)
            return null;
        T beanObject= beanList.get(0);
        return BeanUtilities.beanToMap(beanObject,beanClass);
    }

    public List<Map<String,Object>> getMapList(ResultSet resultSet, Class<T> beanClass)
    {
        List<T> beanList = getBeanList(resultSet, beanClass);
        if(beanList==null || beanList.size()==0)
            return null;
       List<Map<String,Object>> mapList=new ArrayList<>();
       Map<String,Object> map;
        for (T t : beanList) {
            map = BeanUtilities.beanToMap(t, beanClass);
            mapList.add(map);
        }
        return mapList;
    }

}

四、总结

纸上得来终觉浅,绝知此事要躬行!只有理性的认识,不足以把握事物,我们还得亲身去接触事物,感受事物,反复认识事物,才能越来越接近事物的本质。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值