编写工具类
复用与重构
复用:使用方法与函数,复用的类,构成JAR包。(工具类属于复用)
一。创建工具类(一般在src下创建util包,在util包下创建工具类)。
例如:MybatisUtilds为工具类:
二:本工具类,作用如下:
1.创建和初始化SqlSessionFactory封装成方法
2.能够创建在一定范围内(线程)有效的SqlSession
3.能够关闭在一定范围内()有效的SqlSession
4.能够进行事务控制
5.一些额外的支持Dao层便捷开发的方法
实现:
ThreadLocal:线程本地存储(只能存储一个对象,但是可以保证这个线程一直有效,除非线程销毁)
ThreadGroup:线程组
ThreadPool:线程池
泛型方法:
public static <T> T getMapper(Class<T> tClass){
return open().getMapper(tClass);
}
eg:
public static void rollback(){ SqlSession session = threadLocal.get(); if(session!=null) session.rollback(); UsersMapper dao=session.getMapper(UsersMapper.class); NewsMapper newDao=session.getMapper(NewsMapper.class); } public static <T> T getMapper(Class<T> tClass){ return open().getMapper(tClass); }
可更改:
public static void rollback(){ SqlSession session = threadLocal.get(); if(session!=null) session.rollback(); UsersMapper dao=getMapper(UsersMapper.class); NewsMapper newDao=getMapper(NewsMapper.class); } public static <T> T getMapper(Class<T> tClass){ return open().getMapper(tClass); }
三:完整代码:
MybatisUtils类:
1 package com.util; 2 3 import com.dao.NewsMapper; 4 import com.dao.UsersMapper; 5 import org.apache.ibatis.io.Resources; 6 import org.apache.ibatis.session.SqlSession; 7 import org.apache.ibatis.session.SqlSessionFactory; 8 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 9 10 import java.io.IOException; 11 import java.io.InputStream; 12 13 public class MybatisUtils { 14 /** 15 * 1.创建和初始化SqlSessionFactory 16 * 2.能够创建在一定范围内(线程)有效的SqlSession 17 * 3.能够关闭在一定范围内()有效的SqlSession 18 * 4.能够进行事务控制 19 * 5.一些额外的支持Dao层便捷开发的方法 20 * * 场景1:重定向 21 * * me -> A(伊滨) 1request->response 1线程 22 * * -> B(西工) 2request->response 2线程 23 * * -> C(涧西) 3request->response 3线程 24 * * -> A(伊滨) 4request->response 4线程 25 * * 场景2:转发 1request->response 1线程 26 * * me -> A(伊滨) 27 * * -电话-> B(西工) 28 * * -电话-> C(涧西) 29 * * <- 30 * * 多线程环境下访问SqlSession是同一个么、需要是同一个么? 不是同一个 31 * * 单线程环境下访问SqlSession是同一个么、需要是同一个么? 是同一个 32 */ 33 static final String CONFIG_FILE = "mybatis-config.xml"; 34 static SqlSessionFactory factory; 35 static{ 36 initFactory(CONFIG_FILE); 37 } 38 public static void initFactory(String configName){ 39 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); 40 try { 41 InputStream resourceAsStream = 42 Resources.getResourceAsStream(configName); 43 factory = builder.build(resourceAsStream); 44 } catch (IOException e) { 45 e.printStackTrace(); 46 } 47 } 48 static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<>(); 49 public static SqlSession open(){ 50 SqlSession session = threadLocal.get(); 51 if(session==null){ 52 session = factory.openSession(); 53 threadLocal.set(session);//线程绑定session,保证每次调用的是同一个线程 54 } 55 return session; 56 } 57 public static void close(){ 58 SqlSession session = threadLocal.get(); 59 if(session!=null){ 60 session.close(); 61 threadLocal.set(null); 62 } 63 } 64 public static void commit(){ 65 SqlSession session = threadLocal.get(); 66 if(session!=null) session.commit(); 67 } 68 public static void rollback(){ 69 SqlSession session = threadLocal.get(); 70 if(session!=null) session.rollback(); 71 UsersMapper dao=getMapper(UsersMapper.class); 72 NewsMapper newDao=getMapper(NewsMapper.class); 73 } 74 public static <T> T getMapper(Class<T> tClass){ 75 return open().getMapper(tClass); 76 } 77 78 }
测试类MybatisUtilsTest:
1 package com.dao; 2 3 import org.apache.ibatis.session.SqlSession; 4 import org.junit.Test; 5 6 import static com.util.MybatisUtils.open; 7 8 public class MybatisUtilsTest { 9 //单线程测试 10 @Test 11 public void openInUniqueThread() throws InterruptedException{ 12 SqlSession s1=open(); 13 Thread.sleep(2000); 14 SqlSession s2=open(); 15 Thread.sleep((int)(Math.random()*10000)+1000); 16 SqlSession s3=open(); 17 Thread.sleep((int)(Math.random()*10000)+1000); 18 assert s1==s2&&s1==s3; 19 } 20 //多线程测试 21 SqlSession s1 = null;//全局变量 22 SqlSession s2 = null; 23 SqlSession s3 = null; 24 @Test 25 public void openInMultiplyThread() throws InterruptedException { 26 // 匿名类对象(匿名内部类)。1.创建匿名内部类(thread)2.重写run方法 3.创建对象 27 new Thread(){//子线程 28 public void run(){ 29 s1 = open(); 30 } 31 }.start(); 32 new Thread(){ 33 public void run(){ 34 s2 = open(); 35 } 36 }.start(); 37 new Thread(){ 38 public void run(){ 39 s3 = open(); 40 } 41 }.start(); 42 // 等待,轮训 43 while(true){ 44 if(s1 != null && s2 != null && s3 != null){ 45 System.out.println("结束了!"); 46 break; 47 } 48 System.out.println("等待:s1=" + s1 +",s2=" + s2 + ",s3=" + s3); 49 Thread.sleep(10); 50 } 51 assert s1 != s2 && s2 != s3 && s1 != s3;//主线程,s1,S2,S3为子线程。 52 } 53 54 }