• java _JDBC 开发


    目录

    一.封装JDBCUtiles

    二.事务

     三.批处理

    四.数据库连接池

      C3P0

    Druidf(德鲁伊)阿里

    五.Apache-DBUtiles

    六.Apache-DBUtils

    七.DAO 和增删改查 通用方法 - BasicDao

    一.封装JDBCUtiles

    说明:在jdbc操作中,获取连接和释放资源,是经常使用到,可以将其封装JDBC连接的,工具类JDBCUtils

    1. package com.tianedu.jdbc.utils;
    2. import java.io.FileInputStream;
    3. import java.io.IOException;
    4. import java.sql.*;
    5. import java.util.Properties;
    6. /**
    7. * @author tian
    8. * 这是一个工具类 完成MySQL的连接和关闭资源
    9. *
    10. */
    11. public class JDBCUtils {
    12. // 定义相关的属性(4个),因为只需要一份,我们做出Static
    13. private static String user; // 用户名
    14. private static String password; // 密码
    15. private static String url; //url
    16. private static String driver; //驱动名称
    17. //在static 代码块去初始化
    18. static {
    19. Properties properties = new Properties();
    20. try {
    21. properties.load(new FileInputStream("src\\mysql.properties"));
    22. //读取相关的属性值
    23. user = properties.getProperty("user");
    24. password = properties.getProperty("password");
    25. url = properties.getProperty("url");
    26. driver = properties.getProperty("driver");
    27. } catch (IOException e) {
    28. //在实际开发中,我们可以这样处理
    29. //1.将编译异常转换成 运行异常
    30. //2.这里调用者可以选择捕获该异常,也可以选择默认异常,比较方便。
    31. throw new RuntimeException(e);
    32. // e.printStackTrace();
    33. }
    34. }
    35. // 连接数据库 返回一个Connection
    36. public static Connection getConnection(){
    37. try {
    38. return DriverManager.getConnection(url,user,password);
    39. } catch (SQLException e) {
    40. // throwables.printStackTrace();
    41. //将编译异常转换成 运行异常,调用者可以捕获该异常,也可以选择默认处理该异常,比较方便
    42. throw new RuntimeException(e);
    43. }
    44. }
    45. //关闭相关的资源
    46. /*
    47. 1.ResultSet 结果集
    48. 2.Statement 或者 PreparedStatement
    49. 3.关闭Connection
    50. 4.如果需要关闭资源,就传入对象,否则传入null
    51. */
    52. public static void close(ResultSet set, Statement statement,Connection connection){
    53. //判断是否为null
    54. try {
    55. if(set != null){
    56. set.close();
    57. }
    58. if (statement != null) {
    59. statement.close();
    60. }
    61. if (connection != null){
    62. connection.close();
    63. }
    64. } catch (SQLException e) {
    65. //将编译异常转成运行异常抛出
    66. throw new RuntimeException(e);
    67. }
    68. }
    69. }

    使用工具类 JDBCUtils

    1. package com.tianedu.jdbc.utils;
    2. import org.junit.Test;
    3. import java.sql.*;
    4. /**
    5. * @author tian
    6. * 该类演示如何使用JDBCUtile工具类完成DML 和 select
    7. *
    8. *
    9. */
    10. public class JDBCUtils_Use {
    11. public static void main(String[] args) {
    12. //测试
    13. }
    14. @Test
    15. public void testSelect(){
    16. //1.得到连接
    17. Connection connection = null;
    18. //2.组织一个sql
    19. String sql = "select * from actor where id = ?";
    20. //测试 select
    21. PreparedStatement preparedStatement = null;
    22. ResultSet set = null;
    23. //3.创建PrepareStatement 对象
    24. try {
    25. connection = JDBCUtils.getConnection();
    26. preparedStatement = connection.prepareStatement(sql);
    27. preparedStatement.setInt(1,2); // 给问号赋值
    28. //执行 得到结果集
    29. set = preparedStatement.executeQuery();
    30. //遍历该结果集
    31. while(set.next()){
    32. int id = set.getInt("id");
    33. String name = set.getString("name");
    34. String sex = set.getString("sex");
    35. Date borndate = set.getDate("borndate");
    36. String phone = set.getString("phone");
    37. System.out.println(id + "\t" + name + "\t" + sex + "\t" + borndate + "\t" + phone );
    38. }
    39. } catch (SQLException e) {
    40. e.printStackTrace();
    41. } finally {
    42. //关闭资源
    43. JDBCUtils.close(set,preparedStatement,connection);
    44. }
    45. }
    46. @Test
    47. public void testDML() {
    48. // insert update delete
    49. //1.得到连接
    50. Connection connection = null;
    51. //2.组织一个sql语句
    52. String sql = "update actor set name = ? where id = ?";
    53. PreparedStatement preparedStatement = null;
    54. //3.创建一个PreparedStatement 对象
    55. try {
    56. connection = JDBCUtils.getConnection();
    57. preparedStatement = connection.prepareStatement(sql);
    58. // 给占位符 赋值
    59. preparedStatement.setString(1,"周星驰");
    60. preparedStatement.setInt(2,1);
    61. //执行
    62. preparedStatement.executeUpdate();
    63. } catch (SQLException e) {
    64. e.printStackTrace();
    65. } finally {
    66. //关闭资源
    67. JDBCUtils.close(null,preparedStatement,connection);
    68. }
    69. }
    70. }

    二.事务

    应用实例,模拟经典的转账业务

    • 不使用事可能出现的问题模拟,模拟经典的转账业务 
    1. package com.tianedu.jdbc.transaction_;
    2. import com.tianedu.jdbc.utils.JDBCUtils;
    3. import org.junit.Test;
    4. import java.sql.Connection;
    5. import java.sql.PreparedStatement;
    6. import java.sql.SQLException;
    7. /**
    8. * @author tian
    9. * 演示在JDBC中如何使用事务
    10. */
    11. public class Transaction_ {
    12. @Test
    13. public void noTransaction_(){
    14. //操作转账的业务
    15. //1.得到连接
    16. Connection connection = null;
    17. //2.组织一个sql语句
    18. String sql = "update account set balance = balance -100 where id = 1";
    19. String sql2 = "update account set balance = balance + 100 where id = 2";
    20. // 创建 PreparedStatement 对象
    21. PreparedStatement preparedStatement = null;
    22. try {
    23. connection = JDBCUtils.getConnection();
    24. preparedStatement = connection.prepareStatement(sql);
    25. preparedStatement.executeUpdate(); // 执行第一条sql语句
    26. int i = 1/0; // 抛出异常 下面的代码不在执行
    27. preparedStatement = connection.prepareStatement(sql2);
    28. preparedStatement.executeUpdate(); // 执行第二条 sql2 语句
    29. } catch (SQLException e) {
    30. e.printStackTrace();
    31. } finally {
    32. JDBCUtils.close(null,preparedStatement,connection);
    33. }
    34. }
    35. // 事务来解决
    36. @Test
    37. public void useTransaction() {
    38. //1. 连接事务
    39. Connection connection = null;
    40. //2.组织sql
    41. String sql = "update account set balance = balance -100 where id = 1";
    42. String sql2 = "update account set balance = balance + 100 where id = 2";
    43. //3.创建PrepareStatement 对象
    44. PreparedStatement preparedStatement = null;
    45. try {
    46. connection = JDBCUtils.getConnection();
    47. // 将connection 设置为不自动提交
    48. connection.setAutoCommit(false); //相当于开始事务
    49. preparedStatement = connection.prepareStatement(sql);
    50. preparedStatement.executeUpdate(); // 执行sql
    51. preparedStatement = connection.prepareStatement(sql2);
    52. preparedStatement.executeUpdate(); //执行sql2
    53. //这里提交事务
    54. connection.commit();
    55. } catch (SQLException e) {
    56. //这里我们可以进行回滚,即撤销执行的sql
    57. //默认回滚到事务开始的状态
    58. System.out.println("执行发生了异常,撤销执行的sql");
    59. try {
    60. connection.rollback();
    61. } catch (SQLException throwables) {
    62. throwables.printStackTrace();
    63. } finally {
    64. }
    65. e.printStackTrace();
    66. } finally {
    67. //关闭资源
    68. JDBCUtils.close(null,preparedStatement,connection);
    69. }
    70. }
    71. }

     三.批处理

    • 当需要成批插入或者更新记录时。可以采用java 的批处理更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比较单独提交处理更有效率。
    • JDBC的批处理语句包括下面方法:addBatch() 添加需要批处理的sql语句或参数       executeBatch() 执行批批量处理的语句                                                                                        clearBatch() 清空批处理包的语句
    • JDBC连接MySQL时,如果需要使用批处理功能,请在url中加参数? rewriteBatchedStatements = true
    • 批处理往往和PreparedStatement 一起搭配使用,可以减少编译次数,有减少运行次数,效率大大提高 
    • 如果要批量处理  需要修改 配置文件 jdbc.properties url=jdbc:mysql://localhost:3306/数据库? rewriteBatchedStatements = true
    1. package com.tianedu.jdbc.batch_;
    2. import com.tianedu.jdbc.utils.JDBCUtils;
    3. import org.junit.Test;
    4. import java.sql.Connection;
    5. import java.sql.PreparedStatement;
    6. import java.sql.SQLException;
    7. /**
    8. * @author tian
    9. * 演示Java的批处理
    10. */
    11. public class Batch_ {
    12. @Test
    13. //传统的方法添五千条数数据到admin2
    14. public void noBatch() throws SQLException {
    15. //得到连接
    16. Connection connection = JDBCUtils.getConnection();
    17. //sql
    18. String sql = "insert into admin2 values(null,?,?)";
    19. //使用connect创建一个prepareStatement()
    20. PreparedStatement preparedStatement = connection.prepareStatement(sql);
    21. System.out.println("开始时间");
    22. long start = System.currentTimeMillis(); // 开始时间
    23. for (int i = 0; i<= 5000; i++){
    24. preparedStatement.setString(1,"jack"+i);
    25. preparedStatement.setString(2,"666");
    26. preparedStatement.executeUpdate();
    27. }
    28. long end = System.currentTimeMillis();
    29. System.out.println("传统的方式 耗时="+ (end - start));
    30. //关闭连接
    31. JDBCUtils.close(null,preparedStatement,connection);
    32. }
    33. //使用批量处理方式添加数据
    34. @Test
    35. public void batch() throws SQLException {
    36. //获得连接
    37. Connection connection = JDBCUtils.getConnection();
    38. //写sql语句
    39. String sql = "insert into admin3 values(null,?,?)";
    40. //获得preparedStatement
    41. PreparedStatement preparedStatement = connection.prepareStatement(sql);
    42. System.out.println("开始执行");
    43. long start = System.currentTimeMillis();
    44. for (int i = 0; i < 5000; i++) {
    45. preparedStatement.setString(1,"tom+i");
    46. preparedStatement.setString(2,"777");
    47. // preparedStatement.executeUpdate(); // 执行
    48. //将sql语句加入到批处理包中
    49. preparedStatement.addBatch();
    50. /*
    51. 1.第一创建ArrayList —— elementDate => object[]
    52. 2.elementDate => object[] 就会存放我们预处理的sql语句
    53. 3.当elementDate满后,就按照1.5扩容
    54. 4.当添加到指定的值后就执行批量处理
    55. 5.批量处理会减少发生sql 语句的网络开销,而且减少编码的次数,因此效率高
    56. */
    57. //当有一千条记录时候在批量执行
    58. if ((i+1) % 1000 == 0) { // 说明满一千条 批量执行
    59. preparedStatement.executeBatch();
    60. //清空一把
    61. preparedStatement.clearBatch();
    62. }
    63. }
    64. long end = System.currentTimeMillis();
    65. System.out.println("批量执行方式 耗时 = " + (end - start));
    66. //关闭连接
    67. JDBCUtils.close(null,preparedStatement,connection);
    68. }
    69. }

    四.数据库连接池

    传统获取Connection问题分析

    1. 传统的JDBC数据库连接使用 DriverManager 来获取,每次向数据库建立连接的时候都要将connection 加载到内存中,在验证ip地址,用户名和密码(0.05s~1s时间)需要数据库连接的时候,就向数据库要求一个,频繁的进行数据库连接操i在将占用很多的数据系统资源,容易造成服务器崩溃。
    2. 每一次数据库连接,使用完成后都得断开,如果程序出现异常而为关闭,将导致数据库内存泄漏,最终将导致重启数据库
    3. 传统获取连接的方式,不能控制创建的连接数量,如来连接过多,也可能导致内存泄露,mysql奔溃
    4. 解决传统数据库中的数据库连接问题,可以采用数据库连接池技术(connection pool)

    数据库连接池基本介绍

    1. 预先在缓冲区中放入一数量的连接,当需要建立数据库连接时,只需从"缓冲池"中取出一个,使用完毕之后在放回去
    2. 数据库连接池负责分配,管理和释放数据库连接,它允许程序重复使用一个现有的数据库连接,而不是重新建立一个
    3. 当应用程序向连接池请求将被加入到等待队列中  

    数据库连接池种类

    1. JDBC的数据库连接池使用java.x.sql.DataSource 来表示,DataSource只是一个接口,该接口通常由第三方提高实现  会提供相应的jar 包
    2. C3p0 数据库连接池,速度相对较慢,稳定性不错
    3. DBCP数据库连接驰,速度相对c3p0较快,但不稳定
    4. Proxool数据库连接池,有监控连接池状态的功能,稳定性较c3p0差一点
    5. BoneCP 数据库连接池,速度快
    6. Druid(德鲁伊) 是阿里提供的数据库连接池,集DBCP,C3P0吗,Proxool优点于一深的数据库连接池
      C3P0
    1. package com.tianedu.jdbc.datasource;
    2. import com.mchange.v2.c3p0.ComboPooledDataSource;
    3. import org.junit.Test;
    4. import java.io.FileInputStream;
    5. import java.sql.Connection;
    6. import java.sql.SQLException;
    7. import java.util.Properties;
    8. /**
    9. * @author tian
    10. *
    11. * 演示c3p0的使用
    12. */
    13. public class C3P0_ {
    14. @Test
    15. //方式1 相关的参数在程序中指定 user url password 等
    16. public void testC3p0_01() throws Exception {
    17. //1.创建一个数据源对象
    18. ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
    19. //2.通过配置文件获取相关信息 MySQL.properties 获取相关的连接信息
    20. Properties properties = new Properties();
    21. properties.load(new FileInputStream("src\\mysql.properties"));
    22. //获取相关的属性
    23. String user = properties.getProperty("user");
    24. String password = properties.getProperty("password");
    25. String url = properties.getProperty("url");
    26. String driver = properties.getProperty("driver");
    27. //给数据源 comboPooledDateSource 设置相关的参数
    28. //连接的管理是由 comboPooledDataSource帮我们管理的
    29. comboPooledDataSource.setDriverClass(driver);
    30. comboPooledDataSource.setJdbcUrl(url);
    31. comboPooledDataSource.setUser(user);
    32. comboPooledDataSource.setPassword(password);
    33. // 设置初始化连接数
    34. comboPooledDataSource.setInitialPoolSize(10);
    35. //最大连接数
    36. comboPooledDataSource.setMaxPoolSize(50);
    37. //测试连接池的效率
    38. long start = System.currentTimeMillis();
    39. for (int i = 0; i < 5000; i++) {
    40. Connection connection = comboPooledDataSource.getConnection();//这个方法是从 DateSource 接口实现的
    41. // System.out.println("连接成功");
    42. connection.close();
    43. }
    44. long end = System.currentTimeMillis();
    45. System.out.println(end - start);
    46. }
    47. // 方式2 使用配置文件模板来完成
    48. // 将c3p0 拷贝到 src 目录下
    49. //该文件指定了 连接数据库和连接池的线管参数
    50. @Test
    51. public void testC3PO_02() throws SQLException {
    52. //使用配置文件
    53. ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("tian");
    54. long start = System.currentTimeMillis();
    55. for (int i = 0; i < 5000; i++) {
    56. Connection connection = comboPooledDataSource.getConnection();
    57. connection.close();
    58. }
    59. long end = System.currentTimeMillis();
    60. System.out.println(end -start);
    61. }
    62. }
    Druidf(德鲁伊)阿里
    1. package com.tianedu.jdbc.datasource;
    2. import com.alibaba.druid.pool.DruidDataSourceFactory;
    3. import org.junit.Test;
    4. import javax.sql.DataSource;
    5. import java.io.FileInputStream;
    6. import java.sql.Connection;
    7. import java.util.Properties;
    8. /**
    9. * @author tian
    10. */
    11. public class Druid_ {
    12. @Test
    13. //测试德鲁伊的使用
    14. public void testDruid() throws Exception {
    15. // 1.加入Druid jar 包
    16. // 加入配置文件 将该文件拷贝到src目录下 druid.properties
    17. //3.创建一个 properties 对象,用来读取配置文件
    18. Properties properties = new Properties();
    19. properties.load(new FileInputStream("src\\druid.properties"));
    20. //4.创建一个指定参数的数据库连接池,德鲁伊的连接池
    21. DataSource dataSource =
    22. DruidDataSourceFactory.createDataSource(properties);
    23. //拿到连接
    24. Connection connection = dataSource.getConnection();
    25. System.out.println("连接成功");
    26. connection.close();
    27. }
    28. }

    //创建德鲁伊数据库连接池

    1. package com.tianedu.jdbc.datasource;
    2. import com.alibaba.druid.pool.DruidDataSourceFactory;
    3. import javax.sql.DataSource;
    4. import java.io.FileInputStream;
    5. import java.sql.Connection;
    6. import java.sql.ResultSet;
    7. import java.sql.SQLException;
    8. import java.sql.Statement;
    9. import java.util.Properties;
    10. /**
    11. * @author tian
    12. * 基于德鲁伊数据库池连接的工具类
    13. */
    14. public class JDBCUtilsByDruid {
    15. private static DataSource ds;
    16. //在静态代码块完成ds 的初始化
    17. static {
    18. Properties properties = new Properties();
    19. try {
    20. properties.load(new FileInputStream("src:druid.properties"));
    21. ds = DruidDataSourceFactory.createDataSource(properties);
    22. } catch (Exception e) {
    23. e.printStackTrace();
    24. }
    25. }
    26. // 编写getConnection方法
    27. public static Connection getConnection() throws SQLException {
    28. return ds.getConnection();
    29. }
    30. //关闭连接 是将连接放回到连接池中,close 不是真的断掉连接
    31. //而是把使用的Connection对象放回到连接池
    32. public static void close(ResultSet resultSet, Statement statement,Connection connection){
    33. try {
    34. if (resultSet != null){
    35. resultSet.close();
    36. }
    37. if (statement != null){
    38. statement.close();
    39. }
    40. if (connection != null){
    41. connection.close();
    42. }
    43. } catch (SQLException e) {
    44. throw new RuntimeException(e);
    45. }
    46. }
    47. }
    1. package com.tianedu.jdbc.datasource;
    2. import com.alibaba.druid.pool.DruidDataSourceFactory;
    3. import javax.sql.DataSource;
    4. import java.io.FileInputStream;
    5. import java.sql.Connection;
    6. import java.sql.ResultSet;
    7. import java.sql.SQLException;
    8. import java.sql.Statement;
    9. import java.util.Properties;
    10. /**
    11. * @author tian
    12. * 基于德鲁伊数据库池连接的工具类
    13. */
    14. public class JDBCUtilsByDruid {
    15. private static DataSource ds;
    16. //在静态代码块完成ds 的初始化
    17. static {
    18. Properties properties = new Properties();
    19. try {
    20. properties.load(new FileInputStream("src\\druid.properties"));
    21. ds = DruidDataSourceFactory.createDataSource(properties);
    22. } catch (Exception e) {
    23. e.printStackTrace();
    24. }
    25. }
    26. // 编写getConnection方法
    27. public static Connection getConnection() throws SQLException {
    28. return ds.getConnection();
    29. }
    30. //关闭连接 是将连接放回到连接池中,close 不是真的断掉连接
    31. //而是把使用的Connection对象放回到连接池
    32. public static void close(ResultSet resultSet, Statement statement,Connection connection){
    33. try {
    34. if (resultSet != null){
    35. resultSet.close();
    36. }
    37. if (statement != null){
    38. statement.close();
    39. }
    40. if (connection != null){
    41. connection.close();
    42. }
    43. } catch (SQLException e) {
    44. throw new RuntimeException(e);
    45. }
    46. }
    47. }
    1. package com.tianedu.jdbc.datasource;
    2. import org.junit.Test;
    3. import java.sql.*;
    4. /**
    5. * @author tian
    6. */
    7. public class JDBCUtilsByDruid_USE {
    8. @Test
    9. public void testSelect(){
    10. System.out.println("使用德鲁伊的方式完成");
    11. // 1.得到连接
    12. Connection connection = null;
    13. //2.组织一个sql
    14. String sql = "select * from actor where id = ?";
    15. PreparedStatement preparedStatement = null;
    16. ResultSet set = null;
    17. //3.创建PreparedStatement 对象
    18. try {
    19. connection = JDBCUtilsByDruid.getConnection();
    20. preparedStatement = connection.prepareStatement(sql);
    21. preparedStatement.setInt(1,5);
    22. set = preparedStatement.executeQuery();
    23. //遍历该结果集
    24. while (set.next()){
    25. int id = set.getInt("id");
    26. String name = set.getString("name");
    27. String sex = set.getString("sex");
    28. Date borndate = set.getDate("brondate");
    29. String phone = set.getString("phone");
    30. System.out.println(id + "\t" + name + "\t" + sex + "\t" + borndate + "\t" + phone );
    31. }
    32. } catch (SQLException e){
    33. e.printStackTrace();
    34. }finally {
    35. //关闭资源
    36. JDBCUtilsByDruid.close(set,preparedStatement,connection);
    37. }
    38. }
    39. }

    五.Apache-DBUtiles

    • 关闭connection 后,resultSet 结果无法使用
    • resultSet 不利于数据的管理
    • 示意图

     使用土方法来解决  来完成分装

    1. package com.tianedu.jdbc.datasource;
    2. import org.junit.Test;
    3. import java.sql.*;
    4. import java.util.ArrayList;
    5. /**
    6. * @author tian
    7. */
    8. @SuppressWarnings({"all"})
    9. public class JDBCUtilsByDruid_USE {
    10. @Test
    11. public void testSelect(){
    12. System.out.println("使用德鲁伊的方式完成");
    13. // 1.得到连接
    14. Connection connection = null;
    15. //2.组织一个sql
    16. String sql = "select * from actor where id >= ?";
    17. PreparedStatement preparedStatement = null;
    18. ResultSet set = null;
    19. //3.创建PreparedStatement 对象
    20. try {
    21. connection = JDBCUtilsByDruid.getConnection();
    22. preparedStatement = connection.prepareStatement(sql);
    23. preparedStatement.setInt(1,1);
    24. set = preparedStatement.executeQuery();
    25. // connection.close();
    26. //遍历该结果集
    27. while (set.next()){
    28. int id = set.getInt("id");
    29. String name = set.getString("name"); //getName()
    30. String sex = set.getString("sex");
    31. Date borndate = set.getDate("borndate");
    32. String phone = set.getString("phone");
    33. System.out.println(id + "\t" + name + "\t" + sex + "\t" + borndate + "\t" + phone );
    34. }
    35. } catch (SQLException e){
    36. e.printStackTrace();
    37. }finally {
    38. //关闭资源
    39. JDBCUtilsByDruid.close(set,preparedStatement,connection);
    40. }
    41. }
    42. //使用土方法来解决 ResultSet => 封装 => ArrayList
    43. @Test
    44. public ArrayList testSelectToArrayList(){
    45. System.out.println("使用德鲁伊的方式完成");
    46. // 1.得到连接
    47. Connection connection = null;
    48. //2.组织一个sql
    49. String sql = "select * from actor where id >= ?";
    50. PreparedStatement preparedStatement = null;
    51. ResultSet set = null;
    52. //创建一个ArrayList
    53. ArrayList list = new ArrayList<>(); // 创建ArrayList 对象,存放actor 对象
    54. //3.创建PreparedStatement 对象
    55. try {
    56. connection = JDBCUtilsByDruid.getConnection();
    57. preparedStatement = connection.prepareStatement(sql);
    58. preparedStatement.setInt(1,1);
    59. set = preparedStatement.executeQuery();
    60. // connection.close();
    61. //遍历该结果集
    62. while (set.next()){
    63. int id = set.getInt("id");
    64. String name = set.getString("name"); //getName()
    65. String sex = set.getString("sex");
    66. Date borndate = set.getDate("borndate");
    67. String phone = set.getString("phone");
    68. //把得到的resultSet 分装到 Actor对象 放入到List 集合
    69. list.add(new Actor(id,name,sex,borndate,phone));
    70. }
    71. System.out.println("list 集合数据=" + list);
    72. } catch (SQLException e){
    73. e.printStackTrace();
    74. }finally {
    75. //关闭资源
    76. JDBCUtilsByDruid.close(set,preparedStatement,connection);
    77. }
    78. //因为ArrayList 和 connection 没有任何关联 所以该集合可以复用
    79. return list;
    80. }
    81. }

    六.Apache-DBUtils

    基本介绍

    1. commons-dbutils 是Apache 组织提供的一个开源JDBC工具类,它是对JDBC的分装,使用dbutils能极大简化jdbc编程的工作量
    • DbUtils类
    • QueryRunner类:该类封装了sql的执行,是线程安全的。可以实现增,删,改,查,批处理 
    • 使用QueryRunner类实现查询
    • ResultHandler 接口:该接口用于处理 java.sql.ResultSet,将数据按照要求转换成为另外一种形式

    ArrayHandler 把结果集中的第一行数据转换成对象数组

    ArrayListHandler:把结果集中的每一行数据都转换成一个数组,在存放到List中

    BeanHandler: 将结果集中的第一行数据分装到一个对应的JavaBean实例中

    BeanListHandler :将结果集中的每一行数据分装到一个对应的JavaBean实例中,存放到List里

    ColumnListHandler:将结果就中某一行的数据存放到List中

    KeyedHandler(name) 将结果集中的每一行数据都分装到mvp里,在把这些map里,其key为指定的key

    Maphandler:将结果集中的第一行数据分装到一个Map里面,key是列名,value就是对应的值

    MapListHandler: 将结果集中的每一行数据都分装到一个Map里,然后在存放到List  

    应用实例

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

    1. package com.tianedu.jdbc.datasource;
    2. import org.apache.commons.dbutils.QueryRunner;
    3. import org.apache.commons.dbutils.handlers.BeanListHandler;
    4. import org.junit.Test;
    5. import java.sql.Connection;
    6. import java.sql.SQLException;
    7. import java.util.List;
    8. /**
    9. * @author tian
    10. */
    11. @SuppressWarnings({"all"})
    12. public class DBUtils_USE {
    13. @Test
    14. //使用apache-DBUtils 工具类 + druid 的方式完成对表的crud操作
    15. public void testQueryMany() throws SQLException { //返回结果是多行的情况
    16. //1. 得到连接
    17. Connection connection = JDBCUtilsByDruid.getConnection();
    18. //2.使用DBUtiles 类和接口 先引入德鲁伊的jar文件,加入到本project
    19. //3.创建一个 QueryRunner
    20. QueryRunner queryRunner = new QueryRunner();
    21. //4.就可以执行相关的方法,返回ArrayList 结果集
    22. //String sql = "select * from actor where id >= ?";
    23. //注意 sql 语句也可以查询部分列
    24. String sql = "select id,name from actor where id >= ?";
    25. //1.query 方法就是执行一个sql语句得到一个resultset -- 分装到 --》 ArrayList 集合中然后返回
    26. //2.返回集合
    27. //3.connection: 连接
    28. //4.sql 执行sql语句
    29. //5.ew BeanListHandler<>(Actor.class) 再将resultset -》 actor 对象分装到 ArrayList
    30. //底层 使用反射机制 去获取actor 类的属性,然后进行封装
    31. //6. 1 是传递给sql 的? 的 可以有多个值,因为它是一个可变参数 Object... parames
    32. //7.底层 得到的resultSet 会在query 关闭,关闭PrepareStatment
    33. List list =
    34. queryRunner.query(connection, sql, new BeanListHandler<>(Actor.class), 1);
    35. System.out.println("输出集合的信息");
    36. for (Actor actor : list){
    37. System.out.print(actor);
    38. }
    39. // 释放资源
    40. JDBCUtilsByDruid.close(null,null,connection);
    41. }
    42. }
    1. package com.tianedu.jdbc.datasource;
    2. import org.apache.commons.dbutils.QueryRunner;
    3. import org.apache.commons.dbutils.handlers.BeanHandler;
    4. import org.apache.commons.dbutils.handlers.BeanListHandler;
    5. import org.apache.commons.dbutils.handlers.ScalarHandler;
    6. import org.junit.Test;
    7. import java.sql.Connection;
    8. import java.sql.SQLException;
    9. import java.util.List;
    10. /**
    11. * @author tian
    12. */
    13. @SuppressWarnings({"all"})
    14. public class DBUtils_USE {
    15. @Test
    16. //使用apache-DBUtils 工具类 + druid 的方式完成对表的crud操作
    17. public void testQueryMany() throws SQLException { //返回结果是多行的情况
    18. //1. 得到连接
    19. Connection connection = JDBCUtilsByDruid.getConnection();
    20. //2.使用DBUtiles 类和接口 先引入德鲁伊的jar文件,加入到本project
    21. //3.创建一个 QueryRunner
    22. QueryRunner queryRunner = new QueryRunner();
    23. //4.就可以执行相关的方法,返回ArrayList 结果集
    24. //String sql = "select * from actor where id >= ?";
    25. //注意 sql 语句也可以查询部分列
    26. String sql = "select id,name from actor where id >= ?";
    27. //1.query 方法就是执行一个sql语句得到一个resultset -- 分装到 --》 ArrayList 集合中然后返回
    28. //2.返回集合
    29. //3.connection: 连接
    30. //4.sql 执行sql语句
    31. //5.ew BeanListHandler<>(Actor.class) 再将resultset -》 actor 对象分装到 ArrayList
    32. //底层 使用反射机制 去获取actor 类的属性,然后进行封装
    33. //6. 1 是传递给sql 的? 的 可以有多个值,因为它是一个可变参数 Object... parames
    34. //7.底层 得到的resultSet 会在query 关闭,关闭PrepareStatment
    35. List list =
    36. queryRunner.query(connection, sql, new BeanListHandler<>(Actor.class), 1);
    37. System.out.println("输出集合的信息");
    38. for (Actor actor : list){
    39. System.out.print(actor);
    40. }
    41. // 释放资源
    42. JDBCUtilsByDruid.close(null,null,connection);
    43. }
    44. // 演示 apache - dubtlis + druid 完成 返回的结果 是单行记录(单个对象)
    45. @Test
    46. public void testQuerySingle() throws SQLException {
    47. //1.得到连接
    48. Connection connection = JDBCUtilsByDruid.getConnection();
    49. //2.创建QueryRunner
    50. QueryRunner queryRunner = new QueryRunner();
    51. //3.sql 语句 执行相关方法,返回单个对象
    52. String sql = "select * from actor where id = ?";
    53. //因为我们知道返回的是单行记录 单个记录,使用Hander 是 BeanHandler
    54. Actor actor = queryRunner.query(connection, sql, new BeanHandler<>(Actor.class), 2);
    55. System.out.println(actor);
    56. JDBCUtilsByDruid.close(null,null,connection);
    57. }
    58. // 演示apache-dubtils + druid 完成查询结果是单行单列 - 返回的就是一个Object
    59. // Scalar 胆量
    60. @Test
    61. public void testScalar() throws SQLException {
    62. Connection connection = JDBCUtilsByDruid.getConnection();
    63. QueryRunner queryRunner = new QueryRunner();
    64. //执行相关方法,返回单行单列,返回的就是Obeject
    65. String sql = "select name from actor where id = ?";
    66. //因为返回的是单行单列,返回的是ScalarHandler
    67. Object obj= queryRunner.query(connection, sql, new ScalarHandler(), 2);
    68. System.out.println(obj);
    69. JDBCUtilsByDruid.close(null,null,connection);
    70. }
    71. //演示 apache-dbutils + druid 完成 dml(update insert delect)
    72. @Test
    73. public void testDML() throws SQLException {
    74. //得到连接
    75. Connection connection = JDBCUtilsByDruid.getConnection();
    76. //创建queryRunner
    77. QueryRunner queryRunner = new QueryRunner();
    78. //4.这里我们可以组织sql语句来完成 update insert delect
    79. //String sql = "update actor set name = ? where id = ?";
    80. //String sql = "insert into actor values(null,?,?,?,?)";
    81. String sql =" delete from actor where id = ?";
    82. // 1.我们执行dml 操作使用 方法是 queryRunner.update()
    83. //2.返回值是受影响的行数 affectedRow 受影响的行
    84. //int affectedRow = queryRunner.update(connection, sql, "林青霞","女","1917-10-10","116");
    85. int affectedRow = queryRunner.update(connection,sql,100 );
    86. System.out.println(affectedRow > 0 ? "执行成功":"执行没有影响数据库·");
    87. //释放资源
    88. JDBCUtilsByDruid.close(null,null,connection);
    89. }
    90. }

    七.DAO 和增删改查 通用方法 - BasicDao

    基本说明:

    • DAO: data access object 数据访问对象
    • 这样的通用类,称为BasicDao 是专门和数据库交互的,及完成对数据库(表)的crud操作
    • 在BaiscDao 的基础上,实现一张表 对应一个Dao 更好的完成功能,比如 Customer 表,Customer.java类(javabean)-CustomerDao.java

    完成一个简单的设计

    com.tianedu.dao_

    1. com.tainedu.dao_utils  //工具类
    2. com.tainedu.da0_.domain  //javabean
    3. com.tainedu.dao_.dao  //存放XXXDAO和BasicDAO
    4. com.tianedu.dao_.test //写测试类 
    1. package com.tianedu.dao_.test;
    2. import com.tianedu.dao_.dao.ActorDAO;
    3. import com.tianedu.dao_.domain.Actor;
    4. import org.junit.Test;
    5. import java.util.List;
    6. /**
    7. * @author tian
    8. */
    9. public class TestDAO {
    10. @Test
    11. //测试ActorDAO 对 actor 表的crud操作
    12. public void testActorDAO() {
    13. ActorDAO actorDAO = new ActorDAO();
    14. //测试查询语句
    15. List actors
    16. = actorDAO.queryMulti("select * from actor where id =?", Actor.class, 1);
    17. System.out.println("查询结果");
    18. for (Actor actor : actors) {
    19. System.out.println(actor);
    20. }
    21. //查询单行记录
    22. Actor actor = actorDAO.querySingle("select * from actor where id =?", Actor.class, 1);
    23. System.out.println(actor);
    24. //查询单行单列
    25. Object o = actorDAO.queryScalar("select name from actor where id = ?", 1);
    26. System.out.println("==== 查询单行列值===");
    27. System.out.println(o);
    28. //演示dml操作
    29. int update =
    30. actorDAO.update("insert into actor values(null,?,?,?,?)", "张无忌", "男", "2000-11-11", "999");
    31. System.out.println(update > 0 ? "执行成功":"执行没有影响表");
    32. }
    33. }

     

  • 相关阅读:
    数据结构与算法
    使用docker获取docker hub中的项目并复现
    centos7手动配置jdk1.8环境与maven环境
    栈和队列 OJ题
    【贪心算法-LeetCode3:无重复字符的最长子串(Java实现)】
    想了一个月都不知道如何开始做自媒体
    SqlKata - 方便好用的 Sql query builder
    Keil仿真闪退问题
    Dubbo夺命17连问
    编写单元测试
  • 原文地址:https://blog.csdn.net/weixin_68773927/article/details/133936400