一_JDBC概述
1. JDBC是什么
英文全称:Java DataBase Connectivity
中文全称:Java 数据库连接技术
2. JDBC的作用
与数据库建立连接并对数据库执行操作:增删改查操作
3. JDBC的组成
由一组官方定义的接口(规范)组成:接口的实现类由数据库厂商提供:数据库驱动(包含实现操作数据库接口的类)
4. JDBC的好处
代码不依赖于任何数据库。
只需要修改少量配置就可以方便切换到其他厂商数据库。
JDBC核心类和接口 |
说明 |
Connection 接口 |
|
Statement 接口 |
|
ResultSet 接口 |
|
Drvier 接口 | 数据库驱动对象 |
示例代码
import com.mysql.jdbc.Driver; import java.sql.DriverManager; /** 目标: 1. 理解注册驱动的作用:告诉JVM接下来要操作哪个厂商的数据库了 2. 掌握注册驱动的方式 DriverManger工具类与注册驱动相关的方法 * static registerDriver(Driver driver) * 注册数据库驱动 * 存在问题:驱动会被注册两次 */ public class Demo01 { public static void main(String[] args) throws Exception{ // 方式1:存在问题:驱动会被注册两次 // 创建驱动对象(Driver是mysql厂商提供Driver接口的实现类) /*Driver driver = new Driver(); // 注册驱动 DriverManager.registerDriver(driver);*/ // 方式二:利用反射触发Driver实现类的加载实现驱动注册 Class.forName("com.mysql.jdbc.Driver"); } }
注册驱动的作用:告诉JVM接下来要操作哪个厂商的数据库了
注册驱动方法 | 说明 |
static registerDriver(Driver driver) | 驱动会注册两次 |
Class.forName("com.mysql.jdbc.Driver") | 只会注册一次 |
import java.io.FileInputStream; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.util.Properties; /** 目标:与数据库建立连接并获得Connection对象 DriverManager工具类与获得连接对象相关的方法 * static Connection getConnection(String url, String user, String password) * 与数据库建立连接并返回连接对象 * url: 数据库连接字符串 * user: 用户名 root * password: 密码 root * static Connection getConnection(String url, Properties info) * 与数据库建立连接并返回连接对象 * url: 数据库连接字符串 * info: 属性集合(双列集合,用法和map一样):用来存储用户名和密码 * 可以将用户名和密码配置在文件中 数据库连接字符串格式: 完整格式:JDBC协议:子协议://数据库服务器地址:端口号/数据库名 * JDBC协议:固定值是:jdbc * 子协议:一般是数据库厂商的名字,比如mysql或oracle 省略格式:JDBC协议:子协议:/// 数据库名 * 前提条件:操作本机数据库且端口号是默认值3306 MySQL数据库连接字符串完整格式:jdbc:mysql://localhost:3306/day11 MySQL数据库连接字符串省略格式:jdbc:mysql:///day11 */ public class Demo01 { public static void main(String[] args) throws Exception{ // 方式1: 获得连接对象 // test01(); // 方式2:获得连接对象 test02(); } /** * 获得连接对象 */ private static void test02() throws Exception { // 1. 注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2. 创建属性集对象 // 键和值都是String类型 Properties info = new Properties(); // 创建输入流关联配置文件 InputStream in = Demo01.class.getResourceAsStream("/jdbc.properties"); // 从文件中加载数据到集合中 info.load(in); System.out.println(info);// {user=root, password=root} /*info.setProperty("user", "root"); info.setProperty("password", "root");*/ // 2. 获得连接对象 Connection conn = DriverManager.getConnection("jdbc:mysql:///day11", info); System.out.println(conn); } /** * 获得连接对象 */ private static void test01() throws Exception{ // 1. 注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2. 获得连接对象 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day11", "root", "root"); System.out.println(conn); } }
小结
DriverManager类与数据库建立连接的方法 | 说明 |
获得连接对象 |
Statement对象常用方法 | 说明 |
boolean execute(String sql) | |
int executeUpdate(String sql) | |
ResultSet executeQuery(String sql) | 用于执行查询语句 |
import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; /** 目标:使用JDBC在MySQL的数据库中创建一张学生表 1) id 是主键,整数类型,自增长 2) name 是varchar(20),非空 3) 性别 是char类型 4) 生日 是date类型 */ public class Demo01 { public static void main(String[] args) throws Exception{ // 1. 注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2. 获得连接对象 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day11", "root", "root"); // 3. 获得SQL语句发送对象 Statement stmt = conn.createStatement(); // 4. 准备SQL语句 String sql = "create table student(" + "id int primary key auto_increment," + "name varchar(20) not null," + "gender char(1)," + "birthday date);"; // 5. 调用发送对象的方法执行SQL stmt.execute(sql); // 6. 释放资源 stmt.close(); conn.close(); } }
小结
使用JDBC在数据库创建数据表的步骤
1. 注册驱动:Class.forName("驱动类全名字符串");
2. 获得连接对象:Connection conn = DriverManger.getConnection("连接字符串","用户名","密码");
3. 获得SQL语句发送对象:Statement stmt = conn.createStatement();
4. 准备SQL语句:String sql="....";
5. 调用SQL语句发送对象的方法:stmt.execute...(sql);
6. 关闭连接释放资源
import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; /** 目标:使用JDBC实现增删改功能 */ public class Demo01 { public static void main(String[] args) throws Exception{ // 插入数据 // testInsert(); // 更新数据 // testUpdate(); // 删除数据 testDelete(); } // 插入数据 public static void testInsert()throws Exception{ // 1. 注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2. 获得连接对象 Connection conn = DriverManager.getConnection("jdbc:mysql:///day11", "root", "root"); // 3. 获得SQL语句发送对象 Statement stmt = conn.createStatement(); // 4. 准备SQL语句 String sql = "insert into student values(null,'rose','女','2000-12-20'),(null,'luck','男','1990-02-21');"; // 5. 调用SQL语句发送对象的方法 int row = stmt.executeUpdate(sql); System.out.println("row = " + row); // 6. 关闭连接释放资源 stmt.close(); conn.close(); } // 修改数据:将id为3的学生性别修改为女,姓名修改为:lily public static void testUpdate()throws Exception{ // 1. 注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2. 获得连接对象 Connection conn = DriverManager.getConnection("jdbc:mysql:///day11", "root", "root"); // 3. 获得SQL语句发送对象 Statement stmt = conn.createStatement(); // 4. 准备SQL语句 String sql = "update student set gender = '女', name='lily' where id = 3;"; // 5. 调用SQL语句发送对象的方法 int row = stmt.executeUpdate(sql); System.out.println("row = " + row); // 1 // 6. 关闭连接释放资源 stmt.close(); conn.close(); } // 删除数据:把id为2的学生删除 public static void testDelete() throws Exception{ // 1. 注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2. 获得连接对象 Connection conn = DriverManager.getConnection("jdbc:mysql:///day11", "root", "root"); // 3. 获得SQL语句发送对象 Statement stmt = conn.createStatement(); // 4. 准备SQL语句 String sql = "delete from student where id = 2"; // 5. 调用SQL语句发送对象的方法 int row = stmt.executeUpdate(sql); System.out.println("row = " + row); // 1 // 6. 关闭连接释放资源 stmt.close(); conn.close(); } }
小结
使用JDBC在数据库创建数据表的步骤
1. 注册驱动:Class.forName("驱动类全名字符串");
2. 获得连接对象:Connection conn = DriverManger.getConnection("连接字符串","用户名","密码");
3. 获得SQL语句发送对象:Statement stmt = conn.createStatement();
4. 准备SQL语句:String sql="....";
5. 调用SQL语句发送对象的方法:stmt.execute...(sql);
6. 关闭连接释放资源
小结
ResultSet对象常用方法 | 说明 |
boolean next() | |
Xxx getXxx(列号或列名) | 根据列号或列名获得当前行指定列的数据 |
import java.sql.*; /** 目标:使用JDBC实现查询功能 需求:查询所有学生信息并输出到控制台 注意事项: 1. 当指针执行结果集的第一行之前,调用了getXxx方法获取数据则会出现下面异常: java.sql.SQLException: Before start of result set 2. 当指针执行结果集的最后一行之后,调用了getXxx方法获取数据则会出现下面异常: java.sql.SQLException: After end of result set */ public class Demo01 { public static void main(String[] args) throws Exception { // 1. 注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2. 获得连接对象 Connection conn = DriverManager.getConnection("jdbc:mysql:///day11", "root", "root"); // 3. 获得SQL语句发送对象 Statement stmt = conn.createStatement(); // 4. 准备SQL语句 String sql = "select * from student"; // 5. 执行SQL语句并获得结果集对象 ResultSet rs = stmt.executeQuery(sql); // 循环获取每一行数据 // 将指针下移一行、 while(rs.next()){ // 根据列号获取每一列的值 /* int id = rs.getInt(1); String name = rs.getString(2); String gender = rs.getString(3); String birthday = rs.getString(4);*/ // 根据列名获取每一列的值 int id = rs.getInt("id"); String name = rs.getString("name"); String gender = rs.getString("gender"); Date birthday = rs.getDate("birthday"); System.out.println(id+","+name+","+gender+"," + birthday); } // 6. 关闭连接释放资源 rs.close(); stmt.close(); conn.close(); } }
-
-
准备数据:创建账号表和添加用户数据
-
1. 注册驱动 2. 获得连接对象并开启事务 3. 获取SQL发送对象 4. 准备扣钱SQL语句 5. 执行扣钱SQL语句 6. 准备加钱SQL语句 7. 执行加钱SQL语句 8. 如果没有问题则提交事务,否则回滚事务 9. 关闭资源
示例代码
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; /** 目标:使用JDBC实现事务管理 需求:Jack给rose转500块 实现步骤 1. 注册驱动 2. 获得连接对象 3. 获取SQL发送对象 4. 准备扣钱SQL语句 5. 执行扣钱SQL语句 6. 准备加钱SQL语句 7. 执行加钱SQL语句 8. 关闭资源 Connection对象与事务管理相关的方法 * void setAutoCommit(boolean b) * 设置是否自动提交事务 * b:true 自动提交,默认值 * b:false 禁止自动提交 ==> 相当于start transaction;手动开启事务 * void commit(); * 提交事务 * void rollback(); * 回滚事务 */ public class Demo01 { public static void main(String[] args){ // 声明连接对象 Connection conn = null; Statement stmt = null; try{ // 1. 注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2. 获得连接对象 conn = DriverManager.getConnection("jdbc:mysql:///day11", "root", "root"); // 开启事务:等价start transaction; conn.setAutoCommit(false); // 3. 获取SQL发送对象 stmt = conn.createStatement(); // 4. 准备扣钱SQL语句 String sql01 = "update account set balance = balance - 500 where id = 1"; // 5. 执行扣钱SQL语句 int row = stmt.executeUpdate(sql01); System.out.println("扣钱:" + row); // 模拟异常 System.out.println(10/0); // 6. 准备加钱SQL语句 String sql02 = "update account set balance = balance + 500 where id = 2"; // 7. 执行加钱SQL语句 row = stmt.executeUpdate(sql02); System.out.println("加钱:" + row); // 提交事务 conn.commit(); } catch(Exception e){ System.out.println("回滚了事务..."); try { if (conn != null) conn.rollback(); // 回滚事务 } catch (SQLException ex) { ex.printStackTrace(); } } finally { // 8. 关闭资源 if (stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn !=null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
小结
Connection接口中与事务相关的方法 | 说明 | |
void setAutCommit(boolean b); |
|
|
void commit() | 提交事务 | |
void rollback() | 回滚事务 |
import java.sql.*; /** 创建工具类的目的:将重复的代码定义到某个类的方法中,直接调用方法,可以简化代码。 实现工具类的步骤 1. 将固定字符串定义为常量 2. 在静态代码块中注册驱动(只注册一次) 3. 提供一个获取连接的方法:static Connection getConnection(); 4. 定义关闭资源的方法:close(Connection conn, Statement stmt, ResultSet rs) 5. 重载关闭方法:close(Connection conn, Statement stmt) */ public class JDBCUtil { // 1. 将固定字符串定义为常量 private static final String DRIVER_CLASS = "com.mysql.jdbc.Driver"; private static final String URL = "jdbc:mysql:///day11"; private static final String USER = "root"; private static final String PASSWORD = "root"; /** * 2. 在静态代码块中注册驱动(只注册一次) */ static { try { // 1. 注册驱动 Class.forName(DRIVER_CLASS); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /* * 3. 提供一个获取连接的方法:static Connection getConnection(); * */ public static Connection getConnection() { try{ return DriverManager.getConnection(URL, USER,PASSWORD); } catch(Exception e){ // return null; // 将编译时异常包装成运行时异常 throw new RuntimeException(e); } } // 4. 定义关闭资源的方法:close(Connection conn, Statement stmt, ResultSet rs) public static void close(Connection conn, Statement stmt, ResultSet rs){ /** 关闭资源注意事项:先开后关(先创建的后关闭) 1. 创建顺序:Connection ==> Statement ==> ResultSet 2. 关闭顺序:ResultSet ==> Statement ==> Connectio */ if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn !=null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } // 5. 重载关闭方法:close(Connection conn, Statement stmt) public static void close(Connection conn, Statement stmt){ close(conn, stmt, null); } }
案例需求
模拟用户输入账号和密码登录网站
输入正确的账号,密码,显示登录成功
输入错误的账号,密码,显示登录失败
示例代码
1、准备数据表和用户数据
create table user( id int primary key auto_increment, username varchar(20) not null unique, password varchar(20) not null ); insert into user(username,password) values('jack','rose'),('rose','laowang'); select * from user; select * from user where username = 'jack' and password = 'rose';
2、实现登录
import com.pkx._07utlis.JDBCUtil; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import java.util.Scanner; /** * 目标:实现用户登录 实现步骤: 1. 创建键盘录入对象:Scanner 2. 接收用户名和密码 3. 获得连接对象 4. 获得SQL语句发送对象 5. 准备要执行的SQL语句:登录SQL 6. 执行查询语句获得结果集对象 7. 判断是否登录成功 8. 释放资源 */ public class LoginDemo { public static void main(String[] args) throws Exception{ // 1. 创建键盘录入对象:Scanner Scanner sc = new Scanner(System.in); // 2. 接收用户名和密码 System.out.println("请输入用户名:"); // jack String username = sc.nextLine(); System.out.println("请输入密码:"); // rose String password = sc.nextLine(); // 3. 获得连接对象 Connection conn = JDBCUtil.getConnection(); // 4. 获得SQL语句发送对象 Statement stmt = conn.createStatement(); // 5. 准备要执行的SQL语句:登录SQL String sql = "select * from user where username = '"+username+"' and password = '"+password+"';"; System.out.println("sql = " +sql); // 6. 执行查询语句获得结果集对象 ResultSet rs = stmt.executeQuery(sql); // 7. 判断是否登录成功 if (rs.next()){ System.out.println("欢迎你:" +username); } else { System.out.println("用户名或密码错误"); } // 8. 释放资源 JDBCUtil.close(conn, stmt, rs); } }
请输入用户名:
hehe
请输入密码:
a' or '1'='1
问题分析
// 代码中的SQL语句 "SELECT * FROM user WHERE name='" + name + "' AND password='" + password + "';"; // 将用户输入的账号密码拼接后 "SELECT * FROM user WHERE name='hehe' AND password='a' or '1'='1';"
小结
什么是SQL注入:用户输入的内容和SQL语句进行了拼接,用户输入的内容作为了SQL语法的一部分,改变了原有SQL语句的含义
-
-
PreparedStatement对象的作用:用来发送SQL语句到数据库执行增删改查操作
-
PreparedStatement接口常用方法 | 说明 |
int executeUpdate(); | |
ResultSet executeQuery(); |
import com.pkx._07utlis.JDBCUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Statement; import java.util.Scanner; /** * 目标:理解SQL注入的概念 什么是SQL注入:用户输入的内容和SQL语句进行了拼接,用户输入的内容作为了SQL语法的一部分,改变了原有SQL语句的含义。 如何解决SQL注入问题:用户输入的内容不要和SQL语句进行拼接,此时不能使用Statement来发送SQL,需要使用PreparedStatement 来发送SQL语句到数据库执行了。 sql = select * from user where username = 'jack' and password = 'a' or '1'='1'; 使用PreparedStatement解决SQL注入问题 */ public class LoginDemo02 { public static void main(String[] args) throws Exception{ // 1. 创建键盘录入对象:Scanner Scanner sc = new Scanner(System.in); // 2. 接收用户名和密码 System.out.println("请输入用户名:"); // jack String username = sc.nextLine(); System.out.println("请输入密码:"); // rose String password = sc.nextLine(); // 3. 获得连接对象 Connection conn = JDBCUtil.getConnection(); // 4. 准备要执行的SQL语句:登录SQL // 4.1 未知内容使用占位符?代替:用户名和密码就属于未知内容 String sql = "select * from user where username = ? and password = ? ;"; System.out.println("sql = " +sql); // 5. 获得预编译对象:PreparedStatement PreparedStatement ps = conn.prepareStatement(sql); // 5.1 使用真实数据替换占位符?:给占位符问号赋值具体内容 // 参数1:占位符的索引值,默认是从1开始 // 参数2:占位符问号赋值的具体内容 ps.setString(1,username); ps.setString(2,password); // 6. 执行查询语句获得结果集对象 ResultSet rs = ps.executeQuery(); // 7. 判断是否登录成功: a' or '1'='1 if (rs.next()){ System.out.println("欢迎你:" +username); } else { System.out.println("用户名或密码错误"); } // 8. 释放资源 JDBCUtil.close(conn, ps, rs); } }
小结
解决SQL注入问题的核心思想是:
1. 用户输入的内容不要和SQL语句进行拼接
2. 使用PreparedStateme对象执行SQL语句
相同点:都可以对数据库执行增删改查操作。 不同点: 1. PreparedStatement有预编译功能,Statement没有预编译功能。 2. PreparedStatement有缓存功能(缓存SQL语句的编译结果),Statement没有缓存功能。 3. PreparedStatement没有SQL注入,更安全,Statement有SQL注入,不安全。
十七.
1. 什么是连接池 一个负责创建和管理连接对象的容器(集合) 2. 为什么需要使用连接池 因为频繁的创建和销毁连接是很耗资源(内存资源和时间资源)的过程。 使用连接池可以减少频繁创建和效率连接带来的系统开销。 从而提高访问数据库的效率 3. 连接池的核心思想:连接复用 4. 连接池规范:DataSource
<c3p0-config> <!-- 使用默认的配置读取连接池对象 --> <default-config> <!-- 连接参数 --> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/day25</property> <property name="user">root</property> <property name="password">root</property> <!-- 连接池参数 --> <property name="initialPoolSize">5</property> <property name="maxPoolSize">10</property> <property name="checkoutTimeout">2000</property> <property name="maxIdleTime">1000</property> </default-config> <named-config name="pkxingc3p0"> <!-- 连接参数 --> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/day25</property> <property name="user">root</property> <property name="password">root</property> <!-- 连接池参数 --> <property name="initialPoolSize">5</property> <property name="maxPoolSize">15</property> <property name="checkoutTimeout">2000</property> <property name="maxIdleTime">1000</property> </named-config> </c3p0-config>
2.示例代码
import com.mchange.v2.c3p0.ComboPooledDataSource; import javax.sql.DataSource; import java.sql.Connection;
public class Demo01 { public static void main(String[] args) throws Exception{ // 3. 创建连接池对象 // 使用默认配置创建 // DataSource ds = new ComboPooledDataSource(); // 使用命名配置创建 DataSource ds = new ComboPooledDataSource("pkxingc3p0"); // 循环从连接池中获取连接对象 for (int i = 0; i < 16; i++) { // 调用连接池对象的方法获得连接对象 Connection conn = ds.getConnection(); System.out.println(i+ "==>" +conn); // ...... if (i == 5){ // 关闭连接对象:不是真正的关闭,而是将连接对象放回连接池中等待复用。 conn.close(); } } } }
ComboPooledDataSource构造方法 | 说明 |
ComboPooledDataSource() | |
使用步骤
1. 导入c3p0相关jar包 2. 准备c3p0配置文件 2.1 配置文件要求 命名要求:c3p0-config.xml 位置要求:在src目录下 2.2 配置信息 数据库信息: 数据库驱动:com.mysql.jdbc.Driver 数据库地址: url 用户名: user 密码:password 连接池信息: 初始化连接数:5 最大连接数:10 最大等待时间:3000毫秒 最大空闲时间:3000毫秒 3. 创建连接池对象 4. 调用连接池对象的方法获得连接对象 ...... 5. 关闭连接对象:不是真正的关闭,而是将连接对象放回连接池中等待复用。
DruidDataSourceFactory类静态方法 | 说明 |
public static DataSource createDataSource(Properties properties) | 创建连接池对象 |
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/day25 username=root password=root initialSize=5 maxActive=10 maxWait=3000 maxIdle=6 minIdle=3
示例代码
import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.InputStream; import java.sql.Connection; import java.util.Properties; /** * 目标:创建Druid连接池并从池中获得连接对象 */ public class Demo01 { public static void main(String[] args)throws Exception { // 1. 创建集合用来存储配置信息 Properties info = new Properties(); System.out.println(info); // 2. 加载配置文件信息到集合中 // 2.1 获得与配置文件关联的输入流 // InputStream in = Demo01.class.getResourceAsStream("/druid.properties"); info.load(Demo01.class.getResourceAsStream("/druid.properties")); System.out.println(info); // 3. 创建连接池对象 DataSource ds = DruidDataSourceFactory.createDataSource(info); // 4. 从连接池中获得连接对象 for (int i = 0; i < 11; i++) { Connection conn = ds.getConnection(); System.out.println(i+"===>"+conn); // ..... if (i==5){ // 5. 关闭连接对象:不是真正关闭而是放回池中 conn.close(); } } } }
小结
Druid连接池的使用步骤 1. 导入相关jar 2. 准备配置文件:xxx.properties 2.1 配置数据库信息 2.2 配置连接池信息 3. 创建属性集对象:Properties 3.1 加载配置文件信息到属性集对象中 4. 通过Driud提供的工具类方法创建数据源对象 5. 调用数据源对象的方法获得连接对象:getConnection .... 6. 调用连接对象方法将连接对象关闭返回池中
import com.alibaba.druid.pool.DruidDataSourceFactory; import com.mchange.v2.c3p0.ComboPooledDataSource; import com.pkx._11druid.Demo01; import javax.sql.DataSource; import java.sql.*; import java.util.Date; import java.util.Properties; /** 数据源工具类实现步骤 1) 创建私有静态数据源成员变量 DataSource ds 2) 在静态代码块中创建连接池 a) 创建属性集对象 b) 从类路径下加载属性文件,得到输入流对象 c) 通过工厂类创建一个数据源 3) 创建公有的得到数据源的方法 getDataSource() 4) 创建得到连接对象的方法 getConnection() 5) 创建释放资源的方法 close(Connction conn, Statement stmt, ResultSet rs) */ public class DataSourceUtil { // 1) 创建私有静态数据源成员变量 DataSource ds private static DataSource ds = null; // 2) 在静态代码块中创建连接池:只需要创建1个 static { try{ // a) 创建属性集对象 Properties info = new Properties(); // b) 从类路径下加载属性文件,得到输入流对象 info.load(Demo01.class.getResourceAsStream("/druid.properties")); // c) 通过工厂类创建一个数据源 ds = DruidDataSourceFactory.createDataSource(info); } catch(Exception e){ e.printStackTrace(); } } // 3) 创建公有的得到数据源的方法 getDataSource() public static DataSource getDataSource(){ return ds; } // 4) 创建得到连接对象的方法 getConnection() public static Connection getConnection() { try{ return ds.getConnection(); } catch(Exception e){ // 将编译时异常包装成运行时异常 throw new RuntimeException(e); } } // 5. 定义关闭资源的方法:close(Connection conn, Statement stmt, ResultSet rs) public static void close(Connection conn, Statement stmt, ResultSet rs){ /** 关闭资源注意事项:先开后关(先创建的后关闭) 1. 创建顺序:Connection ==> Statement ==> ResultSet 2. 关闭顺序:ResultSet ==> Statement ==> Connectio */ if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn !=null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } // 重载关闭方法:close(Connection conn, Statement stmt) public static void close(Connection conn, Statement stmt){ close(conn, stmt, null); } }
import com.alibaba.druid.pool.DruidDataSourceFactory; import com.pkx._11druid.Demo01; import javax.sql.DataSource; import java.sql.*; import java.util.Properties; /** 数据源工具类的测试 */ public class DataSourceUtilDemo { public static void main(String[] args) throws Exception{ // 获得连接对象 Connection conn = DataSourceUtil.getConnection(); // 获得预编译对象 PreparedStatement ps = conn.prepareStatement("insert into student values(null,?,?,?)"); // 给问号赋值 ps.setString(1 ,"老王"); ps.setString(2 ,"男"); ps.setString(3 ,"2020-01-20"); // 执行SQL语句 int row = ps.executeUpdate(); System.out.println(row); // 关闭资源 DataSourceUtil.close(conn, ps); } }
小结
数据源工具类实现步骤 1) 创建私有静态数据源成员变量 DataSource ds 2) 在静态代码块中创建连接池 a) 创建属性集对象 b) 从类路径下加载属性文件,得到输入流对象 c) 通过工厂类创建一个数据源 3) 创建公有的得到数据源的方法 getDataSource() 4) 创建得到连接对象的方法 getConnection() 5) 创建释放资源的方法 close(Connction conn, Statement stmt, ResultSet rs)
JDBC就介绍到这里,如果有总结得不好的地方,欢迎指正!