简单的DbUtils工具类

目录

单条通用增删改方法

        1.创建maven项目,并加载依赖

 2.创建数据库连接工具类(Dbutils类)

3.创建一个执行器(SqlExecutor类)

4.通用(增,删,改)方法

1.创建方法

2.创建userInfo实体类

3.创建测试类,测试增,删,改三个操作

4.最后执行结果

批量(增,删,改)方法

1.在sqlExecutor类中添加一个executeBatch(String,Object[][])方法

2. 测试类中执行 批量(增,删,改)操作

3.最后运行结果

通用查询

策略模式:

1.定义一个类型转换接口 ResultSetHandler

【一】将查询结果转换为Array数组

1.定义ArrayHandler转换类,实现ResultSetHandler接口

2.定义RowProcessor行处理器

3. 在SqlExecutor类中定义通用查询方法

【二】将查询结果转换为Map集合

1.定义MapHandler类,实现ResultSetHandler

2.在RowProcessor类中实现具体转换map集合的方法

【二.五】测试转换的两个类型(Array和Map)

1.分别创建两个策略

2.最后转换结果

【三】将结果集转换成Bean对象


单条通用增删改方法

        1.创建maven项目,并加载依赖

对应maven的依赖为:

        <!--mysql驱动-->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <version>8.2.0</version>
        </dependency>


        <!--单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>


        <!--lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.32</version>
            <scope>provided</scope>
        </dependency>

 2.创建数据库连接工具类(Dbutils类)

作用:   用于获取Connection连接对象,连接数据库

package com.xr.utils;

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

/**
 * 数据库连接工具类
 * 作用: 用于获取Connection连接对象
 * @author xr
 * @Date 2024/5/8 13:10
 */

public class Dbutils {

    /**
     * 数据库驱动
     * @Date 2024/5/8 13:12
     */

    private static final String DRIVER = "com.mysql.cj.jdbc.Driver";

    /**
     * 数据据连接地址
     * jdbc:mysql://localhost:3306/数据库名称?serverTimezone=GMT%2B8"
     * @Date 2024/5/8 13:12
     */

    private static final String URL = "jdbc:mysql://localhost:3306/dbutils?serverTimezone=GMT%2B8";

    /**
     * 数据库用户名
     * @Date 2024/5/8 13:12
     */

    private static final String USER = "root";

    /**
     * 数据库密码
     * @Date 2024/5/8 13:12
     */

    private static final String PASSWORD = "1234";

    /**
     * 获取数据库连接
     * @Date 2024/5/8 13:12
     */
    public static Connection getConnection() {
        // 定义数据库连接对象
        Connection conn = null;


        try {
            // 注册JDBC驱动
            Class.forName(DRIVER);
            // 获取数据库连接
            conn = DriverManager.getConnection(URL, USER, PASSWORD);
        } catch (ClassNotFoundException | SQLException e) {
            throw new RuntimeException("数据数据库连接失败!!!!",e);
        }
        // 返回连接对象
        return conn;
    }
}

3.创建一个执行器(SqlExecutor类)

作用: 

         封装增,删,查,改操作

package com.xr.utils;

import java.sql.Connection;



/**
 * sql 执行器,操作执行sql,通用增删改操作
 * 作用: 封装增删改查操作
 * @author xr
 * @Date 2024/5/8 13:19
 */
public class SqlExecutor {

    /**
     * 定义连接对象
     * @Date 2024/5/8 13:20
     */

    private final Connection conn;

    /**
     * 构造方法,初始化连接对象
     * @Date 2024/5/8 13:20
     */
    public SqlExecutor(Connection conn) {
        this.conn = conn;
    }


}


4.通用(增,删,改)方法

因为我想使用一个方法就可以完成(增,删,改)操作

1. 例如:

        // 增加数据

        insert into user_info(u_name,u_password,u_age,deposit,brith)

        value(?,?,?,?,?);

        // 删除数据

        delete from user_info where u_name = ?

        // 修改数据

        update user set u_name = ? where id = ?

2. 发现:

        我们的有不同的sql语句,设置不同的值

3. 解决方案: 

        使用PreparedStatement中的预编译sql语句,使用占位数 ? 解决值未知问题

4.思路: 

         1. 定义方法 excuteUpdate(sql,Object... params){};

         2. sql: sql语句  , params : 为多个参数,返回一个任意类型数组

         3. 将sql语句进行预编译操作,设置传递过来的参数

         4. 为什么要将预编译操作抽离出来一个方法,因为可以使方法结果更清晰

         5. 执行sql语句,返回受影响行数

         6.关闭资源

1.创建方法

        executeUpdate(String,Object...) : 通用增,删,改方法

        setPreparedStatement(PreparedStatement,Object...) : sql语句预编译,并设置参数

        close(Statement st) :关闭Statement对象资源

        close(ResultSet rs) : 关闭ResultSet对象资源

        close() :关闭Connection连接对象资源

    /**
     * 通用执行增删改操作方法
     * sql: sql语句
     * params: sql语句中占位符对应的参数
     * @Date 2024/5/8 13:23
     */    
public int executeUpdate(String sql,Object... params) throws SQLException {
        // 判断连接对象是否为空
        if (conn == null) {
            throw new RuntimeException("连接对象为空!!!");
        }

        // 判断sql语句是否为空
        if(sql == null || sql.isEmpty()) {
            throw new RuntimeException("sql语句为空!!!");
        }

        // 定义PreparedStatement对象,作用对sql语句进行预编译
        PreparedStatement ps = null;

        try {
            // 将sql进行预编译,方法中抛出SQL异常
            ps = conn.prepareStatement(sql);

            // 设置sql 中 ?号 占位符对应的参数
            // 比如 sql = "insert into user(name,age) values(?,?)"
            setPreparedStatementParams(ps,params);

            // 执行sql语句,返回影响行数
            return ps.executeUpdate();
        } catch (SQLException e) {
            // 异常重抛,重抛成运行时异常
            throw new RuntimeException("执行sql语句失败!!!",e);
        } finally {
            // 关闭资源
            close(ps);
            close();
        }
    }


    /**
     * 设置sql预编译参数
     * @Date 2024/5/8 9:04
     */

    private void setPreparedStatement(PreparedStatement preparedStatement,Object... params)throws SQLException {
        // insert into user(id,name,age) values(?,?,?)
        // update user set name=?,age=? where id=?
        // 循环的边界为传递过来的params参数长度
        for (int i = 0; i < params.length; i++) {
            // 设置占位符?对应的值,占位符下标从1开始
            preparedStatement.setObject(i+1,params[i]);
        }
    }



    /**
     * 关闭PreparedStatement对象资源
     * @Date 2024/5/8 13:54
     */

    private void close(PreparedStatement ps) {
        if (ps != null) {
            try {
                // 关闭PreparedStatement对象资源
                ps.close();
            } catch (SQLException e) {
                throw new RuntimeException("关闭PreparedStatement对象失败!!!",e);
            }
        }
    }

    /**
     * 关闭连接对象资源
     * @Date 2024/5/8 13:54
     */
    private void close() {
        if (conn != null ) {
            try {
                // 关闭连接对象资源
                conn.close();
            } catch (SQLException e) {
                throw new RuntimeException("关闭conn对象资源失败!!!",e);
            }
        }
    }


    /**
     * 关闭ResultSet对象资源
     * @param rs 结果集对象
     */
    private void close(ResultSet rs) {
        if (rs != null) {
            try {
                // 关闭ResultSet对象资源
                rs.close();
            } catch (SQLException e) {
                throw new RuntimeException("关闭ResultSet对象失败!!!",e);
            }
        }
    }

2.创建userInfo实体类

package com.xr.entity;

import com.xr.util.interfaceUtils.Column;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * userInfo实体
 * @Data注解: 拥有get,set方法
 * @AllArgsConstructor: 拥有全参数构造方法
 * @NoArgsConstructor: 拥有无参构造方法
 * @author xr
 * @Date 2024/5/8 20:51
 */


@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserInfo {
    /**
     * id
     */
    private Integer id; 
    /**
     * 用户名
     */
    private String username;
    /**
     * 密码
     */
    private String password;
    /**
     * 年龄
     */
    private Integer age;
    /**
     * 存款
     */
    private BigDecimal deposit;
    /**
     * 生日
     */
    private LocalDateTime birth;
}

3.创建测试类,测试增,删,改三个操作

package com.xr;

import com.xr.utils.Dbutils;
import com.xr.utils.SqlExecutor;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.time.LocalDateTime;

/**
 * 测试类
 * @author xr
 * @Date 2024/5/10 10:54
 */

public class TestSql {
    public static void main(String[] args) throws SQLException {

        //*----------------------添加数据-----------------------*/
        // 创建SqlExecutor对象控制器,并传入连接对象
        SqlExecutor sqlExecutor = new SqlExecutor(Dbutils.getConnection());
        // 定义sql语句,[插入数据]
        String sql = "insert into user_info(u_name,u_password,u_age,deposit,birth) values(?,?,?,?,?)";

        // 增加数据操作
        int i = sqlExecutor.executeUpdate(sql, "张三", "123456", 18, new BigDecimal(1000), LocalDateTime.now());

        //输出结果
        System.out.println("插入数据:" + i +"行");


        /*----------------------修改数据-----------------------*/
        sqlExecutor = new SqlExecutor(Dbutils.getConnection());
        // 定义sql语句,[修改数据]
        sql = "update user_info set u_password = ? where u_name = ?";

        // 修改数据操作
        i = sqlExecutor.executeUpdate(sql, "22222","张三");

        //输出结果
        System.out.println("修改数据:" + i +"行");




        /*----------------------删除数据-----------------------*/
        sqlExecutor = new SqlExecutor(Dbutils.getConnection());
        // 定义sql语句,[删除数据]
        sql = "delete from user_info where u_name = ?";

        // 删除数据操作
        i = sqlExecutor.executeUpdate(sql, "张三");

        //输出结果
        System.out.println("删除数据:" + i +"行");
    }
}

4.最后执行结果


批量(增,删,改)方法

前面定义的方法是 :

        1.单条增加数据

        2.单条修改数据

        3.单条删除数据

现在我想批量做这些操作(多条),就是将多个sql语句参数装数组里面,定义一个Object[][]二维数组,存储参数

思路:

        1.将sql语句进行预编译

        2.将sql语句中的占位符对应的参数设置到sql语句中

        3.将sql语句添加到批量缓存中

        4.批量提交到数据库中

1.在sqlExecutor类中添加一个executeBatch(String,Object[][])方法

String : sql语句

Object[][] : sql语句的参数

  /**
     * 批量执行sql语句(增,删,改)
     * 实现思路:
     * 1.将sql语句进行预编译
     * 2.将sql语句中的占位符对应的参数设置到sql语句中
     * 3.将sql语句添加到批量缓存中
     * 4.批量提交到数据库中
     * @param sql sql语句
     * @param params 参数数组
     * @return 受影响行数
     */
    public int[] executeBatch(String sql,Object[][] params) {
        if (conn == null) {
            throw new RuntimeException("连接对象为空!!!");
        }

        if (sql == null || sql.isEmpty()) {
            throw new RuntimeException("sql语句为空!!!");
        }

        // 定义PreparedStatement对象
        PreparedStatement ps = null;

        try {
            // 将sql语句进行预编译
            ps = conn.prepareStatement(sql);

            // 遍历params数组,将数组中的参数设置到sql语句中
            // 第一个循环遍历params数组,第二个循环遍历params数组中的数组

            for(Object[] param : params) {

                // 设置sql语句中占位符对应的参数
                setPreparedStatementParams(ps,param);

                //将ps的操作缓存到内存中,最后在批量提交到数据库中  添加到批量缓存中
                ps.addBatch();
            }

            // 批量提交sql语句
            return ps.executeBatch();
        } catch (SQLException e) {
            throw new RuntimeException("预编译sql语句失败!!!",e);
        } finally {
            close(ps);
            close();
        }
    }

2. 测试类中执行 批量(增,删,改)操作

package com.xr;

import com.xr.utils.Dbutils;
import com.xr.utils.SqlExecutor;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.time.LocalDateTime;

/**
 * 测试类
 * @author xr
 * @Date 2024/5/10 10:54
 */

public class TestSql {
    public static void main(String[] args) throws SQLException {

        //*----------------------批量添加数据-----------------------*/
        // 创建SqlExecutor对象控制器,并传入连接对象
        SqlExecutor sqlExecutor = new SqlExecutor(Dbutils.getConnection());


        // 定义sql语句,[批量插入数据]
        String sql = "insert into user_info(u_name,u_password,u_age,deposit,birth) values(?,?,?,?,?)";

        // 创建二维数组
        Object[][] params = {
                {"李四", "123456", 18, new BigDecimal(1000), LocalDateTime.now()},
                {"王五", "123456", 18, new BigDecimal(1000), LocalDateTime.now()},
                {"张三", "123456", 18, new BigDecimal(1000), LocalDateTime.now()}
        };

        // 批量增加数据操作
        int[] i = sqlExecutor.executeBatch(sql,params );

        //输出结果
        System.out.println("批量添加数据:" + i.length +"行");


        /*----------------------批量修改数据-----------------------*/
        sqlExecutor = new SqlExecutor(Dbutils.getConnection());

        // 定义sql语句,[批量修改数据]
        sql = "update user_info set u_password = ? where u_name = ?";

        // 创建二维数组
        params = new Object[][]{
                {"11111","李四"},
                {"22222","王五"},
                {"33333","张三"}
        };

        // 批量修改数据操作
        i = sqlExecutor.executeBatch(sql, params);

        //输出结果
        System.out.println("批量修改数据:" + i.length +"行");




        /*----------------------批量删除数据-----------------------*/
        sqlExecutor = new SqlExecutor(Dbutils.getConnection());
        // 定义sql语句,[批量删除数据]
        sql = "delete from user_info where u_name = ?";

        //定义二位数组
        params = new Object[][]{
                {"李四"},
                {"王五"},
                {"张三"}
        };

        // 批量删除数据操作
        i = sqlExecutor.executeBatch(sql, params);

        //输出结果
        System.out.println("批量删除数据:" + i.length +"行");
    }
}

3.最后运行结果


通用查询

前面完成了增删改操作,就差一个查询了

当从数据库查询出来的结果后,java代码如何拿到呢???

        1.可以通过Array数组接收

        2.可以通过map集合接收

        3.可以将查询出来的结果映射成java对象

        4.如果只查一列的值,直接返回一个任意基本数据类型接收

这里有4中选项可以选择,将查询出的结果使用多种方式接收他,如果按照常理的方案写的话,需要写多个if,else很麻烦,所以可以择优简便选择使用策略模式


 

策略模式:

策略模式:

        我的理解: 当一个东西可以有很多种选择时,就可以考虑使用策略来简化代码了

        官方解释:

                策略模式是一种设计模式,它允许在运行时选择算法的行为。在策略模式中,可以定义一系列算法,并将每个算法封装在单独的类中。这些算法具有相同的接口,使得它们可以互相替换,而客户端代码则可以根据需要选择合适的算法。

        比如:

                我商城购买了一件东西,付款的时候可有有多种支付方式,如:支付宝支付,微信支付,银联支付,这时也是有多种选择

1.定义一个类型转换接口 ResultSetHandler

作用:

        是封装结果集不同处理方法,将查询的结果转换成不同的形式

ResultSet :结果集,我们通过结果集来转化为其他类型

package com.xr.util;

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

/**
 * 抽象的结果集处理器
 * @author xr
 * @Date 2024/5/8 9:58
 */

public interface ResultSetHandler<T> {
    /**
     * 结果集的处理方法
     * @param rs 结果集对象
     * @return 处理后的对象,因为返回的对象是未知类型,定义成泛型
     * @throws SQLException sql异常
     */
    T handle(ResultSet rs) throws SQLException;
}

【一】将查询结果转换为Array数组

实现思路: 

        1. 定义一个ArrayHandler类,实现ResultSetHandler接口

        2. 定义一个RowProcessor工具类,具体的实现转换方法写在该类

        2. 重写Handle方法,调用RowProcessor工具类中的具体转换实现

为什么不直接到ArrayHandler类中直接写转换的实现,而是又定义一个RowProcessor工具类来实现呢?

        1. 因为要避免将具体的实现逻辑暴露给调用者,因为调用者并不需要知道如何将结果集转换为数组,而是应该只关心如何将结果集转换为数组,所以将具体的实现逻辑写在RowProcessor中,也遵循单一职责原则

        2.看RowProcessor这个类名,他是一个行处理工具类,所以现在将查询出来的结果转换成其他类型都只是转换1条数据,如果多条数据需要转换的话,我们也可以调用行处理器中的实现,简便代码

1.定义ArrayHandler转换类,实现ResultSetHandler接口

作用:

        将查询出来的数据(单条)转换成数组

package com.xr.result;

import com.xr.utils.ResultSetHandler;
import com.xr.utils.RowProcessor;

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

/**
 * 数组转换类
 * @author xr
 * @Date 2024/5/10 19:31
 */

public class ArrayHandler implements ResultSetHandler<Object[]> {

    /**
     * 将结果集转换为数组
     * @param rs 结果集
     * @return 返回转换后的数组
     * @throws SQLException 抛出sql异常
     */
    @Override
    public Object[] handle(ResultSet rs) throws SQLException {
        // 如果结果集有数据,则调用工具类中的方法将结果集转换为数组,否则返回null
        return rs.next() ? RowProcessor.toArray(rs):null;
    }
}

2.定义RowProcessor行处理器

作用:

        将转换多个类型具体操作全部写在本类,实施单一职责

在类中定义toArray()方法

      作用: 将查询出的数据结果集转换成数组

package com.xr.utils;

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

/**
 * 行处理器工具类
 * @author xr
 * @Date 2024/5/10 19:34
 */

public class RowProcessor {

    /**
     * 将结果集转换为数组
     * @param rs 数据集对象
     * @return 转换后的数组
     * @throws SQLException 抛出sql异常
     */
    public static Object[] toArray(ResultSet rs) throws SQLException {
        // 定义数组,使用结果集的元数据中的列数作为数组长度
        Object[] result = new Object[rs.getMetaData().getColumnCount()];

        // 遍历结果集
        for(int i = 0; i< result.length; i++) {
            // 遍历数组,将结果集的每一列的值赋值给数组,通过结果集的下标获取具体值
            result[i] = rs.getObject(i+1);
        }

        // 返回数组
        return result;
    }
}
3. 在SqlExecutor类中定义通用查询方法

executeQuery(String,ResultSetHandler,Object....)

        作用:

                通用返回结果类,并将查询的结果转换成指定的类型

String :sql语句

ResultSetHandler:指定转换类型的实现类

Object...: 参数数组

  /**
     * 执行查询sql语句,返回指定类型
     * 实现思路:
     * 1.将sql语句进行预编译
     * 2.将sql语句中的占位符对应的参数设置到sql语句中
     * 3.执行sql语句,返回结果集
     * 4.调用处理器,将查询的结果转换成指定类型
     * 5.返回转换之后的类型
     * @param sql sql语句
     * @param handler 结果集处理器, 将结果集转换为指定类型
     * @param params 参数数组
     * @return 返回转换之后的类型
     */
    public <T> T executeQuery(String sql,ResultSetHandler<T> handler,Object... params) {
        if (conn == null) {
            throw new RuntimeException("连接对象为空!!!");
        }

        if (sql == null || sql.isEmpty()) {
            throw new RuntimeException("sql语句为空!!!");
        }
        if (handler == null) {
            throw new RuntimeException("ResultSetHandler为空!!!");
        }

        // 定义PreparedStatement对象
        PreparedStatement ps = null;
        // 声明结果集对象
        ResultSet rs = null;

        // 定义转换后的结果
        T result = null;

        try {
            // 将sql语句进行预编译
            ps = conn.prepareStatement(sql);

            // 设置sql语句中占位符对应的参数
            setPreparedStatementParams(ps,params);

            //执行sql
            rs = ps.executeQuery();

            // 调用处理器,将查询的结果转换成指定类型
            result = handler.handle(rs);

            // 返回转换后的类型
            return result;


        }catch (SQLException e) {
            throw new RuntimeException("预编译sql语句失败!!!",e);
        } finally {
            // 关闭ResultSet结果集资源
            close(rs);
            // 关闭PreparedStatement对象资源
            close(ps);
            // 关闭Connection连接对象资源
            close();
        }
    }


【二】将查询结果转换为Map集合

前面已经实现第一个策略,将查询的结果转换成Array数组

现在将查询结果转换成Map集合,同样也是将这个策略实现ResultSetHandler接口

实现思路:

        1.定义一个类MapHandler,并实现ResultsetHandler接口,重写handle方法

        2.在行转换器RowProcess类中写出转换成map类型方法的具体实现

        3.查询的结果字段作为map集合的key,具体值作为map集合的value

1.定义MapHandler类,实现ResultSetHandler
package com.xr.result;

import com.xr.utils.ResultSetHandler;
import com.xr.utils.RowProcessor;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;

/**
 * 将查询的结果ResultSet结果集转换为Map集合
 * @author xr
 * @Date 2024/5/11 8:42
 */

public class MapHandler implements ResultSetHandler<Map<String,Object>> {

    /**
     * 将查询的结果ResultSet结果集转换为Map集合
     * @param rs 结果集
     * @return 返回转换后的Map集合
     * @throws SQLException sql异常
     */
    @Override
    public Map<String, Object> handle(ResultSet rs) throws SQLException {
        // 如果结果集有数据,则返回Map集合,否则返回null
        return rs.next() ? RowProcessor.toMap(rs) : null;
    }
}
2.在RowProcessor类中实现具体转换map集合的方法
    /**
     * 将查询结果转换成map
     * 思路:
     * 1. 获取结果集的元数据
     * 2. 获取结果集的列数
     * 3. 遍历结果集,将结果集的每一列的值赋值给map,通过结果集的下标获取具体值
     * 4. map集合中的key为列名,value为列的值
     * 5. 返回map
     * @param rs 数据集对象
     * @return 返回转换后的map集合
     * @throws SQLException sql异常
     */
    public static Map<String,Object> toMap(ResultSet rs) throws SQLException {
        // 定义map数组
        Map<String,Object> result = new HashMap<>();

        //循环遍历结果结合
        for(int i = 0; i<rs.getMetaData().getColumnCount(); i++) {
            // 获取列名
            String columnName = rs.getMetaData().getColumnName(i+1);
            // 获取列值
            Object object = rs.getObject(i + 1);
            // 将列名和列值添加到map集合中
            result.put(columnName,object);
        }
        // 返回map数组
        return result;
    }

【二.五】测试转换的两个类型(Array和Map)

1.分别创建两个策略
package com.xr;

import com.xr.result.ArrayHandler;
import com.xr.result.MapHandler;
import com.xr.utils.Dbutils;
import com.xr.utils.ResultSetHandler;
import com.xr.utils.SqlExecutor;

import java.sql.SQLException;
import java.util.Arrays;
import java.util.Map;

/**
 * 测试类
 * @author xr
 * @Date 2024/5/10 10:54
 */

public class TestSql {
    public static void main(String[] args) throws SQLException {

        /*----------------------转换Array数组-----------------------*/
        // 创建SqlExecutor对象控制器,并传入连接对象
        SqlExecutor sqlExecutor = new SqlExecutor(Dbutils.getConnection());

        // 定义sql语句,[查询单条数据]
        String sql = "select * from user_info where u_name = ?";

        /* 将查询的结果转换成Array数组*/
        //1.创建Array策略
        ResultSetHandler<Object[]> arrayHandler = new ArrayHandler();

        //2.调用sqlExecutor工具类的executeQuery方法,传入sql语句和策略和具体参数
        Object[] objects = sqlExecutor.executeQuery(sql, arrayHandler, "xr");

        // 查看转换结果
        Arrays.stream(objects).forEach(System.out::println);

        System.out.println("-------------------------------转换数组完成------------------------------------");


        /*----------------------转换Array数组-----------------------*/
        // 创建SqlExecutor对象控制器,并传入连接对象
        sqlExecutor = new SqlExecutor(Dbutils.getConnection());

        // 定义sql语句,[查询单条数据]
        sql = "select * from user_info where u_name = ?";

        /* 将查询的结果转换成map集合*/
        // 1. 创建Map策略
        ResultSetHandler<Map<String,Object>> result = new MapHandler();

        //2.调用sqlExecutor工具类的executeQuery方法,传入sql语句和策略和具体参数
        Map<String, Object> map = sqlExecutor.executeQuery(sql, result, "xr");

        // 循环输出结果
        map.forEach((k,v)->{
            System.out.println("字段名:"+k+"---->字段值:"+v);
        });

    }
}
2.最后转换结果


【三】将结果集转换成Bean对象

将查询的结果转换成bean对象时解决难点:

        1.对象属性名称与数据库字段名称不一样

        2.如何将查询出来的值设置到对象属性中

        3.时间转换问题

解决方案:

        1.添加自定义注解,解决属性名称与数据库字段名称不一致

        2.通过反射的内省机制来设置对象属性值

        3.因为有多种时间类型,mysql版本8之前只有Date时间类型,而mysql8之后多了LocalDateTime时间类型

1.创建一个Cloumn注解【映射数据库名称】
package com.xr;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 映射数据库名称
 * @author xr
 * @Date 2024/5/11 9:37
 * @Retention 注解在运行时有效
 * @Target 注解作用范围
 */

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Column {

    /**
     * 数据库字段名
     */
    String name();
}

------------------------------------------------------------待更新------------------------------------------------------------

相关推荐

  1. 【JDBC】Apache DbUtils工具使用

    2024-05-11 16:06:10       32 阅读
  2. EasyExcel简单合并单元格数据工具

    2024-05-11 16:06:10       72 阅读
  3. springboot集成 mongodb以及mongodb简单工具

    2024-05-11 16:06:10       33 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-11 16:06:10       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-11 16:06:10       101 阅读
  3. 在Django里面运行非项目文件

    2024-05-11 16:06:10       82 阅读
  4. Python语言-面向对象

    2024-05-11 16:06:10       91 阅读

热门阅读

  1. nginx开启目录索引搭建文件服务器

    2024-05-11 16:06:10       36 阅读
  2. openssh升级最新脚本及问题处理

    2024-05-11 16:06:10       25 阅读
  3. VIM_beginner

    2024-05-11 16:06:10       28 阅读
  4. 用python写一个自动生成android开机动画的工具

    2024-05-11 16:06:10       35 阅读
  5. C语言中 #include<>与 include ““的区别

    2024-05-11 16:06:10       34 阅读
  6. 找第二大的数(分治法)

    2024-05-11 16:06:10       32 阅读
  7. 个人如何做股指期货交易?

    2024-05-11 16:06:10       37 阅读
  8. 间隔采样视频的代码

    2024-05-11 16:06:10       31 阅读
  9. 低方差过滤

    2024-05-11 16:06:10       33 阅读