MyBatisUtil 工具类

Exisi 2021-03-27 07:16:01
Categories: Tags:
  • Mybatis 中进行查询操作的时候,查询单个对象、查询列表信息等的时候,我们需要每次都重复写创建 SqlSessionFactorySqlSession 等相关代码

 

// 根据主键 id 查询单个用户

@Test

void testGet() {

InputStream in = Resources.getResourceAsStream("mybatis-config.xml");

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);

SqlSession sqlSession = sqlSessionFactory.openSession();

User user = sqlSession.selectOne("com.mxz.mybatis.mapper.UserMapper.get", 1L);

sqlSession.close();

}

 

// 查询所有用户

@Test

void testListAll() {

InputStream in = Resources.getResourceAsStream("mybatis-config.xml");

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);

SqlSession sqlSession = sqlSessionFactory.openSession();

List<User> userList = sqlSession.selectList("com.mxz.mybatis.mapper.UserMapper.ListAll");

sqlSession.close();

}

 

这样一来,如果后面有多个操作的话,代码就显得很冗余,所以我们需要提取共同的代码,创建 MybatisUtil 类,把冗余的代码进行封装

 

这里边共同的代码主要是

  • 加载构造器配置数据库交互文件(SqlSessionFactoryBuilder
  • 创建构造器容器 (SqlSessionFactory
  • 数据库连接和操作的交互对象(SqlSession

 

SqlSessionFactory的生成

 

SqlSessionFactoryBuilder

 

这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。

因此 SqlSessionFactoryBuilder 的作用域是局部方法中

 

SqlSessionFactory

 

  • SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例,而使用(private static)共享
  • 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,因此使用单例模式或者静态单例模式控制只创建一次

 

SqlSession

 

  • 每个线程都应该有它自己的 SqlSession 实例。
  • SqlSession 的实例不是线程安全的,因此是不能被(public/private stastic)共享的,所以它的作用域是每个请求或每个方法的作用域中。
  • 绝对不能将 SqlSession 实例的引用放在一个类的静态域中共享SqlSession连接,甚至一个类的实例变量也不行。

所以,要记住的是,SqlSessionFactory 是线程安全的,和数据库连接池 dataSource 一样,整个应用中有一份就够了

 

 

 

MybatisUtils 的封装

  • MybatisUtils 中,定义了一个静态代码块用于获取 SqlSession 对象。基本的 MybatisUtils 应该包含SqlSession 的获取创建和关闭

示例

  • MyBatisUtils.java

 

public class MyBatisUtils {

private static SqlSessionFactory factory;

 

static {//静态代码下,factory只创建一次

System.out.print("static factory=============");

try {

// classpath 路径去加载mybatis 全局配置文件

InputStream is= Resources.getResourceAsStream("mybatis-config.xml");

factory=new SqlSessionFactoryBuilder().build(is);

}catch(IOException e){

e.printStackTrace();

}

}

 

public static SqlSession createSqlSession() {

return factory.openSession(false);//true提交事务

}

 

public static void closeSqlSession(SqlSession sqlSession) {

sqlSession.close();

}

 

}

 

 

 

MybatisUtils 的使用

SqlSession 和数据库连接对象 Connection 是一样的,是线程不安全的,每次都要创建新的连接,用完了都要去关闭它,这个关闭操作是很重要的,你应该把这个关闭操作放到 finally 块中以确保每次都能执行关闭

示例

public void testGetUserList() {

SqlSession sqlSession=null;

List<Users> userList =new ArrayList<Users>();

try{

//调用封装为MyBatisUtil的数据库连接方法.java

sqlSession=MyBatisUtils.createSqlSession();

 

//调用getMapper(Mapper.class)执行dao接口方法来实现对数据库的查询操作

count=sqlsession.getMapper(UsersMapper.class).count();

 //获取实体类数据

userList=sqlSession.getMapper(UsersMapper.class).getUserList();

sqlSession.commit();

 

logger.debug("UserMappingTest count--->"+count);

}catch(Exception e){

e.printStackTrace();

}finally{

MyBatisUtil.closeSqlSession(sqlSession);

}

}

 

 

来自 <https://zhuanlan.zhihu.com/p/82849890>