ThreadLocal:线程容器,给线程绑定一个 Object 内容,后只要线程不变,可以随时取出.
注意:如果改变了线程,无法取出内容.
代码示例:
final ThreadLocal<String> threadLocal = newThreadLocal<>(); threadLocal.set("测试"); new Thread(){ public void run() { String result = threadLocal.get(); System.out.println("结果:"+result); }; }.start();
我们使用ThreadLocal来优化一下之前写的项目:
实体类:
package com.tao.pojo; public class Log { private int id; private String accIn; private String accOut; private double money; public Log() { } public Log(int id, String accIn, String accOut) { this.id = id; this.accIn = accIn; this.accOut = accOut; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAccIn() { return accIn; } public void setAccIn(String accIn) { this.accIn = accIn; } public String getAccOut() { return accOut; } public void setAccOut(String accOut) { this.accOut = accOut; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } @Override public String toString() { return "Log [id=" + id + ", accIn=" + accIn + ", accOut=" + accOut + ", money=" + money + "]"; } }
映射文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.tao.mapper.LogMapper"> <insert id="insertLog" parameterType="Log"> insert into log values(default,#{accIn},#{accOut},#{money}) </insert> </mapper>
映射接口:
package com.tao.mapper; import java.util.List; import org.apache.ibatis.annotations.Param; import com.tao.pojo.Log; public interface LogMapper { int insertLog(Log log); }
service处理:
package com.tao.service; import com.tao.pojo.Log; /** * 日志逻辑处理层 */ public interface LogService { /** * 增加转账记录 * @return */ int addLog(Log log); }
service实现:省略了 读取配置文件、获取session 、提交session 、回滚、 关闭session等代码
package com.tao.service.impl; import org.apache.ibatis.session.SqlSession; import com.tao.mapper.LogMapper; import com.tao.pojo.Log; import com.tao.service.LogService; import com.tao.util.MyBatisUtil; public class LogServiceImpl implements LogService{ @Override public int addLog(Log log) { SqlSession session = MyBatisUtil.getSqlSession(); LogMapper logMapper = session.getMapper(LogMapper.class); return logMapper.insertLog(log); } }
控制层:
package com.tao.servlet; import java.io.IOException; 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 com.tao.pojo.Log; import com.tao.service.LogService; import com.tao.service.impl.LogServiceImpl; @WebServlet("/insertLog") public class LogServlet extends HttpServlet{ private static final long serialVersionUID = 1L; private LogService logService = new LogServiceImpl(); @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=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.addLog(log); if(index>0){ resp.sendRedirect("success.jsp"); }else{ resp.sendRedirect("error.jsp"); } } }
过滤器:把省略的代码,在控制层执行前后加上处理 也就相当于在service前后加了处理 责任链模式:
package com.tao.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import org.apache.ibatis.session.SqlSession; import com.tao.util.MyBatisUtil; /** * 最开始是由Spring框架提出的.整合Hibernate框架是使用的是OpenSessionInView * @author zhangtao * */ @WebFilter("/*") public class openSessionViewFilter implements Filter{ @Override public void destroy() { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { SqlSession session = MyBatisUtil.getSqlSession(); try { filterChain.doFilter(servletRequest, servletResponse); session.commit(); } catch (Exception e) { session.rollback(); e.printStackTrace(); }finally { MyBatisUtil.closeSession(); } } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } }
使用ThreadLocal封装MyBatisUtil工具类:
package com.tao.util; import java.io.IOException; import java.io.InputStream; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class MyBatisUtil { private static SqlSessionFactory factory; private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<>(); static{ try{ InputStream is = Resources.getResourceAsStream("mybatis.xml"); factory = new SqlSessionFactoryBuilder().build(is); }catch(IOException e){ e.printStackTrace(); } } /** * 获取SqlSession的方法 */ public static SqlSession getSqlSession(){ SqlSession session = threadLocal.get(); if(session==null){ threadLocal.set(factory.openSession()); } return threadLocal.get(); } /** * 关闭Session的方法 */ public static void closeSession(){ SqlSession session = threadLocal.get(); if(session!=null){ session.close(); } threadLocal.set(null); } }
mybaits核心配置文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- mybatis 开启log4j支持功能 --> <settings> <setting name="logImpl" value="LOG4J"/> </settings> <!-- 给某个包下所有类起别名,别名为类名, 不区分大小写 --> <typeAliases> <package name="com.tao.pojo"/> </typeAliases> <environments default="dev"> <environment id="dev"> <!-- JDBC 原生事务管理方式 --> <transactionManager type="JDBC"></transactionManager> <!-- 使用数据库连接池 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/ssm"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <!-- <mapper resource="com/tao/mapper/LogMapper.xml"/> --> <package name="com.tao.mapper"/> </mappers> </configuration>
index.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="insertLog" method="post"> <table> <tr> <td>转账账号:<input type="text" name="accOut" ></td> <td>收账账号:<input type="text" name="accIn"></td> <td>转账金额:<input type="text" name="money"></td> <td><input type="submit" value="确认转账"></td> </tr> </table> </form> </body> </html>