java _JDBC 开发
  5Gk4PdVxxrix 2023年11月13日 31 0


目录

一.封装JDBCUtiles

二.事务

 三.批处理

四.数据库连接池

  C3P0

Druidf(德鲁伊)阿里

五.Apache-DBUtiles

六.Apache-DBUtils

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

一.封装JDBCUtiles

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

package com.tianedu.jdbc.utils;

import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;

/**
 * @author tian
 * 这是一个工具类 完成MySQL的连接和关闭资源
 *
 */
public class JDBCUtils {
    // 定义相关的属性(4个),因为只需要一份,我们做出Static
    private static  String user;     // 用户名
    private static String password;  // 密码
    private static String url;     //url
    private static String driver;  //驱动名称
    //在static 代码块去初始化
    static {
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream("src\\mysql.properties"));
            //读取相关的属性值
            user =  properties.getProperty("user");
            password = properties.getProperty("password");
            url =  properties.getProperty("url");
            driver =  properties.getProperty("driver");
        } catch (IOException e) {
            //在实际开发中,我们可以这样处理
            //1.将编译异常转换成 运行异常
            //2.这里调用者可以选择捕获该异常,也可以选择默认异常,比较方便。
            throw new RuntimeException(e);
//            e.printStackTrace();
        }
    }
//   连接数据库 返回一个Connection
    public static Connection getConnection(){
        try {
            return DriverManager.getConnection(url,user,password);
        } catch (SQLException e) {
//            throwables.printStackTrace();
            //将编译异常转换成 运行异常,调用者可以捕获该异常,也可以选择默认处理该异常,比较方便
            throw new RuntimeException(e);
        }
    }
    //关闭相关的资源
    /*
    1.ResultSet 结果集
    2.Statement 或者 PreparedStatement
    3.关闭Connection
    4.如果需要关闭资源,就传入对象,否则传入null
     */
    public static void  close(ResultSet set, Statement statement,Connection connection){
        //判断是否为null
        try {
            if(set != null){
                set.close();
            }
            if (statement != null) {
                statement.close();
            }
            if (connection != null){
                connection.close();
            }
        } catch (SQLException e) {
            //将编译异常转成运行异常抛出
            throw new RuntimeException(e);
        }
    }
}

使用工具类 JDBCUtils

package com.tianedu.jdbc.utils;

import org.junit.Test;

import java.sql.*;

/**
 * @author tian
 * 该类演示如何使用JDBCUtile工具类完成DML 和 select
 *
 *
 */
public class JDBCUtils_Use {
    public static void main(String[] args) {
        //测试

    }
    @Test
    public void testSelect(){
        //1.得到连接
        Connection connection = null;
        //2.组织一个sql
        String sql  = "select * from actor where id = ?";
        //测试 select
        PreparedStatement preparedStatement = null;
        ResultSet set = null;
        //3.创建PrepareStatement 对象

        try {
            connection = JDBCUtils.getConnection();
            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 {
            //关闭资源
            JDBCUtils.close(set,preparedStatement,connection);
        }
    }




    @Test
    public void testDML() {
        // insert update delete
        //1.得到连接
        Connection connection = null;
        //2.组织一个sql语句
        String sql = "update actor set name = ? where id = ?";
        PreparedStatement preparedStatement = null;
        //3.创建一个PreparedStatement 对象
        try {
            connection = JDBCUtils.getConnection();
            preparedStatement = connection.prepareStatement(sql);
         // 给占位符 赋值
         preparedStatement.setString(1,"周星驰");
         preparedStatement.setInt(2,1);
         //执行
            preparedStatement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //关闭资源
            JDBCUtils.close(null,preparedStatement,connection);
        }
    }
}

二.事务

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

  • 不使用事可能出现的问题模拟,模拟经典的转账业务 
package com.tianedu.jdbc.transaction_;

import com.tianedu.jdbc.utils.JDBCUtils;
import org.junit.Test;

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

/**
 * @author tian
 * 演示在JDBC中如何使用事务

 */
public class Transaction_ {
    @Test
    public void noTransaction_(){
        //操作转账的业务
        //1.得到连接
        Connection connection = null;
        //2.组织一个sql语句
        String sql = "update account  set balance = balance -100 where id = 1";
        String sql2 = "update account  set balance = balance + 100 where id = 2";
        // 创建 PreparedStatement 对象
        PreparedStatement preparedStatement = null;
        try {
            connection = JDBCUtils.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.executeUpdate(); // 执行第一条sql语句

            int i = 1/0;   // 抛出异常 下面的代码不在执行
            preparedStatement = connection.prepareStatement(sql2);
            preparedStatement.executeUpdate(); // 执行第二条 sql2 语句
        } catch (SQLException e) {
          e.printStackTrace();
        } finally {
            JDBCUtils.close(null,preparedStatement,connection);
        }
    }
    // 事务来解决
    @Test
    public void useTransaction() {
        //1. 连接事务
        Connection connection = null;
        //2.组织sql
        String sql = "update account  set balance = balance -100 where id = 1";
        String sql2 = "update account  set balance = balance + 100 where id = 2";
        //3.创建PrepareStatement 对象
        PreparedStatement preparedStatement = null;
        try {
            connection = JDBCUtils.getConnection();
            // 将connection 设置为不自动提交
            connection.setAutoCommit(false);   //相当于开始事务
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.executeUpdate(); // 执行sql

            preparedStatement = connection.prepareStatement(sql2);
            preparedStatement.executeUpdate(); //执行sql2

            //这里提交事务
            connection.commit();

        } catch (SQLException e) {
            //这里我们可以进行回滚,即撤销执行的sql
            //默认回滚到事务开始的状态
            System.out.println("执行发生了异常,撤销执行的sql");
            try {
                connection.rollback();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
            }
            e.printStackTrace();
        } finally {
            //关闭资源
            JDBCUtils.close(null,preparedStatement,connection);
        }


    }
}

 三.批处理

  • 当需要成批插入或者更新记录时。可以采用java 的批处理更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比较单独提交处理更有效率。
  • JDBC的批处理语句包括下面方法:addBatch() 添加需要批处理的sql语句或参数       executeBatch() 执行批批量处理的语句                                                                                        clearBatch() 清空批处理包的语句
  • JDBC连接MySQL时,如果需要使用批处理功能,请在url中加参数? rewriteBatchedStatements = true
  • 批处理往往和PreparedStatement 一起搭配使用,可以减少编译次数,有减少运行次数,效率大大提高 
  • 如果要批量处理  需要修改 配置文件 jdbc.properties url=jdbc:mysql://localhost:3306/数据库? rewriteBatchedStatements = true
package com.tianedu.jdbc.batch_;

import com.tianedu.jdbc.utils.JDBCUtils;
import org.junit.Test;

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

/**
 * @author tian
 * 演示Java的批处理
 */
public class Batch_ {
    @Test
    //传统的方法添五千条数数据到admin2
    public void noBatch() throws SQLException {
        //得到连接
        Connection connection = JDBCUtils.getConnection();
        //sql
        String sql = "insert into admin2 values(null,?,?)";
        //使用connect创建一个prepareStatement()
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        System.out.println("开始时间");
        long  start = System.currentTimeMillis(); // 开始时间
        for (int i = 0; i<= 5000; i++){
            preparedStatement.setString(1,"jack"+i);
            preparedStatement.setString(2,"666");
            preparedStatement.executeUpdate();
        }
        long end = System.currentTimeMillis();
        System.out.println("传统的方式 耗时="+ (end - start));
        //关闭连接
        JDBCUtils.close(null,preparedStatement,connection);

    }
    //使用批量处理方式添加数据
    @Test
    public void batch() throws SQLException {
        //获得连接
        Connection connection = JDBCUtils.getConnection();
        //写sql语句
        String sql = "insert into admin3 values(null,?,?)";
        //获得preparedStatement
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        System.out.println("开始执行");
        long start = System.currentTimeMillis();
        for (int i = 0; i < 5000; i++) {
            preparedStatement.setString(1,"tom+i");
            preparedStatement.setString(2,"777");
         //   preparedStatement.executeUpdate(); // 执行
            //将sql语句加入到批处理包中
             preparedStatement.addBatch();
             /*
             1.第一创建ArrayList —— elementDate => object[]
             2.elementDate => object[] 就会存放我们预处理的sql语句
             3.当elementDate满后,就按照1.5扩容
             4.当添加到指定的值后就执行批量处理
             5.批量处理会减少发生sql 语句的网络开销,而且减少编码的次数,因此效率高
              */
            //当有一千条记录时候在批量执行
            if ((i+1) % 1000 == 0) { // 说明满一千条 批量执行
                preparedStatement.executeBatch();
                //清空一把
                preparedStatement.clearBatch();
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("批量执行方式  耗时 = " + (end - start));
        //关闭连接
        JDBCUtils.close(null,preparedStatement,connection);
    }
}

四.数据库连接池

传统获取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
package com.tianedu.jdbc.datasource;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;

import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * @author tian
 *
 * 演示c3p0的使用
 */
public class C3P0_ {
    @Test

    //方式1  相关的参数在程序中指定  user url  password 等
    public void testC3p0_01() throws Exception {
        //1.创建一个数据源对象
        ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
        //2.通过配置文件获取相关信息 MySQL.properties 获取相关的连接信息
        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");

        //给数据源 comboPooledDateSource  设置相关的参数
        //连接的管理是由 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();//这个方法是从 DateSource 接口实现的
//            System.out.println("连接成功");
            connection.close();
        }
       long end = System.currentTimeMillis();
        System.out.println(end - start);
    }
    // 方式2 使用配置文件模板来完成
    // 将c3p0 拷贝到 src 目录下
    //该文件指定了 连接数据库和连接池的线管参数
    @Test
    public void testC3PO_02() throws SQLException {
        //使用配置文件
        ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("tian");
        long start = System.currentTimeMillis();
        for (int i = 0; i < 5000; i++) {
            Connection connection = comboPooledDataSource.getConnection();
            connection.close();
        }
        long end = System.currentTimeMillis();
        System.out.println(end -start);
    }
}
Druidf(德鲁伊)阿里
package com.tianedu.jdbc.datasource;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.junit.Test;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.util.Properties;

/**
 * @author tian
 */
public class Druid_ {
    @Test
    //测试德鲁伊的使用
    public void testDruid() throws Exception {
         // 1.加入Druid jar 包
        // 加入配置文件 将该文件拷贝到src目录下  druid.properties
        //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();
    }
}

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

package com.tianedu.jdbc.datasource;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * @author tian
 * 基于德鲁伊数据库池连接的工具类
 */
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) {
            e.printStackTrace();
        }
    }
        // 编写getConnection方法
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

    //关闭连接 是将连接放回到连接池中,close 不是真的断掉连接
    //而是把使用的Connection对象放回到连接池
    public static void  close(ResultSet resultSet, Statement statement,Connection connection){
        try {
            if (resultSet != null){
                resultSet.close();
            }
            if (statement != null){
                statement.close();
            }
            if (connection != null){
                connection.close();
            }
        } catch (SQLException e) {
           throw new RuntimeException(e);
        }


    }
}
package com.tianedu.jdbc.datasource;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * @author tian
 * 基于德鲁伊数据库池连接的工具类
 */
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) {
            e.printStackTrace();
        }
    }
        // 编写getConnection方法
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

    //关闭连接 是将连接放回到连接池中,close 不是真的断掉连接
    //而是把使用的Connection对象放回到连接池
    public static void  close(ResultSet resultSet, Statement statement,Connection connection){
        try {
            if (resultSet != null){
                resultSet.close();
            }
            if (statement != null){
                statement.close();
            }
            if (connection != null){
                connection.close();
            }
        } catch (SQLException e) {
           throw new RuntimeException(e);
        }


    }
}
package com.tianedu.jdbc.datasource;

import org.junit.Test;

import java.sql.*;

/**
 * @author tian
 */
public class JDBCUtilsByDruid_USE {
    @Test
    public void testSelect(){
        System.out.println("使用德鲁伊的方式完成");
    // 1.得到连接
        Connection connection = null;
        //2.组织一个sql
        String sql = "select * from actor where id = ?";
        PreparedStatement preparedStatement = null;
        ResultSet set = null;
        //3.创建PreparedStatement 对象
        try {
            connection = JDBCUtilsByDruid.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1,5);
            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("brondate");
                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);
        }
    }
}

五.Apache-DBUtiles

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

java _JDBC 开发_sql

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

package com.tianedu.jdbc.datasource;

import org.junit.Test;

import java.sql.*;
import java.util.ArrayList;

/**
 * @author tian
 */
@SuppressWarnings({"all"})
public class JDBCUtilsByDruid_USE {
    @Test
    public void testSelect(){
        System.out.println("使用德鲁伊的方式完成");
    // 1.得到连接
        Connection connection = null;
        //2.组织一个sql
        String sql = "select * from actor where id >= ?";
        PreparedStatement preparedStatement = null;
        ResultSet set = null;
        //3.创建PreparedStatement 对象
        try {
            connection = JDBCUtilsByDruid.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1,1);
            set = preparedStatement.executeQuery();

//            connection.close();
            //遍历该结果集
            while (set.next()){
                int id = set.getInt("id");
                String name = set.getString("name");  //getName()
                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);
        }
    }
    //使用土方法来解决 ResultSet => 封装 => ArrayList
    @Test
    public ArrayList<Actor> testSelectToArrayList(){
        System.out.println("使用德鲁伊的方式完成");
        // 1.得到连接
        Connection connection = null;
        //2.组织一个sql
        String sql = "select * from actor where id >= ?";
        PreparedStatement preparedStatement = null;
        ResultSet set = null;
        //创建一个ArrayList
        ArrayList<Actor> list = new ArrayList<>();  // 创建ArrayList 对象,存放actor 对象


        //3.创建PreparedStatement 对象
        try {
            connection = JDBCUtilsByDruid.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1,1);
            set = preparedStatement.executeQuery();

//            connection.close();
            //遍历该结果集
            while (set.next()){
                int id = set.getInt("id");
                String name = set.getString("name");  //getName()
                String sex = set.getString("sex");
                Date borndate = set.getDate("borndate");
                String phone = set.getString("phone");
                //把得到的resultSet 分装到 Actor对象  放入到List 集合
                list.add(new Actor(id,name,sex,borndate,phone));
            }

            System.out.println("list 集合数据=" + list);
        } catch (SQLException e){
            e.printStackTrace();
        }finally {
            //关闭资源
            JDBCUtilsByDruid.close(set,preparedStatement,connection);
        }
        //因为ArrayList 和 connection 没有任何关联 所以该集合可以复用
        return list;
    }
}

六.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

package com.tianedu.jdbc.datasource;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.junit.Test;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * @author tian
 */
@SuppressWarnings({"all"})
public class DBUtils_USE {
    @Test
  //使用apache-DBUtils 工具类 + druid  的方式完成对表的crud操作
    public void testQueryMany() throws SQLException {   //返回结果是多行的情况

        //1. 得到连接
        Connection connection = JDBCUtilsByDruid.getConnection();
        //2.使用DBUtiles 类和接口  先引入德鲁伊的jar文件,加入到本project
        //3.创建一个 QueryRunner
        QueryRunner queryRunner = new QueryRunner();
        //4.就可以执行相关的方法,返回ArrayList 结果集
        //String  sql = "select * from actor where id >= ?";
        //注意 sql 语句也可以查询部分列
        String sql = "select id,name from actor where id >= ?";


        //1.query 方法就是执行一个sql语句得到一个resultset -- 分装到 --》 ArrayList 集合中然后返回
        //2.返回集合
        //3.connection: 连接
        //4.sql 执行sql语句
        //5.ew BeanListHandler<>(Actor.class)  再将resultset -》 actor 对象分装到 ArrayList
        //底层 使用反射机制 去获取actor 类的属性,然后进行封装
        //6. 1 是传递给sql 的? 的 可以有多个值,因为它是一个可变参数 Object... parames
        //7.底层 得到的resultSet 会在query 关闭,关闭PrepareStatment
        List<Actor> list =
                queryRunner.query(connection, sql, new BeanListHandler<>(Actor.class), 1);
        System.out.println("输出集合的信息");
        for (Actor actor : list){
            System.out.print(actor);
        }
        // 释放资源
        JDBCUtilsByDruid.close(null,null,connection);
    }

}
package com.tianedu.jdbc.datasource;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.junit.Test;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * @author tian
 */
@SuppressWarnings({"all"})
public class DBUtils_USE {
    @Test
  //使用apache-DBUtils 工具类 + druid  的方式完成对表的crud操作
    public void testQueryMany() throws SQLException {   //返回结果是多行的情况

        //1. 得到连接
        Connection connection = JDBCUtilsByDruid.getConnection();
        //2.使用DBUtiles 类和接口  先引入德鲁伊的jar文件,加入到本project
        //3.创建一个 QueryRunner
        QueryRunner queryRunner = new QueryRunner();
        //4.就可以执行相关的方法,返回ArrayList 结果集
        //String  sql = "select * from actor where id >= ?";
        //注意 sql 语句也可以查询部分列
        String sql = "select id,name from actor where id >= ?";


        //1.query 方法就是执行一个sql语句得到一个resultset -- 分装到 --》 ArrayList 集合中然后返回
        //2.返回集合
        //3.connection: 连接
        //4.sql 执行sql语句
        //5.ew BeanListHandler<>(Actor.class)  再将resultset -》 actor 对象分装到 ArrayList
        //底层 使用反射机制 去获取actor 类的属性,然后进行封装
        //6. 1 是传递给sql 的? 的 可以有多个值,因为它是一个可变参数 Object... parames
        //7.底层 得到的resultSet 会在query 关闭,关闭PrepareStatment
        List<Actor> list =
                queryRunner.query(connection, sql, new BeanListHandler<>(Actor.class), 1);
        System.out.println("输出集合的信息");
        for (Actor actor : list){
            System.out.print(actor);
        }
        // 释放资源
        JDBCUtilsByDruid.close(null,null,connection);
    }
    // 演示 apache - dubtlis + druid 完成 返回的结果 是单行记录(单个对象)
    @Test
    public void testQuerySingle() throws SQLException {
        //1.得到连接
        Connection connection = JDBCUtilsByDruid.getConnection();
        //2.创建QueryRunner
        QueryRunner queryRunner = new QueryRunner();
        //3.sql 语句  执行相关方法,返回单个对象
        String sql = "select * from actor where id = ?";
        //因为我们知道返回的是单行记录  单个记录,使用Hander 是 BeanHandler
        Actor actor = queryRunner.query(connection, sql, new BeanHandler<>(Actor.class), 2);
        System.out.println(actor);
        JDBCUtilsByDruid.close(null,null,connection);

    }
    // 演示apache-dubtils + druid 完成查询结果是单行单列 - 返回的就是一个Object
    // Scalar 胆量
    @Test
    public void testScalar() throws SQLException {
        Connection connection = JDBCUtilsByDruid.getConnection();
        QueryRunner queryRunner = new QueryRunner();
        //执行相关方法,返回单行单列,返回的就是Obeject
        String sql = "select name from actor where id = ?";
        //因为返回的是单行单列,返回的是ScalarHandler
        Object obj= queryRunner.query(connection, sql, new ScalarHandler(), 2);
        System.out.println(obj);
        JDBCUtilsByDruid.close(null,null,connection);
    }

    //演示 apache-dbutils + druid 完成 dml(update insert delect)
    @Test
    public void testDML() throws SQLException {
        //得到连接
        Connection connection = JDBCUtilsByDruid.getConnection();
        //创建queryRunner
        QueryRunner queryRunner = new QueryRunner();

        //4.这里我们可以组织sql语句来完成 update insert delect
        //String sql = "update actor set name = ? where id = ?";



        //String sql = "insert into actor values(null,?,?,?,?)";

        String sql =" delete from actor where  id = ?";

        // 1.我们执行dml 操作使用 方法是 queryRunner.update()
        //2.返回值是受影响的行数 affectedRow 受影响的行

        //int affectedRow = queryRunner.update(connection, sql, "林青霞","女","1917-10-10","116");
        int affectedRow = queryRunner.update(connection,sql,100 );
        System.out.println(affectedRow > 0 ? "执行成功":"执行没有影响数据库·");
        //释放资源
        JDBCUtilsByDruid.close(null,null,connection);
    }
}

七.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 //写测试类 
package com.tianedu.dao_.test;

import com.tianedu.dao_.dao.ActorDAO;
import com.tianedu.dao_.domain.Actor;
import org.junit.Test;

import java.util.List;

/**
 * @author tian
 */
public class TestDAO {
    @Test
    //测试ActorDAO 对 actor 表的crud操作
    public void testActorDAO() {
        ActorDAO actorDAO = new ActorDAO();
        //测试查询语句
        List<Actor> actors
                = actorDAO.queryMulti("select * from actor where id =?", Actor.class, 1);
        System.out.println("查询结果");
        for (Actor actor : actors) {
            System.out.println(actor);
        }
        //查询单行记录
        Actor actor = actorDAO.querySingle("select * from actor where id =?", Actor.class, 1);
        System.out.println(actor);
//查询单行单列
        Object o = actorDAO.queryScalar("select name from actor where id = ?", 1);
        System.out.println("==== 查询单行列值===");
        System.out.println(o);
        //演示dml操作
        int update =
                actorDAO.update("insert into actor values(null,?,?,?,?)", "张无忌", "男", "2000-11-11", "999");
        System.out.println(update > 0 ? "执行成功":"执行没有影响表");
    }
}

 

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月13日 0

暂无评论

推荐阅读
5Gk4PdVxxrix