JDBC(Java Data Base Connectivity,Java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。
Java对外指定一些编程标准,其它数据库服务器厂商按照这个标准,编写对应的实现方案。这样对于Java程序员而言,只需要学习Java的标准即可,不需要了解不同厂商的实现细节。一切操作都是在学习接口开发。按照接口指定的标准完成指定需要完成的业务即可。
- 为了将数据持久的存储、固化到磁盘上我们需要掌握数据库。
- 为了通过Java代码完成对于数据的持久存储我们需要学习JDBC。
- 通过JDBC我们能够以面向接口方式,操作数据库中的数据,更加的方便。
- 本身Java就是跨平台的,通过Java开发的JDBC应用可以在不同的平台上执行。
- JDBC为数据库开发提供了标准的API,所以使用JDBC开发的数据库应用也可以跨数据库(要求全部使用标准的SQL)
JDBC和ODBC的区别和联系:
ODBC:
它使用 C 语言接口,是一组对数据库访问的标准API,这些API通过SQL来完成大部分任务,而且它本身也支持SQL语言,支持用户发来的SQL。ODBC定义了访问数据库API的一组规范,这些API独立于形色各异的DBMS和编程语言。
JDBC:
是Java与数据库的接口规范,JDBC定义了一个支持标准SQL功能的通用低层API,它由Java 语言编写的类和接口组成,旨在让各数据库开发商为Java程序员提供标准的数据库API。
常见JDBC驱动:
Java程序员如果想要和数据库打交道就必须要掌握JDBC。
如果你的业务模型中需要将数据持久化存储就必须掌握JDBC。
更多资料添加QQ:1708434248 v:magejava
[外链图片转存失败(img-lDgEyDIq-1562727277939)(img_jdbc\1558841462677.png)]
1) 手动导入需要连接数据库的jar包
2) 加载驱动
3) 创建连接对象
4) 声明sql语句
5) 创建处理sql语句对象
6) 发送sql语句,接收返回结果
7) 处理结果
8) 关闭资源连接
连接oracle就导入jdbc的jar包,参照附录到安装对应数据库可以在内部找到jar包;
连接mysql就导入mysql-connector的jar包,到官网下载对应版本jar包,或在maven仓库下载jar包。
@Test
public void searchOne() {
//提升作用域 方便后期关闭资源
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2:获取连接对象
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/note",
"root","root");
//3:声明sql语句
String sql = "SELECT * FROM TB_USER WHERE ID = 1";
//4:创建处理对象
stmt = conn.createStatement();
//5:发送sql语句获取结果集(如果是查询操作才存在结果集)
rs = stmt.executeQuery(sql);
//6. 迭代结果集
while(rs.next()) {
//7:分析结果集
System.out.println(rs.getString("name"));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
//8:关闭资源
try {
if(rs!=null)
rs.close();
if(stmt!=null)
stmt.close();
if(conn!=null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
A. 为什么要加载驱动?
I. 通过Class.forName(“Driver类的路径名”);
II.查看Mysql的Driver类
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
//在初始化的时候,就将当前数据库对象的驱动加载到sql的注册中心中去
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
}
B.获取连接源码
//获取连接就是会将连接信息包装为Properties
public static Connection getConnection(String url,
String user, String password) throws SQLException {
java.util.Properties info = new java.util.Properties();
if (user != null) {
info.put("user", user);
}
if (password != null) {
info.put("password", password);
}
return (getConnection(url, info, Reflection.getCallerClass()));
}
C.常见对象:
对象名称 | 获取方式 | 用途 |
---|---|---|
DriverManager | 用来管理JDBC驱动的服务类,主要用来获取Connection。 | |
Connection | DriverManager.getConnection(url,name,pwd); | 代表一个物理连接会话,如果要操作数据库必须先获取数据库连接对象。 |
Statement | Connection.createStatement(); | 用于执SQL语句的对象。常见的有Statement、PreparedStatement、CallableStatement |
ResultSet(针对查询) | Statement.executQuery(sql); | 结果集对象,包含了对于访问查询结果的方法。 |
@Test
public void updateNameById() {
//1:声明用户修改的id
Integer id = 1;
//2:声明修改后的名称
String newName= "大锤";
//3:声明连接对象
Connection conn = null;
Statement stmt = null;
try {
//4:加载驱动
Class.forName("com.mysql.jdbc.Driver");
//5:获取连接对象
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/note",
"root","root");
stmt = conn.createStatement();
//6:声明sql语句
String sql = "UPDATE TB_USER SET NAME = '"+newName+"'WHERE USERID = "+id;
//7:发送sql语句 接受返回结果
int rows = stmt.executeUpdate(sql);
System.out.println("修改了"+rows+"行记录");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
//8:关闭资源
try {
if(stmt!=null) {
stmt.close();
}
if(conn!=null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
1. 修改操作返回的是受影响的行数
2. 加载驱动只需要一次,不需要每次都加载驱动
public class JDBCTest01 {
Connection conn = null;
Statement stmt = null;
@Before
public void load() {
//1:加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
@Test
public void deleteById() {
try {
//5:获取连接对象
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/note",
"root","root");
stmt = conn.createStatement();
//6:声明sql语句
String sql = "DELETE FROM TB_USER WHERE ID = 1";
//7:发送sql语句 接受返回结果
int rows = stmt.executeUpdate(sql);
System.out.println("删除了"+rows+"行记录");
} catch (SQLException e) {
e.printStackTrace();
}
}
@After
public void close() {
try {
if(stmt!=null) {
stmt.close();
}
if(conn!=null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
* 1:删除操作作为DML语句的一种,返回的也是受影响的行数。
public class JDBCTest01 {
Connection conn = null;
Statement stmt = null;
@Before
public void load() {
//1:加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
@Test
public void insert() {
try {
User u = new User("wangdachui", "123456",'王大锤', 18, "男");
//5:获取连接对象
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/note",
"root","root");
stmt = conn.createStatement();
//6:声明sql语句
String sql = "INSERT INTO TB_USER (UNAME,UPWD,NAME,AGE,GENDER) VALUES ('"+u.getUname()+"','"+u.getUpwd()+"','"+u.getName()+"','"+u.getAge() + "','" + u.getGender() + "')";
//7:发送sql语句 接受返回结果
int rows = stmt.executeUpdate(sql);
System.out.println("增加了"+rows+"行记录");
} catch (SQLException e) {
e.printStackTrace();
}
}
@After
public void close() {
try {
if(stmt!=null) {
stmt.close();
}
if(conn!=null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
User.java内容如下:
package com.mage.po;
/*
* javabean规范:
* 所有属性私有
* 所有私有属性提供public的setter、getter方法
* 提供至少空构造器
*/
public class User {
private int id;
private String uname;
private String upwd;
private String name;
private String gender;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getUpwd() {
return upwd;
}
public void setUpwd(String upwd) {
this.upwd = upwd;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public User() {
super();
// TODO Auto-generated constructor stub
}
public User(int id, String uname, String upwd, String name, String gender, int age) {
super();
this.id = id;
this.uname = uname;
this.upwd = upwd;
this.name = name;
this.gender = gender;
this.age = age;
}
}
更多资料添加QQ:1708434248 v:magejava
删除也是返回受影响的行数
**注意:**对于所有的写操作(增、删、改),其实主体内容都差不多,主要是sql语句不同,某些参数不同,后期是可以考虑封装起来的。
public class JDBCTest01 {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
@Before
public void load() {
//1:加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
@Test
public void insert() {
LinkedList<User> list = new LinkedList<User>();
try {
//5:获取连接对象
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/note",
"root","root");
stmt = conn.createStatement();
//6:声明sql语句
String sql = "SELECT * FROM TB_USER";
//7:发送sql语句 接受返回结果
rs = stmt.executeQuery(sql);
//8:分析结果集
while(rs.next()) {
User u = new User();
u.setId(rs.getInt("id"));
u.setUname(rs.getString("uname"));
u.setUpwd(rs.getString("upwd"));
u.setName(rs.getString("name"));
u.setAge(rs.getInt("age"));
u.setGender(rs.getString("gender"));
list.add(s);
}
System.out.println(ls);
} catch (SQLException e) {
e.printStackTrace();
}
}
@After
public void close() {
try {
if(rs!=null) {
rs.close();
}
if(stmt!=null) {
stmt.close();
}
if(conn!=null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
1:对于DQL操作,返回的是结果集ResultSet对象
2:对于ResultSet对象,需要通过.next()方法,查看是否存在其他记录
问题描述:插入100000条数据,通过Statement插入:root
插入数据:1000,用时:2200插入数据:1000,用时:2769
插入数据:1000,用时:2943
public class JDBCTest02 {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
List<User> data = new LinkedList<>();
@Before
public void load() {
try {
//1:加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2:编写测试数据
for(int i = 1;i<100000;i++) {
String uname = "zs"+i;
String upwd = "123";
String name = "张三"+i;
int age = (int)(Math.random()*7+18);
String gender = (int)(Math.random())>0.5?"女":"男";
User u = new User(uname, upwd,name, age, gender);
data.add(u);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
@Test
public void insert() {
try {
//5:获取连接对象
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/note",
"root","root");
stmt = conn.createStatement();
//记录时间
long startTime = System.currentTimeMillis();
int rows = 0;
for(int i = 1;i<data.size();i++) {
//6:声明sql语句
String sql = "INSERT INTO TB_User (UNAME,UPWD,NAME,AGE,GENDER) VALUES ('"+
data.get(i).getUname()+"','"+data.get(i).getUpwd()+"','"+ data.get(i).getName()+"','"+ data.get(i).getAge() +"','"+ data.get(i).getGender()+"')";
//7:发送sql语句 接受返回结果
rows += stmt.executeUpdate(sql);
}
//记录时间
long endTime = System.currentTimeMillis();
System.out.println(endTime-startTime+"ms,总共受影响的行数是:"+rows);
} catch (SQLException e) {
e.printStackTrace();
}
}
@After
public void close() {
try {
if(stmt!=null) {
stmt.close();
}
if(conn!=null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
结论:
399050ms,总共受影响的行数是:100000
通过PreparedStatement插入数据
测试用例:
public class JDBCTest03 {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
List<User> data = new LinkedList<User>();
@Before
public void load() {
try {
//1:加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2:编写测试数据
for(int i = 1;i<100000;i++) {
String uname = "zs"+i;
String pwd = "123";
String name = "张三"+i;
int age = (int)(Math.random()*7+18);
String gender = (int)(Math.random())==0?"女":"男";
User u = new User(uname, pwd,name, age, gender);
data.add(u);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
@Test
public void insert() {
int rows = 0;
try {
//5:获取连接对象
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/note",
"root","root");
//6:声明sql语句
String sql = "INSERT INTO TB_USER(UNAME,UPWD,NAME,AGE,GENDER) VALUES (?,?,?,?,?)";
//7:获取预处理对象
pstmt = conn.prepareStatement(sql);
//记录时间
long startTime = System.currentTimeMillis();
//循环获取到每个对象的内容
for(int i = 0;i<data.size();i++) {
//8:设置绑定变量
pstmt.setString(1,data.get(i).getUname());
pstmt.setString(2,data.get(i).getUpwd());
pstmt.setString(3,data.get(i).getName());
pstmt.setInt(4,data.get(i).getAge());
pstmt.setString(5,data.get(i).getGender());
//9:发送SQL语句 获取结果
rows += pstmt.executeUpdate();
}
//记录时间
long endTime = System.currentTimeMillis();
System.out.println(endTime-startTime+"ms,总共受影响的行数是:"+rows);
} catch (SQLException e) {
e.printStackTrace();
}
}
@After
public void close() {
try {
if(pstmt!=null) {
pstmt.close();
}
if(conn!=null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
结论:
677875ms,总共受影响的行数是:100000
通过PreparedStatement批处理插入数据
测试用例:
public class JDBCTest03 {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
List<Student> data = new LinkedList<>();
@Before
public void load() {
try {
//1:加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2:编写测试数据
for(int i = 1;i<100000;i++) {
String name = "用户"+i;
String pwd = "123";
int age = (int)(Math.random()*7+18);
String gender = (int)(Math.random())>0.5?"女":"男";
Student stu = new Student(name, pwd, age, gender);
data.add(stu);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
@Test
public void insert() {
int rows = 0;
try {
//5:获取连接对象
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/note?rewriteBatchedStatements=true",
"root","root");
//6:声明sql语句
String sql = "INSERT INTO TB_USER(UNAME,UPWD,NAMW,AGE,GENDER) VALUES (?,?,?,?,?)";
//7:获取预处理对象
pstmt = conn.prepareStatement(sql);
//记录时间
long startTime = System.currentTimeMillis();
//关闭自动提交事务
conn.setAutoCommit(false);
//循环获取到每个对象的内容
for(int i = 0;i<data.size();i++) {
//8:设置绑定变量
pstmt.setString(1,data.get(i).getUname());
pstmt.setString(2,data.get(i).getUpwd());
pstmt.setString(3,data.get(i).getName());
pstmt.setInt(4,data.get(i).getAge());
pstmt.setString(5,data.get(i).getGender());
//添加到批处理中
pstmt.addBatch();
}
//一起提交到数据库服务器
rows = pstmt.executeBatch().length;
//提交事务
conn.commit();
//记录时间
long endTime = System.currentTimeMillis();
System.out.println(endTime-startTime+"ms,总共受影响的行数是:"+rows);
} catch (SQLException e) {
try {
//出现异常则回滚事务
conn.rollback();;
e.printStackTrace();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}
@After
public void close() {
try {
if(pstmt!=null) {
pstmt.close();
}
if(conn!=null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
结论:
188114ms,总共受影响的行数是:100000
- Tips
- 使用批处理需要增加rewriteBatchedStatements=true
- 将所有批量操作添加到一个事务当中,设置自动提交为false;conn.setAutoCommite(false);
- 如果语句中出现问题,则在异常中对于事务进行回滚。
测试代码:
public class JDBCTest04 {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
public static final String URL = "jdbc:mysql://localhost:3306/note";
public static final String USER_NAME = "root";
public static final String USER_PWD = "root";
//模拟登陆用户
User user = null;
@Before
public void load() {
try {
//1:加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2:模拟用户数据,这里记得在User.java中添加对应构造器
user = new User("'1","' or 1=1");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
@Test
public void queryByUser() {
int rows = 0;
try {
//5:获取连接对象
conn = DriverManager.getConnection(
URL, USER_NAME,USER_PWD);
//6:声明sql语句
String sql = "SELECT * FROM TB_STUDENT WHERE UNAME = "+loginStu.getUname()
+" AND PWD = "+loginStu.getUpwd();
System.out.println(sql);
//7:获取处理对象
stmt = conn.createStatement();
//8:发送sql 获取结果
rs = stmt.executeQuery(sql);
//9:分析结果
while(rs.next()) {
System.out.println("查询到了结果");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
@After
public void close() {
try {
if(stmt!=null) {
stmt.close();
}
if(conn!=null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
结论:
常见对象 | 对象常见方法 | 作用 |
---|---|---|
Connection | Connection.createStatement(); | 创建Statement对象 |
Connection.preparedStatement(sql); | 创建预处理对象 | |
Connection.prepareCall(sql) | 创建CallableStatement对象,调用存储过程 | |
Connection.setAutoCommite(true/false) | 设置事务提交方式,默认情况是自动提交true | |
Connection.commit(); | 提交事务 | |
Connection.rollback(); | 回滚事务 | |
Statement | Statement.executeQuery(sql); | 针对查询操作,获取结果集对象 |
Statement.executeUpdate(sql); | 针对写(增加、删除、修改)操作,获取受影响的行数 | |
PreparedStatement | PreparedStatement.executeQuery(); | 针对查询操作,获取结果集对象 |
PreparedStatement.executeUpdate(); | 针对写(增加、删除、修改)操作,获取受影响的行数 | |
PreparedStatement.addBatch(); | 添加到批处理中 | |
PreparedStatement.executeBatch(); | 执行批处理操作 | |
PreparedStatement.setXXX(index,value); | 设置绑定变量,给指定的占位符index,指定具体的值value,XXX代表value的数据类型。注意index从1开始 | |
ResultSet | ResultSet.next(); | 查看读操作返回的结果集中是否还存在数据信息 |
ResultSet.getXXX(index/columnName); | 根据字段的顺序或者是字段名称获取结果集中该字段的值,XXX代表返回数据的类型。index获取列是从0开始 |
区别点 | 对象 | 具体细节 |
---|---|---|
创建方式 | Statement | Connection.createStatement(); 不需要sql |
PreparedStatement | Connection.preparedStatement(sql);需要sql | |
安全 | Statement | 不能防止sql注入 SELECT * FROM TB_USER WHERE UNAME = '1 AND PWD = ’ OR 1=1 |
PreparedStatement | 可以防止SQL注入 | |
效率 | Statement | 不会初始化,没有预处理,每次都是从0开始执行SQ |
PreparedStatement | 会先初始化SQL,先把这个SQL提交到数据库中进行预处理,多次使用可提高效率 | |
可读性 | Statement | 当多次执行参数不同的语句时,需要不断的拼接字符串,使得阅读变得极为耗时以及费力。 |
PreparedStatement | 通过SetXXX();这样的方式,提高了阅读性 | |
性能 | Statement | 没有预编译的过程,每次都需要在DB中重新编译一下 |
PreparedStatement | 语句被db的编译器编译后的执行代码就会被缓存下来, 那么下次调用时只要相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行就可以。 相当于一个函数 , 对于整个db来说,只有预编译的语句和缓存中匹配,那么任何时候,就可以不需要再次编译从而直接执行。并不是所有的预编译语句都会被缓存起来,数据库本身会用一种策略,频繁使用的语句可能被缓存起来,以保存有更多的空间存储新的预编译语句。 |
1在src下创建一个.properties文件,编写驱动、链接地址、用户名、密码
2在工具类中通过流的方式读取配置文件信息,获取驱动、链接地址、用户名、密码
3编写获取连接、处理对象的方法
4编写资源连接的方法
配置文件DBConfig.properties
database=mysql
#######mysql properties########
mysqlDriver=com.mysql.jdbc.Driver
mysqlUrl=jdbc:mysql://localhost:3306/note
mysqlUsername=root
mysqlPassword=root
#######oracle properties########
oracleDriver=oracle.jdbc.OracleDriver
oracleUrl=jdbc:oracle:thin:@localhost:1521:orcl
oracleUsername=scott
oraclePassword=tiger
编写DBBase接口
public interface DBBase {
public static final String DATABASE_NAME = "database";
public static final String DATABASE_DRIVER = "driver";
public static final String DATABASE_URL = "url";
public static final String DATABASE_USERNAME = "username";
public static final String DATABASE_PASSWORD = "password";
}
编写DBUtils工具类
public class DBUtils {
//声明获取值
private static String database = "";
private static String driver = "";
private static String url = "";
private static String uname = "";
private static String pwd = "";
private static Properties pro = null;
//通过静态代码块将配置文件信息加载进来
static {
try {
//创建配置对象
pro = new Properties();
//获取输入流读取
InputStream is = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("DBConfig.properties");
//读取数据信息
pro.load(is);
//通过方法获取配置文件中的数据信息
database = getValue(DBBase.DATABASE_NAME);
driver = getValue(database+"-"+DBBase.DATABASE_DRIVER);
url = getValue(database+"-"+DBBase.DATABASE_URL);
uname = getValue(database+"-"+DBBase.DATABASE_USERNAME);
pwd = getValue(database+"-"+DBBase.DATABASE_PASSWORD);
//加载驱动
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("驱动类为【"+driver+"】");
}
}
/**
* 获取连接对象
* @return
*/
public static Connection getConn() {
Connection conn = null;
try {
conn = DriverManager.getConnection(url, uname,pwd);
} catch (SQLException e) {
e.printStackTrace();
System.out.println("【"+url+"】【"+uname+"】【"+pwd+"】");
}
return conn;
}
/**
* 创建Statement对象
* @param conn
* @return
*/
public static Statement getState(Connection conn) {
if(conn==null)
throw new RuntimeException("连接为空");
Statement stmt = null;
try {
stmt = conn.createStatement();
} catch (SQLException e) {
e.printStackTrace();
System.out.println("创建Statement对象失败");
}
return stmt;
}
//关闭连接
private static void closeConn(Connection conn) {
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//关闭资源
private static void closeStmt(Statement stmt) {
if(stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//关闭资源
private static void closeRs(ResultSet rs) {
if(rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//关闭所有资源
public static void closeAll(Connection conn,Statement stmt,ResultSet rs) {
closeRs(rs);
closeStmt(stmt);
closeConn(conn);
}
private static String getValue(String key) {
if("".equals(key)||key==null)
throw new NullPointerException("key值有误");
return pro.getProperty(key);
}
}
总结
1:通过Properties来加载配置文件信息。
2:通过getContextClassLoader().getResourceAsStream()读取相对于项目根目录下的资源文件。(这里的ClassLoader是一个上下文的加载器)。
3:在获取Properties中的值时,通过异常中断去处理了程序
4:通过静态代码块保证加载驱动只需要执行一次
更多资料添加QQ:1708434248 v:magejava