thread local(thread 的局部变量)解决多线程并发,为每个使用该变量的线程提供独
立的副本,
jdk5.0后,threadlocal支持泛型
接口方法:
//设置当前线程中局部变量的值
void set(Object value)
//返回当前线程对应的局部变量
public Object get()
//删除当前线程局部变量的值
public void remove()
//返回当前线程局部变量的初始值
protected Object initialValue()
示例程序
所需jar 包
commons-logging-1.1.1.jar
junit-4.10.jar
log4j-1.2.15.jar
log4jdbc4-1.2.jar
mysql-connector-java-5.1.7-bin.jar
slf4j-api-1.6.1.jar
slf4j-log4j12-1.6.1.jar
/*==============================================================*/
/* DBMS name: MySQL 5.0 */
/* Created on: 2012-11-8 11:58:12 */
/*==============================================================*/
drop table if exists t_classroom;
drop table if exists t_student;
drop table if exists t_student_classroom;
/*==============================================================*/
/* Table: t_classroom */
/*==============================================================*/
create table t_classroom
(
roomid varchar(16) not null,
roomname varchar(16),
primary key (roomid)
);
/*==============================================================*/
/* Table: t_student */
/*==============================================================*/
create table t_student
(
sno varchar(8) not null,
sname varchar(16),
sage int,
gender varchar(16),
sbrith date,
primary key (sno)
);
/*==============================================================*/
/* Table: t_student_classroom */
/*==============================================================*/
create table t_student_classroom
(
sno varchar(8) not null,
roomid varchar(16) not null,
primary key (sno, roomid)
);
alter table t_student_classroom add constraint FK_fk_roomid foreign key (roomid)
references t_classroom (roomid) on delete restrict on update restrict;
alter table t_student_classroom add constraint FK_fk_sno foreign key (sno)
references t_student (sno) on delete restrict on update restrict;
示例代码如下:
/**
* 教室
*
* @time 下午2:41:21
* @author retacn yue
* @Email
[email protected]
*/
public class ClassRoom {
private String classRoomId;
private String classRoomName;
public String getClassRoomId() {
return classRoomId;
}
public void setClassRoomId(String classRoomId) {
this.classRoomId = classRoomId;
}
public String getClassRoomName() {
return classRoomName;
}
public void setClassRoomName(String classRoomName) {
this.classRoomName = classRoomName;
}
}
/**
* 学生
*
* @time 下午2:40:57
* @author retacn yue
* @Email
[email protected]
*/
public class Student {
private String sNo;
private String sName;
private String sAge;
private String gender;
private String sBirth;
private String classRoomId;
private String classRoomName;
public String getsNo() {
return sNo;
}
public void setsNo(String sNo) {
this.sNo = sNo;
}
public String getsName() {
return sName;
}
public void setsName(String sName) {
this.sName = sName;
}
public String getsAge() {
return sAge;
}
public void setsAge(String sAge) {
this.sAge = sAge;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getsBirth() {
return sBirth;
}
public void setsBirth(String sBirth) {
this.sBirth = sBirth;
}
public String getClassRoomId() {
return classRoomId;
}
public void setClassRoomId(String classRoomId) {
this.classRoomId = classRoomId;
}
public String getClassRoomName() {
return classRoomName;
}
public void setClassRoomName(String classRoomName) {
this.classRoomName = classRoomName;
}
}
dao层=========================================================
/**
* 教室dao接口
*
* @time 下午2:48:13
* @author retacn yue
* @Email
[email protected]
*/
public interface ClassRoomDao {
public void addStudentRoom(String roomid, String sNo) throws
Exception;
}
public class ClassRoomDaoImpl implements ClassRoomDao {
/**
* 添加教室
*/
@Override
public void addStudentRoom(String roomid, String sNo) throws
Exception {
Connection conn = null;
PreparedStatement pstmt = null;
conn = ConnectionManager.getConnection();
try {
pstmt = conn.prepareStatement("insert into
t_student_classroom(roomid,sno)values(?,?)");
pstmt.setString(1, roomid);
pstmt.setString(2, sNo);
pstmt.executeUpdate();
} catch (SQLException e) {
throw new Exception("add studentClassRoom" +
e.getMessage(), e);
// e.printStackTrace();
} finally {
try {
if (pstmt != null) {
pstmt.close();
pstmt = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
/**
* 学生dao接口
*
* @time 下午2:46:30
* @author retacn yue
* @Email
[email protected]
*/
public interface StudentDao {
public void addStudent(Student student) throws Exception;
}
public class StudentDaoImpl implements StudentDao {
/**
* 添加学生
*/
@Override
public void addStudent(Student student) throws Exception {
Connection conn = null;
PreparedStatement pstmt = null;
conn = ConnectionManager.getConnection();
try {
pstmt = conn.prepareStatement(" insert into
t_student(sno, sname, sage, gender, sbrith) values (?,?,?,?,?)");
pstmt.setString(1, student.getsNo());
pstmt.setString(2, student.getsName());
pstmt.setString(3, student.getsAge());
pstmt.setString(4, student.getGender());
pstmt.setString(5, student.getsBirth());
pstmt.executeUpdate();
} catch (SQLException e) {
throw new Exception("add student " + e.getMessage
(), e);
// e.printStackTrace();
} finally {
try {
if (pstmt != null) {
pstmt.close();
pstmt = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
service层===================================================
/**
*
* @time 下午3:03:30
* @author retacn yue
* @Email
[email protected]
*/
public interface StudentService {
public void addStudent(Student student);
}
/**
*
* @time 下午3:04:46
* @author retacn yue
* @Email
[email protected]
*/
public class StudentServiceImpl implements StudentService {
/**
* 添加学生
*/
@Override
public void addStudent(Student student) {
StudentDao studentDao = new StudentDaoImpl();
ClassRoomDao classRoomDao = new ClassRoomDaoImpl();
try {
// 开 启事务
ConnectionManager.BeginTrans(true);
studentDao.addStudent(student);
classRoomDao.addStudentRoom
(student.getClassRoomId(), student.getsNo());
// 提交事务
ConnectionManager.commit();
} catch (Exception e) {
// 回滚
ConnectionManager.rollback();
e.printStackTrace();
} finally {
try {
// 关闭联接
ConnectionManager.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
工具类================================================
/**
* 读取jdbc配置文件
*
* @time 下午1:32:22
* @author retacn yue
* @Email
[email protected]
*/
public class JdbcProperies {
@SuppressWarnings("unused")
private static Log logger = LogFactory.getLog
(JdbcProperies.class);
public static Properties getPropObjectFromFile() {
Properties properties = new Properties();
// 取得当前线程的类加载器
ClassLoader classLoader = Thread.currentThread
().getContextClassLoader();
URL url = classLoader.getResource("jdbc.properties");
if (url == null) {
classLoader = ClassLoader.getSystemClassLoader();
url = classLoader.getResource("jdbc.properties");
}
System.out.println("=======" + url);
File file = new File(url.getFile());
InputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
properties.load(inputStream);
} catch (IOException e) {
properties = null;
e.printStackTrace();
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return properties;
}
}
/**
* 数据库连接工具类
*
* @time 下午1:25:59
* @author retacn yue
* @Email
[email protected]
*/
public class DBConnection {
private static Connection conn = null;
private static DBConnection instance = null;
private static Properties jdbcPro = null;
private static String driveName = null;
private static String userName = null;
private static String pwd = null;
private static String url = null;
/**
* 构造器
*/
private DBConnection() {
}
/**
* 读取配置文件
*
* @return
*/
private static Properties getConfigFromPropertiesFile() {
Properties properties = null;
properties = JdbcProperies.getPropObjectFromFile();
return properties;
}
/**
* 初始化配置文件
*/
private static void initJdbcParameters(Properties properties) {
driveName = properties.getProperty("driver");
userName = properties.getProperty("user");
pwd = properties.getProperty("password");
url = properties.getProperty("url");
}
/**
* 取得connection对象
*
* @return
*/
public static Connection getConnection() {
return conn;
}
/**
* 取得DBConnection对象(单例)
*
* @return
* @throws Exception
*/
public synchronized static DBConnection getInstance() throws
Exception {
if (instance == null) {
jdbcPro = getConfigFromPropertiesFile();
instance = new DBConnection();
}
initJdbcParameters(jdbcPro);
createConnection();
return instance;
}
/**
* 建立连接
*
* @throws Exception
*/
private static void createConnection() throws Exception {
Class.forName(driveName);
conn = DriverManager.getConnection(url, userName, pwd);
}
}
/**
*
* 数据据事务管理工具类
*
* @time 下午1:22:41
* @author retacn yue
* @Email
[email protected]
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public class ConnectionManager {
private static ThreadLocal tl = new ThreadLocal();
private static Connection conn = null;
/**
* 是否开启事务
*
* @param beginTrans
* @throws Exception
*/
@SuppressWarnings({ "static-access" })
public static void BeginTrans(boolean beginTrans) throws Exception
{
if (tl.get() == null || ((Connection) tl.get()).isClosed
()) {
conn = DBConnection.getInstance().getConnection();
if (beginTrans) {
conn.setAutoCommit(false);
}
tl.set(conn);
}
}
/**
* 取得connection对象
*
* @return
*/
public static Connection getConnection() {
return (Connection) tl.get();
}
/**
* 关闭事务
*
* @throws SQLException
*/
public static void close() throws SQLException {
try {
((Connection) tl.get()).setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
}
((Connection) tl.get()).close();
tl.set(null);
}
/**
* 提交
*/
public static void commit() {
try {
((Connection) tl.get()).commit();
} catch (SQLException e) {
e.printStackTrace();
}
try {
((Connection) tl.get()).setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 回滚
*/
public static void rollback() {
try {
((Connection) tl.get()).rollback();
} catch (SQLException e) {
e.printStackTrace();
}
try {
((Connection) tl.get()).setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
配置文件==============================================
driver = com.mysql.jdbc.Driver
password = ******
url = jdbc:mysql://localhost:3306/threadlocal
user = root
hibernate 里的
getCurrentSession
在hibernate配置文件中需要声明
<!-- 启用session的线程本地化技术,将session绑定到当前的线程
,实现session的传播(service层面上实现事务管理)-->
<property
name="current_session_context_class">thread</property>
openSession和getCurrentSession的区别
openSession需要在finally中关闭
getCurrentSession只需调用rollback和commit就可以
使用场景
service方法中如果对多个dao进行操作,可使用getCurrentSession
参考博客
http://blog.csdn.net/lifetragedy/article/details/7751059