文章目录
java database connection:java数据库连接
1.JDBC原生7大步骤
JDBC如何操作DQL语句,操作步骤
//1)导包,注册驱动
Class.forName("com.mysql.jdbc.Driver") ;
//2)获取数据库的连接对象
Connnection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/库名",
"root",
"登录数据库的密码"
) ;
//3)准备sql---查询语句
String sql = "select * from 表名" ;
//4)获取执行对象Statement
Statement stmt = conn.createStatement() ;
//5)执行dql语句
ResultSet rs = stmt.executeQuery(sql) ;
//6)遍历结果集的数据
while(rs.next()){
字段类型 变量名= rs.getXXX("字段名称") ;
//或者是 字段类型 变量名 = rs.getXXX(列的索引值) ; //列的索引值1..开始
//使用这个变量名
}
//7)释放资源
rs.close();
stmt.close() ;
conn.close() ;
1.1 DDL
/**
* JDBC操作DDL语句 创建表
*/
public class Jdbc_OperatrDDL {
public static void main(String[] args) throws Exception{
//1)导包,注册驱动
Class.forName("com.mysql.jdbc.Driver") ;
//2)获取数据库连接对象
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/myee_2203_02",
"root",
"123456");
//3)准备sql
String sql = "CREATE TABLE student("
+ " id INT PRIMARY KEY AUTO_INCREMENT," +
" NAME VARCHAR(10), " +
" gender VARCHAR(2), " +
" address VARCHAR(50), " +
" hobby VARCHAR(100) " +
") " ;
//4)使用连接对象创建执行对象
Statement stmt = connection.createStatement();
//5)执行sql,发送数据库
int count = stmt.executeUpdate(sql);
System.out.println("影响"+count+"行") ;
//6)释放资源
stmt.close();
connection.close();
}
}
1.2 DML
package jdbc_02;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
/**
* JDBC操作DDL语句 创建表
*/
public class Jdbc_OperatrDDL {
public static void main(String[] args) throws Exception{
//1)导包,注册驱动
Class.forName("com.mysql.jdbc.Driver") ;
//2)获取数据库连接对象
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/myee_2203_02",
"root",
"123456");
//3)准备sql
String sql = "CREATE TABLE student("
+ " id INT PRIMARY KEY AUTO_INCREMENT," +
" NAME VARCHAR(10), " +
" gender VARCHAR(2), " +
" address VARCHAR(50), " +
" hobby VARCHAR(100) " +
") " ;
//4)使用连接对象创建执行对象
Statement stmt = connection.createStatement();
//5)执行sql,发送数据库
int count = stmt.executeUpdate(sql);
System.out.println("影响"+count+"行") ;
//6)释放资源
stmt.close();
connection.close();
}
}
1.3DQL
/**
* JDBC使用Statement执行对象来操作DQL语句:数据库查询语句
*/
public class Jdbc_Operator_DQL {
public static void main(String[] args)throws Exception {
//需求:查询myee_2203_02 库中学生表的所有信息
//注册驱动
Class.forName("com.mysql.jdbc.Driver") ;
//获取数据库的连接对象
Connection connection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/myee_2203_02",
"root",
"123456"
) ;
//sql
String sql ="select * from student" ;
//获取执行对象
Statement stmt = connection.createStatement();
//执行DQL语句
//ResultSet exceuteQuery(String sql)
ResultSet rs = stmt.executeQuery(sql);
System.out.println("学生列表如下:");
System.out.println("编号\t姓名\t性别\t地址\t爱好");
/* //第一次获取
if(rs.next()){ //true,有数据,光标向前移动一行
//获取数据 ResultSet 通用操作
//xxx getXxx(int 列的索引值)
//xxx getXxxx(String 列的名称)
int id = rs.getInt(1); //获取编号
String name = rs.getString(2); //获取姓名
String gender = rs.getString(3); //获取性别
String addrses = rs.getString(4); //获取地址
String hobby = rs.getString(5);//获取爱好
System.out.println(id+"\t\t"+name+"\t"+gender+"\t\t"+addrses+"\t"+hobby);
}
//第二次获取
if(rs.next()){ //true,有数据,光标向前移动一行
//获取数据 ResultSet 通用操作
//xxx getXxx(int 列的索引值)
//xxx getXxxx(String 列的名称)
int id = rs.getInt("id"); //获取编号
String name = rs.getString("name"); //获取姓名
String gender = rs.getString("gender"); //获取性别
String addrses = rs.getString("address"); //获取地址
String hobby = rs.getString("hobby");//获取爱好
System.out.println(id+"\t\t"+name+"\t"+gender+"\t\t"+addrses+"\t"+hobby);
}*/
//依次类推
//不明确循环次数
while(rs.next()){
int id = rs.getInt("id"); //获取编号
String name = rs.getString("name"); //获取姓名
String gender = rs.getString("gender"); //获取性别
String addrses = rs.getString("address"); //获取地址
String hobby = rs.getString("hobby");//获取爱好
System.out.println(id+"\t\t"+name+"\t"+gender+"\t\t"+addrses+"\t"+hobby);
}
//释放资源
rs.close();
stmt.close();
connection.close();
}
}
2.封装JDBC基本操作的工具类步骤
//在src目录下:类路径 xxx.properties
//driverClass=com.mysql.jdbc.Driver
//url=jdbc:mysql://localhost:3306/库名?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
//username=root
//password=登录的密码
class JdbcUtils{
private static String drierClass = null ;
private static String url = null ;
private static String username = null ;
private static String password = null ;
private JdbcUtils(){}
//提供静态代码块:随着类的加载而加载
static{
//创建属性列表:属性集合类 Properties
Properties prop = new Properties() ;
//读取配置文件 获取配置文件所在的输入流对象
InputStream inputStream = JdbcUtils.class.getClassLoader().getResurcesAsStream("xxx.properties") ;
//将流对象中的加载属性列表中prop
prop.load(inputStream) ;
//通过key获取它里面的value
drierClass = prop.getProperty("driverClass") ;
url = prop.getProperty("url") ;
username = prop.getProperty("username") ;
password = prop.getProperty("password") ;
//注册驱动
Class.forName(drierClass) ;
}
//获取连接对象
public static Connection getConnection(){
Connnection conn = DriverManager.getConnection(url,username,password) ;
return conn ;
}
//释放资源--关闭相关系统资源 (发送sql到数据库Statement执行对象,Connection ,ResultSet)
public static void close(Statement stmt,Connnection conn){
close(null,stmt,conn) ;
}
public static void close(ResultSet rs,Statement stmt,Connnection conn){
if(rs!=null){
try{
rs.close() ;
}catch(SQLException e){
e.printStackTrice() ;
}
}
if(stmt!=null){
try{
stmt.close() ;
}catch(SQLException e){
e.printStackTrice() ;
}
}
if(conn!=null){
try{
conn.close() ;
}catch(SQLException e){
e.printStackTrice() ;
}
}
}
}
3.获取一个类的字节码文件的方式
1)任意java类型的class属性
2)Object类中的getClass(); 对象名.getClass()
3)Class.forName("类的全限定名称") ;//包名.类名
4.mysql的驱动包如何注册驱动的?
针对5.1的jar包的com.mysql.jdbc.Driver进行说明
class Driver implements java.sql.Driver{
static{
DriverManager.registerDriver(new Driver()) ; //这块已经使用到了注册驱动的方法
}
}
5.JDBC使用PreparedStatement预编译对象操作数据库的步骤
//原生操作步骤
//1.导包 驱动包:5.1jar/8.0以及它以上的jar包
//2.注册驱动
Class.forName("com.mysql.jdbc.Driver") ;
//3.获取数据库的连接对象
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/库名?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true",
"root",
"登录mysql的密码"
) ;
//4)准备好参数化的sql语句 DML语句
String sql = "insert into 表名 values(?,?,?...)" ;
String sql2 = "update 表名 set 字段名称1 = ?,字段名称2 = ?,字段名称3 = ? where 字段名称 = ?" ;
String sql3 = "delete from 表名 where 字段名称 = ?" ;
//sql语句:参数化的DQL语句
String sql4 = "select * from 表名 " ;
String sql5 = "select * from 表名 where 字段名称 = ?" ;
//...
//5)获取预编译对象,同时将sql发送给数据库
PreparedStatement ps = conn.prepareStatement(sql) ;
//6)通过预编译对象,参数赋值
ps.setXXX(占位符号的索引值,XXX类型的实际参数) ;
//7)要么执行DML语句
int count = ps.executeUpdate() ;
//影响的行数 count
//要么执行的DQL语句
ResultSet rs = ps.executeQuery() ;
while(rs.next()){
//获取结果数据
XXX 变量名 = rs.getXXX("列的名称要么列的索引值") ;
}
//释放资源
//执行dql语句,
//执行dml,只需要释放后面两个对象 ps对象以及conn对象
rs.close();
ps.close();
conn.close() ;
6.Statement和PreparedStatement对象的区别
1)执行sql效率区别
Statement对象:执行sql,每一次将sql都需要发送一次,相对于PreparedStatement对象效率低,不用它的原因
数据库的性能优化--->减少服务器的交互次数(和数据库的交互次数减少)
PreparedStatement对象:预编译对象: 执行的参数化的sql,直接先发送给数据库,数据库会进行校验(参数类型,以及参数的字段是哪一列),并且保存在预编译对象中,可以不断的重新赋值;执行sql效率高!
2)是否存在sql注入的区别
Statement对象:执行的sql语句,都是静态化sql,sql存在字符串拼接,就会导致可能出现sql注入,非常不安全!
举例
select * from user where username = '"+变量名+"' and password '"+值...+"' ;
PreparedStatement预编译对象:每次是在自己内存中直接赋值对应的值,sql语句永远是占位符号?
select * from user where username = ? and password = ? ;
不会造成sql注入问题,非常安全的!
7.什么是数据库连接池,数据库连接池的好处是什么
数据库连接池:
可以分配,释放,管理数据库连接对象,当前某个连接对象释放之后,会归还到连接池中,大大提高了JDBC操作数据库性能!
弊端:维护成本高; (维护它druid的版本以及监控它的连接数量)
好处:可以设置参数,将数据库连接池进行调优;
每一个线程都会使用自己的连接对象!
前某个连接对象释放之后,会归还到连接池中,等待下一次利用(大大提高了连接对象的使用率)
在连接池中:会初始化一些连接数量(提供了很多参数)
initialSize:初始化数量
maxActive:最大激活数量
maxWait:最大等多等待时间(毫秒值)
maxidle:最大空闲数量
minidel:最小空闲数量
...
...
8.通过Druid(德鲁伊)获取数据源的操作步骤
//1)导包
//2)加入连接池的配置文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/库名?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username=root
password=123456
initialSize=5
maxActive=10
maxWait=3000
//3)读取配置文件
InputStream inputStream = 当前类.class.getClassLoader().getResourceAsStream("xxx.properties") ;
//4)创建属性集合列表
Properties prop = new Properties() ;
prop.load(inputStream) ;
//5)获取数据源----DruidDataSourceFactory
//public static DataSource createDataSource(Properties prop)
DataSource ds = DruidDataSourceFactory.createDataSource( prop) ;
//DataSource替代了DriverManager: Connection getConnection() ;
//6)获取连接对象
Connection conn = ds.getConnection() ;
//使用连接对象
9.封装jdbc工具类,加入数据库连接池以及ThreadLocal的步骤
//为了模拟真实场景:一个线程使用自己的连接对象---操作数据库
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.qf.hw1.utils.DruidJdbcUtils;
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;
/**
* @version: 1.0
*/
public class DruidJDBCUtils {
//模拟线程,每一个线程使用自己的connection
private static ThreadLocal<Connection> t = new ThreadLocal<>();
//声明一个DataSource类型的变量
private static DataSource ds;
//无参构造私有化
private DruidJDBCUtils() {
}
//静态代码块
static {
try {
//创建属性集合列表
Properties pro = new Properties();
//直接读取连接池的配置文件
InputStream inputStream = DruidJDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
//将字节输入流的内容加载属性列表中
pro.load(inputStream);
//工厂类获取数据源对象
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//封装一个功能:获取数据库的连接对象
public static DataSource getDataSource() {
return ds;
}
public static Connection getConnection(){
//1)首先要从当前线程中获取连接对象
try {
Connection conn = t.get();
//2)判断conn是空的
if(conn==null){
//当前线程中没有开始绑定连接对象
//3)从数据源连接池获取连接对象
conn = ds.getConnection() ;
//4)将当前连接对象绑定给自己的线程中
t.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();
//需要将自己线程中的连接对象解绑
t.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);
}
}
10.单元测试
步骤:
1.导包junit核心包以及hmrecrest-core 依赖包
2)测试某个功能
编写测试用例----编写一个单元测试方法
这个方法没有返回值类型,没有参数
3)需要标记这个方法为单元测试方法,需要在方法上面加入@Test注解
4)在junit包下一个断言Assert里面很多的方法来断言某个功能的结果
是否和预期结果一致,如果一致,说明断言成功;否则失败! (如果测试自己的功能,不用断言,可以直接接口多态测试数据是否存在!)
举例:
员工类
/**
* @Author: txh
* @Date: 2022/5/18 - 05 - 18 - 17:58
* @Description: hw1
* @version: 1.0
*/
public class Emp {
private int id;
private String name;
private int age;
private String gender;
private String address;
private double salary;
public Emp(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 Emp() {
}
@Override
public String toString() {
return "emp{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", address='" + address + '\'' +
", salary=" + salary +
'}';
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getGender() {
return gender;
}
public String getAddress() {
return address;
}
public double getSalary() {
return salary;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setGender(String gender) {
this.gender = gender;
}
public void setAddress(String address) {
this.address = address;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
接口:
import java.sql.SQLException;
import java.util.List;
/**
* @Author: txh
* @Date: 2022/5/19 - 05 - 19 - 20:40
* @Description: com.qf2.hw1
* @version: 1.0
*/
public interface EmpDao {
void add(Emp emp) throws SQLException;
void sub() throws SQLException;
void update() throws SQLException;
List<Emp> select() throws SQLException;
}
实现类:
import com.qf2.druid.DruidJDBCUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* @Author: txh
* @Date: 2022/5/19 - 05 - 19 - 19:52
* @Description: com.qf2.hw1
* @version: 1.0
*/
public class EmpDaoimpl implements EmpDao{
/**
* 添加员工的方法
* @throws SQLException
*/
@Override
public void add(Emp emp) throws SQLException {
//1.获取连接对象
Connection connection = DruidJDBCUtils.getConnection();
//2.获得参数化的sql
String sql = "insert into emp2 values(?,?,?,?,?,?)";
//3.赋值
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,emp.getId());
preparedStatement.setString(2,emp.getName());
preparedStatement.setInt(3,emp.getAge());
preparedStatement.setString(4,emp.getGender());
preparedStatement.setString(5,emp.getAddress());
preparedStatement.setDouble(6,emp.getSalary());
//4.
int i = preparedStatement.executeUpdate();
System.out.println("影响了"+i+"行");
DruidJDBCUtils.close(preparedStatement,connection);
}
/**
* 删除员工的方法
*/
@Override
public void sub() throws SQLException {
Connection connection = DruidJDBCUtils.getConnection();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要删除的id:");
int id = scanner.nextInt();
String sql = "delete from emp2 where id=?;";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,id);
int i = preparedStatement.executeUpdate();
System.out.println("影响了"+i+"行");
DruidJDBCUtils.close(preparedStatement,connection);
}
@Override
public void update() throws SQLException {
Connection connection = DruidJDBCUtils.getConnection();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要更新的id:");
int id = scanner.nextInt();
String sql = "update emp2 set name = '孙悟空' where id=?;";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,id);
int i = preparedStatement.executeUpdate();
System.out.println("影响了"+i+"行");
DruidJDBCUtils.close(preparedStatement,connection);
}
@Override
public List<Emp> select() throws SQLException {
Connection connection = DruidJDBCUtils.getConnection();
String sql = "select * from emp2";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
List<Emp> list = new ArrayList<>();
Emp emp = null;
while(resultSet.next()){
emp = new Emp();
emp.setId(resultSet.getInt(1));
emp.setName(resultSet.getString(2));
emp.setAge(resultSet.getInt(3));
emp.setGender(resultSet.getString(4));
emp.setAddress(resultSet.getString(5));
emp.setSalary(resultSet.getDouble(6));
list.add(emp);
}
DruidJDBCUtils.close(resultSet,preparedStatement,connection);
return list;
}
}
测试类:
import org.junit.Before;
import java.sql.SQLException;
import java.util.List;
/**
* @Author: txh
* @Date: 2022/5/19 - 05 - 19 - 20:52
* @Description: com.qf2.hw1
* @version: 1.0
*/
public class Test {
EmpDaoimpl empDaoimpl;
@Before
public void createEmpDao(){
empDaoimpl = new EmpDaoimpl();
}
@org.junit.Test
public void addTest() throws SQLException {
Emp emp = new Emp(6, "易烊千玺", 20, "男", "北京", 50000);
empDaoimpl.add(emp);
}
@org.junit.Test
public void subTest() throws SQLException {
empDaoimpl.sub();
}
@org.junit.Test
public void updateTest() throws SQLException { EmpDaoimpl empDaoimpl = new EmpDaoimpl();
empDaoimpl.update();
}
@org.junit.Test
public void selectTest() throws SQLException { EmpDaoimpl empDaoimpl = new EmpDaoimpl();
List<Emp> select = empDaoimpl.select();
for (Emp emp : select) {
System.out.println(emp);
}
}
}
@After//在执行@Test标记的这个方法之后执行
@Before//现在执行这个方法
11.事务
import com.qf.hw2.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);
}
}
}
12.引入commons-dbutils工具类库以及使用
qr.ruery这个方法的形参中的接口ResultSetHandler的实现类常用的有三种
BeanListHandler返回一个集合
BeanHandler返回一个对象实例
ScalarHandler返回一个Object对象,使用的时候需要转型
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集合中
接口:
import com.qf.hw1.pojo.Emp;
import java.sql.SQLException;
import java.util.List;
/**
* @Author: txh
* @Date: 2022/5/20 - 05 - 20 - 14:51
* @Description: com.qf.dao
* @version: 1.0
*/
public interface EmoDao {
/**
* 查询全部员工的方法
* @return 集合
* @throws SQLException
*/
List<Emp> findAll() throws SQLException;
/**
* 查询一个员工的方法
* @return
*/
Emp findEmp(int id) throws SQLException;
/**
* 增加员工信息的方法
* @param emp
*/
void addEmp(Emp emp) throws SQLException;
/**
* 根据id删除员工的方法
* @param id
*/
void deleteEmp(int id) throws SQLException;
/**
* 更新员工
* @param
*/
void updateEmp(Emp emp) throws SQLException;
/**
* 获得emp2表中总记录数
* @return
*/
int getTotalCount() throws SQLException;
}
实现类:
package com.qf.hw1.dao.impl;
import com.qf.hw1.dao.EmoDao;
import com.qf.hw1.pojo.Emp;
import com.qf.hw1.utils.DruidJDBCUtils;
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: txh
* @Date: 2022/5/20 - 05 - 20 - 14:54
* @Description: com.qf.dao.impl
* @version: 1.0
*/
public class EmpDaoImpl implements EmoDao {
@Override
public List<Emp> findAll() throws SQLException {
//1.导包
//2.创建数据库的执行对象
QueryRunner query = new QueryRunner(DruidJDBCUtils.getDataSource());
//3.准备参数化的sql语句
String sql = "select * from emp2 " ;
//4.执行它的通用方法
List<Emp> list = query.query(sql, new BeanListHandler<Emp>(Emp.class));
return list;
}
@Override
public Emp findEmp(int id) throws SQLException {
//1.创建数据库的执行对象
QueryRunner queryRunner = new QueryRunner(DruidJDBCUtils.getDataSource());
//2.准备参数化的sql语句
//String sql = "select name=?,age=?,gender=?,address=?,salary=? from emp2 where id = ? " ;
String sql = "select * from emp2 where id = ? " ;
//执行通用方法
Emp emp = queryRunner.query(sql, new BeanHandler<Emp>(Emp.class), id);
return emp;
}
@Override
public void addEmp(Emp emp) throws SQLException {
//1.创建数据库的执行对象
QueryRunner queryRunner = new QueryRunner(DruidJDBCUtils.getDataSource());
//2.准备好参数化的sql语句
String sql = "insert into emp2 (name,age,gender,address,salary) values (?,?,?,?,?) ;" ;
//3.执行方法
int i = queryRunner.update(sql,
emp.getName(),
emp.getAge(),
emp.getGender(),
emp.getAddress(),
emp.getSalary());
System.out.println("影响了"+i+"行");
}
@Override
public void deleteEmp(int id) throws SQLException {
//1.创建数据库的执行对象
QueryRunner queryRunner = new QueryRunner(DruidJDBCUtils.getDataSource());
//2.准备好参数化的sql语句
String sql = "delete from emp2 where id = ? ;" ;
//3.执行方法
int i = queryRunner.update(sql, id);
System.out.println("影响了"+i+"行");
}
@Override
public void updateEmp(Emp emp) throws SQLException {
//1.创建数据库的执行对象
QueryRunner queryRunner = new QueryRunner(DruidJDBCUtils.getDataSource());
//2.准备好参数化的sql语句
String sql = "update emp2 set name=?,age=?,gender=?,address=?,salary=? where id=? ;" ;
//3.执行方法
int i = queryRunner.update(sql,
emp.getName(),
emp.getAge(),
emp.getGender(),
emp.getAddress(),
emp.getSalary(),
emp.getId());
System.out.println("影响了"+i+"行");
}
@Override
public int getTotalCount() throws SQLException {
//1.创建数据库的执行对象
QueryRunner queryRunner = new QueryRunner(DruidJDBCUtils.getDataSource());
//2.准备好参数化的sql语句
String sql = "select count(id) from emp2 ;" ;
//3.执行方法
//执行sql:将查询的这条记录封装到Employee类中
// public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params)
//参数1:sql语句
//参数2:结果集的处理:BeanHandler对象 //有参构造 public BeanHandler<T>(Class<T> class)
//参数3:给占位符号 赋值
Object o = queryRunner.query(sql, new ScalarHandler<>());
String s = String.valueOf(o);
int i = Integer.parseInt(s);
return i;
}
}
测试类:
package com.qf.hw1.Test;
import com.qf.hw1.dao.impl.EmpDaoImpl;
import com.qf.hw1.pojo.Emp;
import org.junit.Before;
import org.junit.Test;
import java.sql.SQLException;
import java.util.List;
/**
* @Author: txh
* @Date: 2022/5/20 - 05 - 20 - 15:01
* @Description: com.qf.Test
* @version: 1.0
*/
public class Test01 {
EmpDaoImpl emoDaoimpl ;
@Before
public void createEmpDaoObject(){
emoDaoimpl = new EmpDaoImpl();
}
@Test
public void testFindAll() throws SQLException {
List<Emp> list = emoDaoimpl.findAll();
if(list!=null){
for (Emp emp : list) {
System.out.println(emp);
}
}
}
@Test
public void testAddEmp() throws SQLException {
Emp emp = new Emp("欧豪",26,"男","上海",20000);
// emp.setName("王雷");
// emp.setAge(26);
// emp.setGender("男");
// emp.setSalary(5000);
// emp.setAddress("北京");
emoDaoimpl.addEmp(emp);
}
@Test
public void testDeleteEmp() throws SQLException {
emoDaoimpl.deleteEmp(9);
}
@Test
public void testFindEmp() throws SQLException {
Emp emp = emoDaoimpl.findEmp(10);
if(emp!=null){
System.out.println(emp);
}
}
@Test
public void testUpdate() throws SQLException {
Emp emp = new Emp(10,"兵兵", 23, "男", "渭南", 12000);
emoDaoimpl.updateEmp(emp);
}
@Test
public void testGetTotalCount() throws SQLException {
int totalCount = emoDaoimpl.getTotalCount();
System.out.println(totalCount);
}
}