DbUtil分析

分析一个最简单的框架流程

dbutil是我知的最简单的框架,分析它有利于了解框架的基础思路

select一个对象并返回是此框架最简单流程:

@Override
public Admin selectAdminByUsername(String name) {
    Admin admin = null;
    QueryRunner queryRunner = new QueryRunner();
    String sql = "select id,username,phone,password,salt from admin where username=?";
    Connection connection = JdbcUtils.getConnection();
    // todo BeanHandle???
    BeanHandler<Admin> beanHandler = new BeanHandler<Admin>(Admin.class);
    try {
        admin = queryRunner.query(connection, sql, beanHandler, name);
    } catch (SQLException e) {
        System.out.println("adminDaoImpl_e_104");
        e.printStackTrace();
    }
    return admin;
}

 

在以上代码段,创建了一个BeanHandler:BeanHandler<Admin> beanHandler = new BeanHandler<Admin>(Admin.class);

执行了sql:admin = queryRunner.query(connection, sql, beanHandler, name);

画图分析了sql执行的流程,以及此流程调用的method,是属于哪个类(BeanHandler的作用):

        执行的最终,是靠BeanProcessor的tobean方法

public <T> T toBean(ResultSet rs, Class<T> type) throws SQLException {
    PropertyDescriptor[] props = this.propertyDescriptors(type);
    ResultSetMetaData rsmd = rs.getMetaData();
    int[] columnToProperty = this.mapColumnsToProperties(rsmd, props);
    return this.createBean(rs, type, props, columnToProperty);
}
this.createBean如下:
private <T> T createBean(ResultSet rs, Class<T> type, PropertyDescriptor[] props, int[] columnToProperty) throws SQLException {
    T bean = this.newInstance(type);

    for(int i = 1; i < columnToProperty.length; ++i) {
        if (columnToProperty[i] != -1) {
            PropertyDescriptor prop = props[columnToProperty[i]];
            Class<?> propType = prop.getPropertyType();
            Object value = this.processColumn(rs, i, propType);
            if (propType != null && value == null && propType.isPrimitive()) {
                value = primitiveDefaults.get(propType);
            }

            this.callSetter(bean, prop, value);
        }
    }

    return bean;
}

断点调试:

每执行一次for循环:通过PropertyDescriptor prop,设置空参bean(反射instance创建)的一个子属性(根据rs)

最终返回处理好的bean

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
A、DBUtil2类代码如下: ```java import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class DBUtil2 { private static final String URL = "jdbc:mysql://localhost:3306/bookdb?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8"; private static final String USERNAME = "root"; private static final String PASSWORD = "123456"; static { try { Class.forName("com.mysql.cj.jdbc.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USERNAME, PASSWORD); } } ``` B、改造后的BookManager类的main函数代码如下: ```java import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Random; public class BookManager { private static final Random random = new Random(); public static void addBook(String name, String author, double price) { String sql = "INSERT INTO book (name, author, price) VALUES (?, ?, ?)"; try (Connection conn = DBUtil2.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, name); pstmt.setString(2, author); pstmt.setDouble(3, price); pstmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } public static void main(String[] args) { long startTime = System.currentTimeMillis(); for (int i = 1; i <= 1000; i++) { String name = "book" + i; String author = "author" + i; double price = random.nextDouble() * 100; addBook(name, author, price); } long endTime = System.currentTimeMillis(); System.out.println("运行时间:" + (endTime - startTime) + "ms"); } } ``` C、使用DBUtilDBUtil2获取数据库连接时,main函数的执行耗时: 使用DBUtil获取数据库连接的执行耗时为:12993ms 使用DBUtil2获取数据库连接的执行耗时为:11780ms 可以看出,使用DBUtil2获取数据库连接的耗时比使用DBUtil获取数据库连接的耗时少,这是因为DBUtil2中使用了连接池技术,避免了重复创建和销毁连接的开销,提高了程序的性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值