一、使用控制事务完成业务功能
(1)ThreadLocal介绍
(2)ThreadLocal对象和方法
(3)TestThreadLocal
二、测试在单线程下获取两个connection连接
(1)在JdbcUtil包下的测试
(2)在JdbcUtil2包下的测试
(3)给出封装的JdbcUtil2代码
一、使用控制事务完成业务功能
(1)ThreadLocal介绍
- ThreadLocal功能:为同一个线程保存同一个值,为不同线程保存不同的值。
- 目的:在一个线程的各段代码中,只使用一个连接connection
在单线程编程中想获得connection,应该是获得同一个connection,但在之前的手动封装JDBC工具类中,并没有使用ThreadLocal控制事务,每一次都会创建一个新的连接,这样的消耗非常大。ThreadLocal就很好的解决了这个问题。
(2)ThreadLocal对象和方法
创建ThreadLocal对象:ThreadLocal<T> tdl = new ThreadLocal<T>();
ThreadLocal中的方法:
- set(T t);//将t对象添加至当前Thread。
- get( );//获得当前Thread中的对象。
- remove( );//移除当前Thread中的对象。
(3)TestThreadLocal
package jdbc;
public class TestThreadLocal {
public static void main(String[] args) throws Exception {
//tl对象可以为同一个线程保存相同的值,为不同线程保存不同的值.
final ThreadLocal<String> tl = new ThreadLocal<String>();
Thread t1 = new Thread() {
public void run() {
tl.set("hello");
System.out.println("t1:" + tl.get());
}
};
t1.start();
Thread.sleep(1000);
Thread t2 = new Thread() {
public void run() {
tl.set("world");
System.out.println("t2:"+tl.get());
}
};
t2.start();
}
}
二、测试在单线程下获取两个connection连接
(1)在JdbcUtil包下的测试
发现两个conn的地址不同,说明创建了两个连接。
(2)在JdbcUtil2包下的测试
可以看到这是同一个conn对象,任务完成。
(3)给出封装的JdbcUtil2代码
package util;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
/**
* Jdbc工具类
* 1:properties配置文件 封装获取连接 释放资源 提高代码复用性√
* 2:类加载时加载驱动√
* 3:ThreadLocal控制事务√
* 4:连接池,提高资源利用率×
* 5:rowmapper封装 减少代码冗余×
* 6:template封装 减少dao层代码冗余×
* @author 郭乾亮1998
*
*/
public class JdbcUtil2 {
//创建properties
static Properties pro = new Properties();
//创建ThreadLocal<Connection>,可以为同一个线程保存同一个连接,为不同线程保存不同的连接
private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
//加载驱动
static{
InputStream is = null;
try {
is = JdbcUtil.class.getResourceAsStream("/conf/db.properties");
//加载文件
pro.load(is);
Class.forName(pro.getProperty("driverClassName"));
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//获取连接
public static Connection getConnection() throws Exception{
Connection conn = tl.get();//获得当前线程中的连接
if(conn == null){//如果当前线程中没有连接
String url = pro.getProperty("url");
String user = pro.getProperty("username");
String password = pro.getProperty("password");
//创建连接
conn = DriverManager.getConnection(url,user,password);
//将连接保存到当前线程
tl.set(conn);
}
return conn;
}
//释放资源
public static void release(ResultSet rs,PreparedStatement pstm,Connection conn) throws Exception{
if(rs!=null){
rs.close();
}
if(pstm!=null){
pstm.close();
}
if(conn!=null){
conn.close();
tl.remove();//将连接从当前线程中移除
}
}
}