ThreadLocal(jdk中)

线程容器,给线程绑定一个 Object 内容,后只要线程不变,可以随时取出.改变线程,无法取出内容.

1
2
3
4
5
6
7
final ThreadLocal<String> threadLocal = new ThreadLocal<>();
threadLocal.set("测试"); new Thread(){
public void run() {
String result = threadLocal.get();
System.out.println("结果:"+result);
};
}.start();

利用这一特性优化mybatis中service加载配置文件,创建session代码

MyUtil

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.kylin.util;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class MyBatisUtil {
//factory实例化的过程是一个比较耗费性能的过程
//保证有且只有一个factory
private static SqlSessionFactory factory;
private static ThreadLocal<SqlSession> tl = new ThreadLocal<>();
static {
try {
InputStream is = Resources.getResourceAsStream("mybatis.xml");
factory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* 获取SqlSession的方法
* @return
*/
public static SqlSession getSession(){
SqlSession session = tl.get();
if (session==null){
tl.set(factory.openSession());
}
return tl.get();
}

public static void closeSession(){
SqlSession session = tl.get();
if (session!=null){
session.close();
}
tl.set(null);
}
}

OpenSessionInView

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.kylin.filter;

import com.kylin.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;


import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/**
* 最开始是有Spring框架提出的,整合Hibernate框架是使用的是OpenSessionInView
*/
@WebFilter("/*")
public class OpenSessionInView implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {

}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
/*InputStream is = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = factory.openSession();*/
SqlSession session = MyBatisUtil.getSession();
try {
filterChain.doFilter(servletRequest,servletResponse);
session.commit();
}catch (Exception e){
session.rollback();
e.printStackTrace();
}finally {
MyBatisUtil.closeSession();
}
}

@Override
public void destroy() {

}
}

InsertServlet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.kylin.Servlet;

import com.kylin.pojo.Log;
import com.kylin.service.LogService;
import com.kylin.service.impl.LogServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/insert")
public class InsertServlet extends HttpServlet {
private LogService logService = new LogServiceImpl();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
Log log = new Log();
log.setAccIn(req.getParameter("accin"));
log.setAccOut(req.getParameter("accout"));
log.setMoney(Double.parseDouble(req.getParameter("money")));
int index = logService.ins(log);
if (index>0){
resp.sendRedirect("success.jsp");
}else {
resp.sendRedirect("/os/error.jsp");
}
}
}

LogServiceImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.kylin.service.impl;

import com.kylin.mapper.LogMapper;
import com.kylin.pojo.Log;
import com.kylin.service.LogService;
import com.kylin.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;

public class LogServiceImpl implements LogService {
@Override
public int ins(Log log) {
SqlSession session = MyBatisUtil.getSession();
LogMapper mapper = session.getMapper(LogMapper.class);
return mapper.ins(log);
}
}

具体过程和代码意义: