在书写代码的时候,我们常常会碰到一些重复使用而且经常使用的代码,这些代码出现在我们逻辑代码中,显得代码很长,非常影响代码的简洁性,所以我们需要把他们封装起来,在进行使用的时候,直接调用即可
封装前VS封装后:
封装前的测试类:
package Dao;
import com.qhit.entity.Student;
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 org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import static org.junit.Assert.*;
/**
* Description: mybatis01
* Created by WuHuaSen .
* Created Date: 2022/3/30 16:12
* Version: V1.0
*/
public class StudentDaoTest {
@Test
public void insertStudent() throws Exception {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//创建会话工厂
SqlSessionFactory factory = builder.build(is);
//会话连接
SqlSession sqlSession = factory.openSession();
//通过对象获取Dao对象、
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
//测试StudentDao方法
int i = studentDao.InsertStudent(new Student(3, "1001", "张三", "男", 21));
//手动提交
sqlSession.commit();
System.out.println(i);
}
@Test
public void deleteStudent() throws Exception {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
int i = studentDao.DeleteStudent(2);
sqlSession.commit();
assertEquals(1, i);
}
@Test
public void updateStudent() {
try {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
int i = studentDao.UpdateStudent(new Student(1, "15454", "麻溜", "男", 110));
sqlSession.commit();
assertEquals(1, i);
} catch (IOException e) {
e.printStackTrace();
}
}
}
封装后:
import com.qhit.Dao.StudentDao;
import com.qhit.pojo.Student;
import com.qhit.untils.MyBatisUntil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import org.apache.ibatis.io.Resources;
import java.io.IOException;
import java.io.InputStream;
import java.sql.ResultSet;
import java.util.List;
import static org.junit.Assert.*;
/**
* Description: NewSsm
* Created by WuHuaSen .
* Created Date: 2022/3/29 20:56
* Version: V1.0
*/
public class StudentDaoTest {
MyBatisUntil myBatisUntil = new MyBatisUntil();
@Test
public void insertStudent() throws Exception {
SqlSession sqlSession= myBatisUntil.getSqlSession(false);
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
//测试StudentDao方法
int i = studentDao.InsertStudent(new Student(2, "1001", "张三", "男", 21));
//手动提交,一般会有多个操作
sqlSession.commit();
//操作2
//操作三
System.out.println(i);
}
@Test
public void deleteStudent() throws Exception {
try {
//自动提交
StudentDao studentDao = myBatisUntil.getMapper(StudentDao.class);
int i = studentDao.DeleteStudent(2);
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void updateStudent() {
StudentDao studentDao = myBatisUntil.getMapper(StudentDao.class);
int i = studentDao.updataStudent(new Student(0, "2222", "1wangwu", "女", 21));
myBatisUntil.getSqlSession(true);
assertEquals(1, i);
}
}
可以明显的看出,我们的代码简洁了很多,下面将会具体讲讲mybatis的until工具类的创建
MyBatisUntil工具类的创建:
步骤:创建util包,新建MyBatisUntil类,定义会话工厂并对其进行私有化,创建线程锁在进行对象的跨层传递的时候,使用ThreadLocal可以避免多次传递,打破层次间的约束。
package com.qhit.untils;
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;
/**
* Description: NewSsm
* Created by WuHuaSen .
* Created Date: 2022/4/1 16:23
* Version: V1.0
*/
public class MyBatisUntil {
//封装会话工厂
private static SqlSessionFactory Factory;
/**在进行对象的跨层传递的时候,使用ThreadLocal可以避免多次传递,打破层次间的约束
*/
private static ThreadLocal<SqlSession> local = new ThreadLocal<SqlSession>();
}
设置静态代码块(随着类的加载而执行,并且只执行一次),所以将获取主配置文件以及建立会话工厂放进静态代码快,这样就减少了配置文件的加载,从而降低了内存的消耗
package com.qhit.untils;
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;
/**
* Description: NewSsm
* Created by WuHuaSen .
* Created Date: 2022/4/1 16:23
* Version: V1.0
*/
public class MyBatisUntil {
//封装会话工厂
private static SqlSessionFactory Factory;
/**在进行对象的跨层传递的时候,使用ThreadLocal可以避免多次传递,打破层次间的约束
*/
private static ThreadLocal<SqlSession> local = new ThreadLocal<SqlSession>();
static {
try {
InputStream is = Resources.getResourceAsStream("mysql-config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
Factory = sqlSessionFactoryBuilder.build(is);
} catch (
IOException e)
{
e.printStackTrace();
}
}
}
由于在编写测试类的时候会用到会话SqlSession、以及会话工厂SqlSessionFactory,因此我们对二者分别进行封装处理,测试的时候只需要调用对应的方法即可~
package com.qhit.untils;
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;
/**
* Description: NewSsm
* Created by WuHuaSen .
* Created Date: 2022/4/1 16:23
* Version: V1.0
*/
public class MyBatisUntil {
//封装会话工厂
private static SqlSessionFactory Factory;
/**在进行对象的跨层传递的时候,使用ThreadLocal可以避免多次传递,打破层次间的约束
*/
private static ThreadLocal<SqlSession> local = new ThreadLocal<SqlSession>();
static {
try {
InputStream is = Resources.getResourceAsStream("mysql-config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
Factory = sqlSessionFactoryBuilder.build(is);
} catch (
IOException e)
{
e.printStackTrace();
}
}
//封装factory方法
public static SqlSessionFactory getFactory(){
return Factory;
}
//封装sqlSession会话
public static SqlSession getSqlSession(boolean IsAutoComiit) {
SqlSession sqlSession = local.get();
if (sqlSession == null) {
sqlSession = Factory.openSession(IsAutoComiit);
local.set(sqlSession);
}
return sqlSession;
}
}
在测试的过程都会有一个通过getMapper方法获取Dao对象的方法(StudentDao studentDao = sqlSession.getMapper(StudentDao.class)过程,所以我们把这一部分也封装到工具类,但由于获取对象的类型是不确定的,所以这里我们要使用泛型~
package com.qhit.untils;
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;
/**
* Description: NewSsm
* Created by WuHuaSen .
* Created Date: 2022/4/1 16:23
* Version: V1.0
*/
public class MyBatisUntil {
//封装会话工厂
private static SqlSessionFactory Factory;
/**在进行对象的跨层传递的时候,使用ThreadLocal可以避免多次传递,打破层次间的约束
*/
private static ThreadLocal<SqlSession> local = new ThreadLocal<SqlSession>();
static {
try {
InputStream is = Resources.getResourceAsStream("mysql-config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
Factory = sqlSessionFactoryBuilder.build(is);
} catch (
IOException e)
{
e.printStackTrace();
}
}
//封装factory方法
public static SqlSessionFactory getFactory(){
return Factory;
}
//封装sqlSession会话
public static SqlSession getSqlSession(boolean IsAutoComiit) {
SqlSession sqlSession = local.get();
if (sqlSession == null) {
sqlSession = Factory.openSession(IsAutoComiit);
local.set(sqlSession);
}
return sqlSession;
}
//使用泛型封装getMapper
public static <T extends Object> T getMapper(Class<T> c) {
SqlSession sqlSession = getSqlSession(true);
return sqlSession.getMapper(c);
}
}
在使用泛型封装getMapper时候,我们给openSession()赋值“true”,自动提交;而在getsqlSession()方法中传递一个Boolean类型的值,来判断是否需要自动提交;True为自动提交,false为不自动提交,则需要手动提交sqlsession.commit();