Commons-dbutils介绍及使用

34 篇文章 0 订阅
7 篇文章 0 订阅

Commons-dbutils介绍及使用

Commons-dbutils使用说明

commons-dbutils的官网地址: Apache组织机构旗下的开源的工具类库
https://commons.apache.org/proper/commons-dbutils/
就是被用来完成jdbc操作,简化了jdbc操作的一种书写格式(查询多条记录,将这些记录封装List中)
针对原生Jdbc的建议封装

完成jdbc操作
使用步骤:
1)需要导入核心的jar包 commons-dbtils.jar
mysql驱动jar包
连接池–druid的jar包
junit单元测试:核心包junit.jar以及依赖包

2)有关commons-dbtils.jar 核心接口以及核心类有哪些
使用的执行对象----操作数据库:
org.apache.commons.dbutils.QueryRunner 里面封装就是PreparedStatement
两个通用的方法
query(xxx,ResultSetHandler rsh):针对dql语句来完成查询操作
update(xxx,xx):针对dml域操作:insert into,update,delete from …
核心接口:ResultSetHandler:针对结果集的处理

很多很多实现类
BeanListHandler:可以将查询的多条记录封装到List集合中

JDBC方式控制事务

package com.qf.jdbc_transaction_01;

import com.qf.utils.DruidJdbcUtils;

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

/**
 * @author Kuke
 * @date 2022/5/20 11:33
 * 现在需要使用JDBC方式控制事务:
 * 事务: 针对关系型数据库的一种机制
 *  	就是在执行业务操作过程中,同时执行多个sql或者多张表(添加/删除/修改),这些sql语句要么同时执行成功;
 *  	要么同时执行失败;
 *
 *  	张三给赵又廷转账---sql全部都是使用参数化的sql语句
 *
 *  	转账的方法(也可以自定义的方法)
 *  	public void transfer(String toName,String reveiveName,int money)
 */
public class JDBCTransactionDemo {
    public static void main(String[] args) {
        //声明Connection类型变量
        Connection connection = null ;
        PreparedStatement ps = null ;
        PreparedStatement ps2 = null ;
        try {
            //没有通过jdbc管理事务-----当同时执行多条sql,中间如果存在异常,第一条件语句成功了,第二条数据失败;
            // 转账业务失败----->应该在jdbc操作转账的业务中加入事务操作!

            //使用Jdbc控制事务--->通过获取连接对象之后,加入事务的方法
            //通过工具类获取连接对象
             connection = DruidJdbcUtils.getConnection();
            //开启事务---->利用Connection的功能void setAutoCommit(boolean autoCommit):默认自动提交
            //参数为false:禁用自动提交,需要手动提交事务
            connection.setAutoCommit(false) ;

            //准备sql---参数化sql
            String sql = "update account set balance = balance - ? where id = ?" ;
            //获取预编译对象
            ps = connection.prepareStatement(sql);
            //参数赋值
            ps.setInt(1,500) ;
            ps.setInt(2,1) ;

            String sql2 = "update account set balance = balance + ? where id = ?" ;
            //获取预编译对象
            ps2 = connection.prepareStatement(sql2);
            ps2.setInt(1,500) ;
            ps2.setInt(2,2);

            //分别执行更新操作
            int count = ps.executeUpdate();

            int i = 10/0 ;

            int count2 = ps2.executeUpdate();
            System.out.println(count+"---"+count2);


            //提交事务: 如果没有问题,提交事务---数据在能永久更新
            //Connection对象的方法:void commit()

        } catch (Exception e) {
            System.out.println("执行catch语句");
            //出现异常,程序执行catch语句
            //事务回滚
            //连接对象的方法void rollback():回滚到默认在更新之前的操作
            try {
                connection.rollback() ;
            } catch (SQLException ex) {
                ex.printStackTrace();
            }

            e.printStackTrace();
            /*System.out.println("异常抛出了");*/
        }finally {
            //任何情况下finally中的代码一定会执行的,除非 只执行这个语句之前,jvm退出了 System.exit(0) ;
            try {
                connection.commit();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            //释放资源
            DruidJdbcUtils.close(ps,connection);
            DruidJdbcUtils.close(ps2,connection);

        }
    }
}

练习:JDBC增删改查

WorkerDao:接口类
import com.qf.entity.Worker;

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

/**
 * @Author 豆三岁
 * @Date 2022-05-19 19:42
 **/
public interface WorkerDao {
    //根据学生id修改某个员工的信息方法 :public void updateWorker(Worker worker) ;
    void updateWorker(Worker worker) throws SQLException;

    //根据id查询某个员工信息,public Worker findWorkerById(int id);
    Worker findWorkerById(int id) throws SQLException;

    //添加员工信息的功能:public void add(Worker worker) ;
    void add(Worker worker) throws SQLException;

    //查询所有员工信息的功能,List<Employee> findAll();
    List<Worker> findAll() throws SQLException;

    //根据id删除某个员工信息,public Worker deleteWorkerById(int id);
    int deleteWorkerById(int id) throws SQLException;

    //查询worker表中的总记录数
    int count() throws SQLException;

}
Worker:实体类
/**
 * @Author 豆三岁
 * @Date 2022-05-19 19:40
 **/
public class Worker {
    private int id;
    private String name;
    private int age;
    private String gender;
    private String address;
    private Double salary;

    public Worker() {
    }

    public Worker(int id, String name, int age, String gender, String address, Double salary) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.address = address;
        this.salary = salary;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Double getSalary() {
        return salary;
    }

    public void setSalary(Double salary) {
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "WorkerDao{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                ", address='" + address + '\'' +
                ", salary=" + salary +
                '}';
    }
}
WorkerDaoImpl:接口实现类
import com.qf.Dao.WorkerDao;
import com.qf.Utils.DruidJdbcUtils;
import com.qf.entity.Worker;
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 java.sql.SQLException;
import java.util.List;

/**
 * @Author 豆三岁
 * @Date 2022-05-20 14:49
 **/
public class WorkerDaoImpl implements WorkerDao {

    /**
     * 根据学生id修改某个学生的信息方法
     * @param worker
     */
    @Override
    public void updateWorker(Worker worker) throws SQLException {
        //执行对象
        QueryRunner queryRunner = new QueryRunner(DruidJdbcUtils.getDataSource());
        //准备sql语句
        String sql= "update worker set name = ?,age = ?,gender = ?,address = ?,salary = ?  where id = ? ";
        //更新
        int i = queryRunner.update(sql,
                worker.getName(),
                worker.getAge(),
                worker.getGender(),
                worker.getAddress(),
                worker.getSalary(),
                worker.getId()
        );
        if (i==1){
            System.out.println("恭喜你,修改成功!");
        } else {
            System.out.println("修改失败!!!!");
        }
    }

    /**
     * 查询员工信息
     * @param id  根据id查询worker表中数据
     * @return  返回结果
     * @throws SQLException
     */
    @Override
    public Worker findWorkerById(int id) throws SQLException {
        //执行对象
        QueryRunner queryRunner = new QueryRunner(DruidJdbcUtils.getDataSource());
        //准备sql语句
        String sql = "select * from worker where id = ?";
        //执行方法
        Worker worker = queryRunner.query(sql, new BeanHandler<Worker>(Worker.class),id);
        //返回结果
        return worker;
    }

    /**
     * 添加员工信息
     * @param worker
     * @throws SQLException
     */
    @Override
    public void add(Worker worker) throws SQLException {
        //执行对象
        QueryRunner queryRunner = new QueryRunner(DruidJdbcUtils.getDataSource());
        //准备sql语句
        String sql = "insert into worker(id,name,age,gender,address,salary) values(?,?,?,?,?,?)";
        //执行方法
        int i = queryRunner.update(sql,
                worker.getId(),
                worker.getName(),
                worker.getAge(),
                worker.getGender(),
                worker.getAddress(),
                worker.getSalary()
        );
        if (i == 1){
            System.out.println("添加成功!!!");
        } else{
            System.out.println("添加失败!请重新添加!!!");
        }

    }

    /**
     * 查询表中所有数据
     * @return
     * @throws SQLException
     */
    @Override
    public List<Worker> findAll() throws SQLException {
        //commons-dbutils的使用步骤
        //1)导入dbutilsjar包
        //2)创建数据库的执行对象
        //QueryRunner
        //public QueryRunner(DataSource ds)
        QueryRunner queryRunner = new QueryRunner(DruidJdbcUtils.getDataSource());

        //3)准备sql语句---参数化的sql---查询全部员工数据
        String sql = "select * from worker";

        //4)执行它的通用方法
        //query(String sql,ResultSetHandler rsh)
        //参数1:sql语句
        //参数2:结果集的处理对象:接口
        //最终目的将所有的记录封装到List<Employee>中
        //public BeanListHandler<T>(Class<T> type) :参数是存储当前类型的字节码文件对象
        List<Worker> query = queryRunner.query(sql, new BeanListHandler<Worker>(Worker.class));

        return query;
    }

    /**
     * 删除员工数据
     * @param id  根据员工ID删除
     * @return  返回影响行数
     * @throws SQLException
     */
    @Override
    public int deleteWorkerById(int id) throws SQLException {
        //执行对象
        QueryRunner queryRunner = new QueryRunner(DruidJdbcUtils.getDataSource());
        //准备sql语句
        String sql = "delete from worker where id = ?";
        //执行方法
        int i = queryRunner.update(sql, id);
        return i;
    }

    /**
     * 统计表中数据个数
     * @return  返回数据个数
     * @throws SQLException
     */
    @Override
    public int count() throws SQLException {

        //执行对象
        QueryRunner queryRunner = new QueryRunner(DruidJdbcUtils.getDataSource());
        //准备sql语句
        String sql = "select count(id) from worker";
        //执行方法
        Object query = queryRunner.query(sql, new ScalarHandler<>());
        //String类有万能方法:valueOf(可以传递任意类型包括Object)---->String
        String str = String.valueOf(query);
        //在String--->Integer的parseInt(String s)---->int
        int i = Integer.parseInt(str);
        return i;

    }
}
Junit_Test:单元测试(增删改查)方法:
package com.qf.Junit;

import com.qf.Impl.WorkerDaoImpl;
import com.qf.entity.Worker;
import org.junit.Test;

import java.sql.SQLException;

/**
 * @Author 豆三岁
 * @Date 2022-05-20 16:17
 **/
public class Junit_Test {

    /**
     * 修改数据:根据id修改worker表中的数据
     * @throws SQLException
     */
    @Test
    public void UpdateWorkerById() throws SQLException {
        WorkerDaoImpl workerDao = new WorkerDaoImpl();
        //创建学生
        Worker worker = new Worker();
        worker.setId(6);
        worker.setName("张三丰");
        worker.setAge(100);
        worker.setGender("男");
        worker.setAddress("武当山");
        worker.setSalary(9999.00);
        //调用功能
        workerDao.updateWorker(worker);

    }
    
    /**
     * 根据员工id获取员工信息
     * @throws SQLException
     */
    @Test
    public void FindById() throws SQLException {
        WorkerDaoImpl workerDao = new WorkerDaoImpl();
        Worker workerById = workerDao.findWorkerById(5);
        if (workerById != null ){
            System.out.println(workerById);
        } else{
            System.out.println("查无此人!");
        }

    }
    
    /**
     * 添加学生信息
     * @throws SQLException
     */
    @Test
    public void add() throws SQLException {
        WorkerDaoImpl workerDao = new WorkerDaoImpl();
        Worker worker = new Worker();
        worker.setId(7);
        worker.setName("杨过");
        worker.setAge(28);
        worker.setGender("男");
        worker.setAddress("绝情谷");
        worker.setSalary(8888.88);
        workerDao.add(worker);
    }
    
    
    /**
     * 单元测试:查询worker表中所有数据
     * @throws SQLException
     */
    @Test
    public void testFindAll() throws SQLException {
        //创建接口对象
        WorkerDao workerDao = new WorkerDaoImpl();
        List<Worker> list = workerDao.findAll();
        if (list!=null){
            //遍历list集合
            for (Worker worker : list) {
                //输出表数据
                System.out.println(worker);
            }
        }else {
            System.out.println("表中没有数据!!!");
        }
    }
    
    /**
     * 根据指定id删除员工信息
     * @throws SQLException
     */
    @Test
    public void deleteById() throws SQLException {
        WorkerDaoImpl workerDao = new WorkerDaoImpl();
        int i = workerDao.deleteWorkerById(3);
        if (i == 1){
            System.out.println("删除成功!!!");
        } else{
            System.out.println("删除失败!请重试!!!");
        }
    }
    
    /**
     * 查询worker表中的总记录数
     * @throws SQLException
     */
    @Test
    public void count() throws SQLException {
        WorkerDaoImpl workerDao = new WorkerDaoImpl();
        int i = workerDao.count();
        System.out.println("总记录数为:"+i+"条!");
    }
}

DruidJdbcUtils:JDBC封装类
package com.qf.Utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

/**
 * @author Kuke
 * @date 2022/5/19 17:40
 * 改进优化:
 * 1)从DataSource获取连接对象getConnection(),DataSource替代了DriverManager (连接池获取连接对象)
 * 2)读取的连接池的配置文件
 * 3)提供静态代码块----加载当前类的时候,直接读取连接池的配置文件,
 * 获取的连接池对象---DruidDataSourceFactroy工厂类获取数据源对象
 *
 */
public class DruidJdbcUtils {

    //成员变量位置:提供ThreadLocal<Connection>:模拟线程,每一个线程使用自己的Connection
    private static ThreadLocal<Connection> t1 = new ThreadLocal<>() ;
    //声明一个DataSource类型的变量
    private static DataSource ds ;

    //无参构造私有化:目的外界不能new对象了
    private DruidJdbcUtils(){}

    //静态代码块
    static{
        try {
            //创建属性集合列表
            Properties prop = new Properties() ;
            //直接读取连接池的配置文件
            InputStream inputStream = DruidJdbcUtils.class.getClassLoader().getResourceAsStream("druid.properties");
            //将字节输入流的内容加载属性列表中
            prop.load(inputStream) ;
            //DruidDataSourceFactroy工厂类获取数据源对象
            ds = DruidDataSourceFactory.createDataSource(prop);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //封装一个功能:获取数据源
    public static DataSource getDataSource(){
        return  ds;
    }

    //封装一个功能:获取数据库的连接对象
    public static Connection getConnection(){
        //1)首先要从当前线程中获取连接对象
        try {
            Connection conn = t1.get();
            //2)判断conn是空的
            if(conn==null){
                //当前线程中没有开始绑定连接对象
                //3)从数据源连接池获取连接对象
                conn = ds.getConnection() ;
                //4)将当前连接对象绑定给自己的线程中
                t1.set(conn);
            }
            return conn ;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return  null ;
    }

    //封装释放资源
    public static void close(PreparedStatement ps,Connection conn){
        close(null,ps,conn);
    }
    public static void close(ResultSet rs, PreparedStatement ps,Connection conn){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(ps!=null){
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(conn!=null){
            try {
                conn.close();
                //需要将自己线程中的连接对象解绑
                t1.remove();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }


    //测试方法
/*    public static void main(String[] args) {
       // DataSource dataSource = DruidJdbcUtils.getDataSource();
      //  System.out.println(dataSource);
        //获取连接对象
        Connection connection = DruidJdbcUtils.getConnection();
        System.out.println(connection);
    }*/

}
druid.properties:Druid连接池文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/homework11
username=root
password=root
initialSize=5
maxActive=10
maxWait=3000
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值