一、JDBC概述
基本介绍
** 1. JDBC为访问不同的数据库提供了统一的接口,为使用者屏蔽了细节问题。**
** 2. Java程序员使用JDBC,可以连接任何提供了JDBC驱动程序的数据库系统,从而完成对数据库的各种操作。 **
** 3. JDBC基本原理示意图**
** 4. JDBC是Java提供一套用于数据库操作的接口API,Java程序员只需要面向这套接口编程即可。不同的数据库厂商,需要针对这套接口,提供不同实现。**
JDBC相关API
二、连接mysql数据库
准备工作
** 1. 创建一个 lib 目录**
** 2. 将 mysql-connector-java .jar 驱动复制进去(点击蓝色字体即可下载)**
** 3. 右键添加到 Library**
JDBC程序编写步骤
** 1. 注册驱动 - 加载 Driver 类**
** 2. 获取连接 - 得到 Connection**
** 3. 执行增删改查 - 发送 SQL 给mysql执行**
** 4. 释放资源 - 关闭相关连接**
五种连接数据库的方式
** 方式一:**
package JDBC.Linkedways; import com.mysql.jdbc.Driver; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; public class linkedways1 { public static void main(String[] args) throws SQLException { //前提准备:导入mysql驱动 //1.注册驱动 Driver driver = new Driver(); //2. 获取mysql连接 // mysql连接地址 jdbc:mysql://IP:端口/数据库 //此处我连接的时本地数据库,可以指定 ip 地址连接 String url = "jdbc:mysql://localhost:3306/test"; // Properties 文件存储用户名和密码 Properties properties = new Properties(); // user - 用户名 password — 密码 按此要求存入用户名和密码 properties.setProperty("user", "root"); properties.setProperty("password", "123456"); // 按照指定的 url 和 Properties 获取连接 Connection connect = driver.connect(url, properties); //3.执行增删改查 //mysql语句 String sql = "insert into jdbc values (1,'Mike',19)"; Statement statement = connect.createStatement(); //返回该指令影响的行数,为0则代表未执行成功 int i = statement.executeUpdate(sql); System.out.println(i > 0 ? "yes" : "no"); // 4. 释放资源 connect.close(); statement.close(); } }
** 方式二:**
package JDBC.Linkedways; import com.mysql.jdbc.Driver; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; public class linkedways2 { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException { //1. 加载 Driver 类 ,此处用类加载 Class<?> aClass = Class.forName("com.mysql.jdbc.Driver"); Driver driver = (Driver) aClass.newInstance(); //2. 获取mysql连接 String url = "jdbc:mysql://localhost:3306/test"; Properties properties = new Properties(); properties.setProperty("user", "root"); properties.setProperty("password", "123456"); Connection connect = driver.connect(url, properties); //3. 执行mysql语句 Statement statement = connect.createStatement(); String sql = "update jdbc set age=age+1 where id = 1"; int i = statement.executeUpdate(sql); System.out.println(i); //4. 关闭资源 connect.close(); statement.close(); } }
** 方式三:**
package JDBC.Linkedways; import com.mysql.jdbc.Driver; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; public class linkedways3 { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException { //1. 加载 Driver 类 Class<?> aClass = Class.forName("com.mysql.jdbc.Driver"); Driver driver = (Driver) aClass.newInstance(); //2. 连接mysql数据库 String url = "jdbc:mysql://localhost:3306/test"; //利用 Properties 文件获取用户名和密码 // Properties properties = new Properties(); // properties.setProperty("user", "root"); // properties.setProperty("password", "123456"); // Connection connection = DriverManager.getConnection(url, properties); //直接利用变量获取用户名和密码 String user = "root"; String password = "123456"; DriverManager.registerDriver(driver);//可省略 // com.mysql.jdbc.Driver //追进 Driver 类 可以发现在类加载的时候会自动注册 /* static { try { DriverManager.registerDriver(new Driver()); } catch (SQLException var1) { throw new RuntimeException("Can't register driver!"); } } */ //利用 DriverManager 类的 getConnection() 方法 Connection connection = DriverManager.getConnection(url, user, password); //3. 执行mysql命令 String sql = "insert into jdbc values (2,'Milan',20)"; Statement statement = connection.createStatement(); statement.executeUpdate(sql); //4. 关闭资源 statement.close(); connection.close(); } }
** 方式四:**
package JDBC.Linkedways; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; public class linkedways4 { public static void main(String[] args) throws ClassNotFoundException, SQLException { // 1. 加载 Driver 类 Class.forName("com.mysql.jdbc.Driver"); // com.mysql.jdbc.Driver //追进Driver类 可以发现在类加载的时候会自动注册 /* static { try { DriverManager.registerDriver(new Driver()); } catch (SQLException var1) { throw new RuntimeException("Can't register driver!"); } } */ // 2. 连接mysql String url = "jdbc:mysql://localhost:3306/test"; String user = "root"; String password = "123456"; Connection connection = DriverManager.getConnection(url, user, password); // 3. 执行mysql语句 String sql = "delete from jdbc where id = 4"; Statement statement = connection.createStatement(); statement.executeUpdate(sql); // 4. 关闭资源 statement.close(); connection.close(); } }
** 方式五:**
package JDBC.Linkedways; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; public class linkedways5 { public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException { //在4的基础上进行改进,通过读取外部配置文件来读取需要的数据,而不是直接在代码里写 //这样我们可以在配置文件修改信息而程序不需要重新编译 //准备工作 //将外部配置文件读取进内存 FileInputStream Properties properties = new Properties(); properties.load(new FileInputStream(new File("src/mysql.properties"))); String url = properties.getProperty("url"); String user = properties.getProperty("user"); String password = properties.getProperty("password"); String driver = properties.getProperty("driver"); //1. 加载Driver Class.forName(driver);//可不写 /** * 1. mysql驱动 5.1.6 可以无需Class.forName(driver); * 2. 从JDK1.5以后使用的jdbc4,不再需要显示调用 Class.forName(driver) 注册驱动 * 而是自动调用驱动jar包下的META-INF\java.sql.Driver 文本中的类名称去注册 * 3. 建议还是写上,这样会更加明确。 */ //2. 连接mysql Connection connection = DriverManager.getConnection(url, user, password); //3. 执行mysql语句 String sql = "insert into jdbc values(4,'ise',20)"; Statement statement = connection.createStatement(); int i = statement.executeUpdate(sql); //4. 关闭资源 statement.close(); connection.close(); } }
#mysql.properties配置文件 #建议放在src文件夹下 #url=jdbc:mysql://ip:端口/数据库?rewriteBatchedStatements=true url=jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true #user=用户名 user=root #password=密码 password=123456 #driver=对应数据库对应的Driver类 driver=com.mysql.jdbc.Driver
温馨提示:推荐用最后一种,灵活度比较高而且操作简单。
三、ResultSet(结果集)
基本介绍
** 1. 表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。**
** 2. ResultSet对象保持一个光标指向其当前数据行。最初,光标位于第一行之前。**
** 3. next 方法将光标移动到下一行,并且由于在ResultSet 对象中没有更多行时返回false,因此可以在while循环中使用循环来遍历结果集。**
代码演示:
package JDBC.ResultSet;
import java.io.File;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
public class ResultSet01 {
public static void main(String[] args) throws Exception {
//准备工作
Properties properties = new Properties();
properties.load(new FileInputStream(new File("src//mysql.properties")));
String url = properties.getProperty("url");
String driver = properties.getProperty("driver");
String user = properties.getProperty("user");
String password = properties.getProperty("password");
//1. loaded driver
Class.forName(driver);
//2. linked mysql
Connection connection = DriverManager.getConnection(url, user, password);
//3. do mysql_order
PreparedStatement preparedStatement = connection.prepareStatement("select * from jdbc ");
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
System.out.println(resultSet.getInt(1) + " " +
resultSet.getString(2) + " " +
resultSet.getInt(3));
}
//4. close
connection.close();
preparedStatement.close();
resultSet.close();
}
}
四、Statement 和 PreparedStatement
Statement
** 1. Statement 对象用于执行静态 SQL 语句并返回其生成的结果的对象。**
** 2. Statement 对象执行 SQL 语句,存在 SQL 注入风险。**
** 3. SQL注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的 SQL 语句段或命令,恶意攻击数据库。**
** 4. 要防范 SQL 注入,只要用 PreparedStatement 取代 Statement 就可以了。**
代码演示:
package JDBC.Statement;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
public class Statement01 {
public static void main(String[] args) throws SQLException, IOException, ClassNotFoundException {
//准备工作
Properties properties = new Properties();
properties.load(new FileInputStream("src//mysql.properties"));
String url = properties.getProperty("url");
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String driver = properties.getProperty("driver");
String name = "1' or"; //
String pwd = "or '1'= '1"; // 万能密码
//加载Driver
Class.forName(driver); // 可省略
//获取mysql连接
Connection connection = DriverManager.getConnection(url, user, password);
//执行mysql命令
Statement statement = connection.createStatement();
//SQL注入 通过插入一些非法语句使得验证条件被屏蔽
String sql = "select * from users where name ='"
+ user + "' and password = '" + pwd + "'";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
System.out.print(resultSet.getInt(1) + "\t");
System.out.print(resultSet.getString(2) + "\t\t");
System.out.println(resultSet.getString(3));
}
//关闭资源
resultSet.close();
statement.close();
connection.close();
}
}
**PreparedStatement **
** 1. PreparedStatement 执行的 SQL 语句中的参数用问号表示,调用PreparedStatement 对象的 setXxx() 方法来设置这些参数。setXxx() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从1 开始),第二个是设置的 SQL 语句中参数的值。**
** 2. 调用 executeQuery() ,执行查询操作,返回ResultSet对象**
** 3. 调用 executeUpdate() ,执行增,删,改操作。**
** 4. 使用预处理可以不再使用 + 拼接sql语句,减少语法错误,而且可以有效的解决了SQL注入问题,还能大大减少编译次数,效率较高。通常情况下,我们推荐使用PreparedStatement。**
代码演示:
package JDBC.PreparedStatement;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
public class PStatement_02 {
public static void main(String[] args) throws SQLException, IOException, ClassNotFoundException {
//准备工作
Properties properties = new Properties();
properties.load(new FileInputStream("src//mysql.properties"));
String url = properties.getProperty("url");
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String driver = properties.getProperty("driver");
String name = "1' or"; //
String pwd = "or '1'= '1"; // 万能密码
//加载Driver
Class.forName(driver); // 可省略
//获取mysql连接
Connection connection = DriverManager.getConnection(url, user, password);
//执行mysql命令
String sql = "select * from users where name = ? and password = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//在preparedStatement 调用setXxx()时会检查插入的语句,以此避免SQL注入问题
preparedStatement.setString(1, name);
preparedStatement.setString(2, pwd);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
System.out.print(resultSet.getInt(1) + "\t");
System.out.print(resultSet.getString(2) + "\t\t");
System.out.println(resultSet.getString(3));
}//此时无输出
//关闭资源
resultSet.close();
preparedStatement.close();
connection.close();
}
}
五、事务
基本介绍
** 1. JDBC程序中当一个Connection 对象创建时,默认情况下是自动提交事务:每次执行一个SQL语句时,如果执行成功,就会向数据库自动提交,而不能回滚。**
** 2. JDBC程序中为了让多个SQL语句作为一个整体执行,需要使用事务。**
** 3. 调用Connection的setAutoCommit(false)可以取消自动提交事务。**
** 4. 在所有的SQL语句都成功执行后,调用Connecttion的commit() 方法,提交事务。**
** 5. 在其中某个操作失败或者出现异常时,调用Connection的rollback() 方法,回滚事务,默认回滚到事务开始时,也可以自己设置保存点。**
** 代码演示:**
package JDBC.Transaction;
import JDBC.JDBCUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class transaction_01 {
public static void main(String[] args) throws SQLException {
//由前面的学习过程我们能发现,在JDBC操作数据库时,
//获得Connection连接和释放资源的操作是相同的
//因此我们可以写一个工具类,专门用来做连接操作和关闭资源操作
//调用 JDBCUtils 工具类获得连接
Connection con = JDBCUtils.con();
String create_Table = "create table account (id int,`name` varchar(33),money double)";
String insert1 = "insert into account values(1,'mike',1000)";
String insert2 = "insert into account values(2,'Alice',20000)";
String money_sub = "update account set money = money - 100 where id = 1";
String money_add = "update account set money = money + 100 where id = 2";
PreparedStatement preparedStatement = null;
try {
preparedStatement = con.prepareStatement(create_Table);
preparedStatement.execute();
preparedStatement = con.prepareStatement(insert1);
preparedStatement.executeUpdate();
preparedStatement = con.prepareStatement(insert2);
preparedStatement.executeUpdate();
con.setAutoCommit(false);//开始事务
preparedStatement = con.prepareStatement(money_sub);
preparedStatement.executeUpdate();
// int a = 1 / 0;
preparedStatement = con.prepareStatement(money_add);
preparedStatement.executeUpdate();
con.commit();//所有操作完成,提交事务
} catch (SQLException e) {
try {
con.rollback();//若有异常事务回滚到开始时
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
throw new RuntimeException(e);
} finally {
//调用 JDBCUtils 工具类释放资源
JDBCUtils.close(null, con, preparedStatement);
}
}
}
JDBCUtils工具类
** 将获取连接和释放资源的过程封装成方法。**
package JDBC; import java.io.FileInputStream; import java.io.IOException; import java.sql.*; import java.util.Properties; public class JDBCUtils { public static String url; public static String user; public static String password; public static String driver; //类加载时自动调用 static { Properties properties = new Properties(); try { properties.load(new FileInputStream("src//mysql.properties")); url = properties.getProperty("url"); user = properties.getProperty("user"); password = properties.getProperty("password"); driver = properties.getProperty("driver"); } catch (IOException e) { throw new RuntimeException(e); } } //获得一个连接 public static Connection con() { try { return DriverManager.getConnection(url, user, password); } catch (SQLException e) { throw new RuntimeException(e); } } //关闭传入的资源,资源不存在则传入null public static void close(ResultSet resultSet, Connection connection, Statement statement) { try { if (resultSet != null) { resultSet.close(); } if (connection != null) { connection.close(); } if (statement != null) { statement.close(); } } catch (SQLException e) { throw new RuntimeException(e); } } }
六、批处理
基本介绍
** 1. 当需要成批插入或者更新时,可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理,通常情况下要比单独提交处理更有效率。**
** 2. JDBC的批量处理语句包括下面方法:**
** addBatch():添加需要批量处理的SQL语句或参数**
** executeBatch():执行批量处理语句**
** clearBatch():清空批处理包的语句**
** 3. JDBC 连接MySQL时,如果要使用批处理功能,需要在url中添加参数****?rewriteBatchedStatements=true(切记切记)**
** 4. 批处理往往和PreparedStatement一起搭配使用,既能减少编译次数,又减少运行次数,效率大大提高。**
代码演示:
package JDBC.Batch_;
import JDBC.JDBCUtils;
import org.junit.jupiter.api.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class Batch_01 {
@Test
// 传统方法执行5000句SQL指令
public void m1() throws SQLException {
Connection con = JDBCUtils.con();
String sql = "insert into account values (?,?,?)";
PreparedStatement preparedStatement = con.prepareStatement(sql);
long begin = System.currentTimeMillis();
for (int i = 0; i < 5000; i++) {
preparedStatement.setInt(1, i);
preparedStatement.setString(2, "jack" + i);
preparedStatement.setInt(3, 22);
preparedStatement.executeUpdate();
}
long end = System.currentTimeMillis();
System.out.println(end - begin);//耗时2281ms
JDBCUtils.close(null, con, preparedStatement);
}
@Test
//批处理执行5000句SQL语句
public void m2() throws SQLException {
Connection con = JDBCUtils.con();
String sql = "insert into account values (?,?,?)";
PreparedStatement preparedStatement = con.prepareStatement(sql);
long begin = System.currentTimeMillis();
for (int i = 0; i < 5000; i++) {//执行5000次sql
preparedStatement.setInt(1, i);
preparedStatement.setString(2, "jack" + i);
preparedStatement.setInt(3, 20);
preparedStatement.addBatch();//往批处理包添加SQL语句
if ((i + 1) % 1000 == 0) {//批处理包添加1000条SQL语句后
preparedStatement.executeBatch();//执行该批处理包
preparedStatement.clearBatch();//清空该批处理包
}
}
long end = System.currentTimeMillis();
System.out.println(end - begin);//耗时51ms
JDBCUtils.close(null, con, preparedStatement);
}
}
七、数据库连接池
传统获取Connection问题分析
** 1. 传统的JDBC数据库连接使用DriverManager来获取,每次向数据库建立连接的时候都要将Connection加载到内存中,再验证IP地址,用户名和密码(0.05s - 1s 时间)。需要数据库连接时,就向数据库要求一个,频繁的进行数据库连接操作将占用很多的系统资源,容易造成服务器崩溃。**
** 2. 每一次数据库连接,使用完后都得断开,如果程序出现异常而未能关闭,将会导致数据库内存泄漏,最终将导致数据库重启。**
** 3. 传统获取连接方式,不能控制创建的连接数量,如连接过多,也可能导致内存泄漏,数据库崩溃。**
** 4. 为了解决传统开发中的数据库连接问题,可以采用数据库连接池技术。**
数据库连接池种类
** JDBC的数据库连接池使用javax.sql.DataSource来表示,DataSource只是一个接口,该接口通常由第三方提供实现。**
** 常见的数据库连接池有下面几种。**
** 1. C3P0 数据库连接池,速度相对较慢,稳定性不错。**
** 2. DBCP 数据库连接池,速度相对C3P0较快,但不稳定。**
** 3. Proxool 数据库连接池,有监控连接池状态的功能,稳定性较C3P0差一点。**
** 4. BoneCP 数据库连接池,速度快。**
** 5. Druid(德鲁伊)数据库连接池,由阿里提供,集DBCP,C3P0,Proxool 优点于一身的数据库连接池。****(后面主要介绍德鲁伊数据库连接池的使用)**
Druid数据库连接池
准备工作:1.将 druid.jar 文件添加到lib目录(点击蓝色字体即可下载)
** 2. 右键选择 Add as Library**
配置文件:1. 将下面配置信息存入 druid.properties 中
** 2. 将 druid.properties 存到 src 目录下**
#配置文件,根据自己的具体需求设置 #driverClassName=对应数据库的驱动路径 driverClassName=com.mysql.jdbc.Driver #url=jdbc:mysql://ip:端口/数据库?rewriteBatchedStatements=true url=jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true #username=你的用户名 password=对应的密码 username=root password=123456 #初始化连接数量 initialSize=20 #最小连接数量 minIdle=20 #最大连接数量 maxActive=50 #最大等待时间 maxWait=5000
代码演示:
package JDBC.Druid;
import JDBC.JDBCUtils;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.junit.jupiter.api.Test;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
//传统连接数据库和通过数据池连接对比
public class Druid01 {
@Test
//连续连接数据库5000次,每次连接完不关闭
//出现错误提示:Too many connections
public void m1() {
for (int i = 0; i < 5000; i++) {
//错误信息
// Data source rejected establishment of connection,
// message from server: "Too many connections"
Connection con = JDBCUtils.con();
}
}
//连接5000次数据库,每次连接完都关闭
@Test
public void m2() throws SQLException {
long l = System.currentTimeMillis();
for (int i = 0; i < 5000; i++) {
Connection con = JDBCUtils.con();
con.close();
}
long l1 = System.currentTimeMillis();
System.out.println(l1 - l);//耗时4385ms
}
//使用druid连接池连接数据库
//获取5000次连接
@Test
public void m3() throws Exception {
Properties properties = new Properties();
properties.load(new FileInputStream("src//druid.properties"));
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
long l = System.currentTimeMillis();
for (int i = 0; i < 5000; i++) {
Connection connection = dataSource.getConnection();
connection.close();
}
long l1 = System.currentTimeMillis();
System.out.println(l1 - l);//耗时311ms
}
}
package JDBC.Druid;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
public class Druid011 {
public static void main(String[] args) throws Exception {
Properties properties = new Properties();
properties.load(new FileInputStream("src//druid.properties"));
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
Connection connection = dataSource.getConnection();
String sql = "select * from account";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
System.out.print(resultSet.getInt(1) + "\t");
System.out.print(resultSet.getString(2) + "\t");
System.out.println(resultSet.getInt(3));
}
connection.close();
resultSet.close();
preparedStatement.close();
}
}
JDBCUtilsByDruid工具类
** 在JDBCUtils工具类的基础上,将基于Druid数据库连接池的获取连接和释放资源操作封装成方法。**
package JDBC; 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; public class JDBCUtilsByDruid { public static DataSource dataSource = null; public static Properties properties = null; static { try { properties = new Properties(); properties.load(new FileInputStream("src//druid.properties")); dataSource = DruidDataSourceFactory.createDataSource(properties); } catch (Exception e) { throw new RuntimeException(e); } } public static Connection getConnection() { try { return dataSource.getConnection(); } catch (SQLException e) { throw new RuntimeException(e); } } public static void close(ResultSet resultSet, Connection connection, Statement statement) { try { if (resultSet != null) resultSet.close(); if (connection != null) connection.close(); if (statement != null) statement.close(); } catch (SQLException e) { throw new RuntimeException(e); } } }
八、Apache-DBUtils类库
基本介绍
** 1. commons - dbutils 是Apache 组织提供的一个开源JDBC工具类库,它是对JDBC的封装,使用dbutils能极大简化jdbc编码的工作量。**
** 2. QueryRunner类:该类封装了SQL的执行,是线程安全的。可以实现增、删、改、查、批处理。**
** 3. ResultSetHandler接口:该接口用于处理 java.sql.ResultSet,将数据按要求转换为另一种形式。其部分实现类如下:**
使用DBUtils类库进行查询操作
** 准备工作:**
** 1. 将 commons-dbutils.jar 文件添加到lib目录中(点击蓝色字体即可下载)**
** 2. 右键选择 Add as Library**
package JDBC.Druid; import JDBC.JDBCUtils; import JDBC.JDBCUtilsByDruid; import JDBC.student; 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.jupiter.api.Test; import java.sql.*; import java.util.ArrayList; import java.util.List; public class Druid02 { @Test //传统思路 public void test1() throws SQLException { Connection con = JDBCUtils.con(); PreparedStatement preparedStatement = con.prepareStatement("select * from jdbc"); ResultSet resultSet = preparedStatement.executeQuery(); ArrayList<student> students = new ArrayList<>(); while (resultSet.next()) { int id = resultSet.getInt(1); String name = resultSet.getString(2); int age = resultSet.getInt(3); students.add(new student(id, name, age)); } JDBCUtils.close(resultSet, con, preparedStatement); for (student student : students) { System.out.println(student); } } //使用DBUtils类库进行查询操作 // 查询多行多列数据 @Test public void m1() throws SQLException { Connection connection = JDBCUtilsByDruid.getConnection(); QueryRunner queryRunner = new QueryRunner(); List<student> query = queryRunner.query(connection, "select * from jdbc", new BeanListHandler<>(student.class)); /* 注意:student类必须有无参构造器和 set 函数 若无参构造器不存在,则无法实例化对象 若set 不存在,则无法赋值,所有属性都会被赋一个默认值 */ System.out.println(query); JDBCUtilsByDruid.close(null, connection, null); } @Test //查询单行数据 public void m2() throws SQLException { Connection connection = JDBCUtilsByDruid.getConnection(); QueryRunner queryRunner = new QueryRunner(); student query = queryRunner.query(connection, "select * from jdbc where id = 1", new BeanHandler<>(student.class)); System.out.println(query); JDBCUtilsByDruid.close(null, connection, null); } @Test //返回单行单列数据 public void m3() throws SQLException { Connection connection = JDBCUtilsByDruid.getConnection(); QueryRunner queryRunner = new QueryRunner(); Object query = queryRunner.query(connection, "select name from jdbc where id = 2", new ScalarHandler()); System.out.println(query); JDBCUtilsByDruid.close(null, connection, null); } }
使用DBUtils类库进行增删改操作
package JDBC.Druid; import JDBC.JDBCUtilsByDruid; import org.apache.commons.dbutils.QueryRunner; import org.junit.jupiter.api.Test; import java.sql.Connection; import java.sql.SQLException; public class Druid03 { //测试插入数据 @Test public void m1() throws SQLException { Connection connection = JDBCUtilsByDruid.getConnection(); QueryRunner queryRunner = new QueryRunner(); int update = queryRunner.update(connection, "insert into jdbc values(4,'erson',45)"); System.out.println(update > 0 ? "yes" : "no"); JDBCUtilsByDruid.close(null, connection, null); } @Test //测试更改数据 public void m2() throws SQLException { Connection connection = JDBCUtilsByDruid.getConnection(); QueryRunner queryRunner = new QueryRunner(); int update = queryRunner.update(connection, "update jdbc set name = 'Lihua' where id = 1 "); System.out.println(update > 0 ? "yes" : "no"); JDBCUtilsByDruid.close(null, connection, null); } @Test //测试删除数据 public void m3() throws SQLException { Connection connection = JDBCUtilsByDruid.getConnection(); QueryRunner queryRunner = new QueryRunner(); int update = queryRunner.update(connection, "delete from jdbc where id =4"); System.out.println(update > 0 ? "yes" : "no"); JDBCUtilsByDruid.close(null, connection, null); } }
九、最后的话
✨ 原创不易,还希望各位大佬支持一下
👍 点赞,你的认可是我创作的动力!
⭐️ 收藏,你的青睐是我努力的方向!
✏️ 评论,你的意见是我进步的财富!
版权归原作者 爱笑的钮布尼茨 所有, 如有侵权,请联系我们删除。