JDBC学习笔记02

JDBC学习笔记02,第1张

JDBC学习笔记02

目录
  • JDBC学习笔记02
    • 数据库连接池
      • 传统获取Connection问题分析
      • 基本介绍
      • 数据库连接池种类
      • c3p0使用
      • Druid(德鲁伊)应用实例
        • 配置文件
        • 封装成工具类
        • 测试
    • Apache-DBUtils
      • 分析一个问题
      • 土方法解决
      • 基本介绍
      • 应用实例
    • BasicDao-DAO和增删改查通用方法
      • 基本说明
      • 应用实例

数据库连接池 传统获取Connection问题分析
  1. 传统的JDBC数据库连接使用 DriverManager来获取,每次向数据库建立连接的时候都要将Connection 加载到内存中,再验证IP地址,用户名和密码(0.05S~1s时间)。需要数据库连接的时候,就向数据库要求一个,频繁的进行数据库连接 *** 作将占用很多的系统资源,容易造成服务器崩溃。

  2. 每一次数据库连接,使用完后都得断开,如果程序出现异常而未能关闭,将导致数据库内存泄 漏,最终将导致重启数据库。

  3. 传统获取连接的方式,不能控制创建的连接数量,如连接过多,也可能导致内存泄漏,MySQL崩溃。

  4. 解决传统开发中的数据库连接问题,可以采用数据库连接池技术(connection pool)。

基本介绍
  1. 预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。

  2. 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。

  3. 当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中

数据库连接池种类
  1. JDBC的数据库连接池使用javax.sql.DataSource来表示,DataSource只是一个接口,该接口通常由第三方提供实现

  2. C3PO数据库连接池,速度相对较慢,稳定性不错(hibernate, spring)

  3. DBCP数据库连接池,速度相对c3p0较快,但不稳定

  4. Proxool数据库连接池,有监控连接池状态的功能,稳定性较c3p0差一点

  5. BoneCP 数据库连接池,速度快

  6. Druid(德鲁伊)是阿里提供的数据库连接池,集DBCP、C3P0、Proxool优点于一身的数据库连接池

c3p0使用

方式1:

 //方式1:相关参数,在程序中指定user,url,password
        ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
        //通过配置文件获取相关的信息
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\mysql.properties"));
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        String url = properties.getProperty("url");
        String driver = properties.getProperty("driver");

        //给数据源comboPooledDataSource设置相关的参数
        //连接管理是由comboPooledDataSource来管理
        comboPooledDataSource.setDriverClass(driver);
        comboPooledDataSource.setJdbcUrl(url);
        comboPooledDataSource.setUser(user);
        comboPooledDataSource.setPassword(password);
        //设置初始化连接数
        comboPooledDataSource.setInitialPoolSize(10);
        //最大连接数
        comboPooledDataSource.setMaxPoolSize(50);
        long start = System.currentTimeMillis();
        for (int i = 0; i < 5000; i++) {
            Connection connection = comboPooledDataSource.getConnection();//从DataSource方法实现的
            System.out.println("连接成功");
            connection.close();//回收
        }
        long end = System.currentTimeMillis();
        System.out.println(end-start);

方式2:

c3p0-config.xml

<c3p0-config>
    
  <named-config name="purplesky">

  <property name="driverClass">com.mysql.cj.jdbc.Driverproperty>
  
   <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/db02property>
  
      <property name="user">rootproperty>
      
   <property name="password">123456property>
   
    <property name="acquireIncrement">5property>
    
    <property name="initialPoolSize">10property>
    
    <property name="minPoolSize">5property>
   
    <property name="maxPoolSize">50property>

   
    <property name="maxStatements">5property> 
    
    
    <property name="maxStatementsPerConnection">2property>
  named-config>
c3p0-config>
//方式2.使用配置文件的模板
public void testC3P0_02() throws SQLException {
    ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("purplesky");
    Connection connection = comboPooledDataSource.getConnection();
    System.out.println("连接成功");
    connection.close();
}
Druid(德鲁伊)应用实例 配置文件

druid.properties

#key=value
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/db02?rewriteBatchedStatements=true
username=root
password=123456
#initial connection Size
initialSize=10
#min idle connection size
minIdle=5
#max active connection size
maxActive=50
#max wait time (5000 mil seconds)
maxWait=5000
//1.加入jar包
//2.加入配置文件druid.properties,放到src目录下
//3.创建Properties对象,读取配置文件
Properties properties = new Properties();
properties.load(new FileInputStream("src\druid.properties"));
//4.创建一个指定参数的数据库连接池
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
Connection connection = dataSource.getConnection();
System.out.println("连接成功");
connection.close();
封装成工具类

JDBCUtilsByDruid

public class JDBCUtilsByDruid {
    private static DataSource ds;
    //在静态代码块完成ds初始化
    static {
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream("src\druid.properties"));
            ds = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static Connection getConnection(){
        try {
            return ds.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    //放回到连接池
    public static void close(ResultSet set, Statement statement, Connection connection) {
        try {
            if (set != null) {
                set.close();
            }
            if (statement != null) {
                statement.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}
测试
@Test
public void testSelect() {
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    ResultSet set = null;
    String sql = "select * from actor where id = ?";

    try {
        connection = JDBCUtilsByDruid.getConnection();
        System.out.println(connection.getClass());
        preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setInt(1,2);
        set = preparedStatement.executeQuery();
        while (set.next()) {
            int id = set.getInt("id");
            String name = set.getString("name");
            String sex = set.getString("sex");
            Date borndate = set.getDate("borndate");
            String phone = set.getString("phone");
            System.out.println(id + "\t" + name + "\t" + sex + "\t" + borndate + "\t" + phone);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        JDBCUtilsByDruid.close(set, preparedStatement, connection);
    }
}
@Test
public void testDML() {
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    String sql = "update actor set name = ? where id =?";

    try {
        connection = JDBCUtilsByDruid.getConnection();
        preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setString(1, "周星驰");
        preparedStatement.setInt(2, 2);
        preparedStatement.executeUpdate();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        JDBCUtilsByDruid.close(null, preparedStatement, connection);
    }
}
Apache-DBUtils 分析一个问题
  1. 关闭connection后,resultSet 结果集无法使用
  2. resultSet不利于数据的管理
土方法解决
public ArrayList<Actor> testSelectToArrayList() {
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    ResultSet set = null;
    String sql = "select * from actor where id = ?";
    ArrayList<Actor> list = new ArrayList<>();
    try {
        connection = JDBCUtilsByDruid.getConnection();
        System.out.println(connection.getClass());
        preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setInt(1,2);
        set = preparedStatement.executeQuery();
        while (set.next()) {
            int id = set.getInt("id");
            String name = set.getString("name");
            String sex = set.getString("sex");
            Date borndate = set.getDate("borndate");
            String phone = set.getString("phone");
            list.add(new Actor(id,name,sex,borndate,phone));
        }
        System.out.println(list);
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        JDBCUtilsByDruid.close(set, preparedStatement, connection);
    }
    return list;
}
基本介绍
  1. commons-dbutils是Apache组织提供的一个开源 JDBC工具类库,它是对JDBC的封装,使用dbutils能极大简化jdbc编码的工作量。
  2. QueryRunner类:该类封装了SQL的执行,是线程安全的。可以实现增、删、改、查、批处理使用
  3. QueryRunner类实现查询
  4. ResultSetHandler接口:该接口用于处理java.sql.ResultSet,将数据按要求转换为另一种形式
ArrayHandler:把结果集中的第一行数据转成对象数组。
ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。
BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里
ColumnListHandler:将结果集中某一列的数据存放到List中。
KeyedHandler(name):将结果集中的每行数据都封装到Map里,再把这些map再存到一个map里,其key为指定的key。
MapHandler: 将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
应用实例

使用DBUtils+数据库连接池(德鲁伊)方式,完成对表的crud

date –> Date或String
char,varchar –> String

@Test
public void testQueryMany() throws SQLException {
    //1.得到连接druid
    Connection connection = JDBCUtilsByDruid.getConnection();
    //2.使用DBUtils类和接口,先引入DBUtils相关的jar
    //3.创建QueryRunner
    QueryRunner queryRunner = new QueryRunner();
    //4.执行相关的方法,返回ArrayList结果集
    //query方法执行sql语句,得到resultSet--封装到ArrayList
    //返回集合
    //connection连接
    //sql语句
    //new BeanListHandler<>(Actor.class):在将resultSet-->Actor对象-->封装到ArrayList
    //底层使用反射机制去获取Actor类的属性,然后进行封装
    //1是传给?的,可以有多个值,是可变参数
    //底层得到的resultSet会在query关闭,关闭PreparedStatement
    //String sql = "select id,name,sex,phone,borndate from actor where id >= ?";
    String sql = "select * from actor where id >= ?";
    List<Actor> list = queryRunner.query(connection, sql, new BeanListHandler<>(Actor.class), 1);
    for (Actor actor : list) {
        System.out.println(actor);
    }
    JDBCUtilsByDruid.close(null, null, connection);
}

@Test
//单行记录
public void testQuerySingle() throws SQLException {
    Connection connection = JDBCUtilsByDruid.getConnection();
    QueryRunner queryRunner = new QueryRunner();
    String sql = "select id,name,sex,phone from actor where id = ?";
    Actor actor = queryRunner.query(connection, sql, new BeanHandler<>(Actor.class), 2);
    System.out.println(actor);
    JDBCUtilsByDruid.close(null, null, connection);
}

@Test
//apache-dbUtils+druid完成查询结果是单行单列的情况
public void testScalar() throws SQLException {
    Connection connection = JDBCUtilsByDruid.getConnection();
    QueryRunner queryRunner = new QueryRunner();
    String sql = "select name from actor where id = ?";
    Object obj = queryRunner.query(connection, sql, new ScalarHandler(), 2);
    System.out.println(obj);

    JDBCUtilsByDruid.close(null, null, connection);
}

@Test
public void testDML() throws SQLException {
    Connection connection = JDBCUtilsByDruid.getConnection();
    QueryRunner queryRunner = new QueryRunner();
    //String sql = "update actor set name = ? where id = ?";
    //String sql = "insert into actor values(null,'林青霞','女','1966-10-10','116')";
    String sql = "insert into actor values(null, ?, ?, ?, ?)";
    //String sql = "delete from actor where id = ?)";
    //返回值是受影响行数,失败0
    //int affectedRow = queryRunner.update(connection, sql, "张三丰", 4);
    int affectedRow = queryRunner.update(connection, sql, "林青霞", "女", "1966-10-10", "116");
    if (affectedRow != 0) {
        System.out.println("成功");
    } else {
        System.out.println("没有影响到表");
    }
}
BasicDao-DAO和增删改查通用方法

apache-dbutils+Druid简化了JDBC开发,但还有不足:

  1. SQL语句是固定,不能通过参数传入,通用性不好,需要进行改进,更方便执行增删改查
  2. 对于select *** 作,如果有返回值,返回类型不能固定,需要使用泛型
  3. 将来的表很多,业务需求复杂,不可能只靠一个Java类完成
  4. 引出 BasicDAO
基本说明
  1. DAO: data access object数据访问对象
  2. 这样的通用类,称为BasicDao,是专门和数据库交互的,即完成对数据库(表)的crud *** 作。在BaiscDao 的基础上,实现一张表对应一个Dao,更好的完成功能,比如 Customer表-customer.java类(javabean)-CustomerDao.java
应用实例
  1. utils
  2. domain
  3. dao
  4. test

JDBCUtilsByDruid

public class JDBCUtilsByDruid {
    private static DataSource ds;
    //在静态代码块完成ds初始化
    static {
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream("src\druid.properties"));
            ds = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public static Connection getConnection(){
        try {
            return ds.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    //放回到连接池
    public static void close(ResultSet set, Statement statement, Connection connection) {
        try {
            if (set != null) {
                set.close();
            }
            if (statement != null) {
                statement.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

BasicDAO

/**
 * @author purplesky
 * 其他DAO的父类
 */
public class BasicDAO<T> {
    private QueryRunner qr = new QueryRunner();

    //开发通用的dml方法,针对任意的表
    public int update(String sql, Object... parameters) {
        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection();
            int update = qr.update(connection, sql, parameters);
            return update;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtilsByDruid.close(null, null, connection);
        }
    }

    //返回多个对象,多行查询结果
    public List<T> queryMulti(String sql, Class<T> clazz, Object... parameters) {
        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection();
            return qr.query(connection, sql, new BeanListHandler<T>(clazz), parameters);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtilsByDruid.close(null, null, connection);
        }
    }
    //单行结果
    public T querySingle(String sql, Class<T> clazz, Object... parameters) {
        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection();
            return qr.query(connection, sql, new BeanHandler<T>(clazz), parameters);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtilsByDruid.close(null, null, connection);
        }
    }

    //返回单值的方法
    public Object queryScalar(String sql, Object... parameters) {
        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection();
            return qr.query(connection, sql, new ScalarHandler(), parameters);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtilsByDruid.close(null, null, connection);
        }
    }

}

ActorDAO

public class ActorDAO extends BasicDAO<Actor> {
    //1.有BasicDAO的方法
    //2.也可以编写特有的方法
}

测试

public class TestDAO_ {
    @Test
    public void testActorDAO() {
        ActorDAO actorDAO = new ActorDAO();
        List<Actor> actors = actorDAO.queryMulti("select id,name,sex,phone from actor where id >= ?", Actor.class, 1);
        for (Actor actor : actors) {
            System.out.println(actor);
        }
        //查询单行记录
        Actor actor = actorDAO.querySingle("select id,name,sex,phone from actor where id = ?", Actor.class, 1);
        System.out.println(actor);
        //查询单行单列
        Object o = actorDAO.queryScalar("select name from actor where id = ?", 6);
        System.out.println(o);
        //dml
        int update = actorDAO.update("insert into actor values(null, ?, ?, ?, ?)", "张无忌", "男", "2000-11-11", "999");
        System.out.println(update > 0 ? "执行成功":"没有影响表");
    }

}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/739877.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-28
下一篇 2022-04-28

发表评论

登录后才能评论

评论列表(0条)

保存