三、MyBatis基本要素—核心对象

一、本课目标

  • 了解MyBatis的三个基本要素
  • 理解核心类和接口的作用域和声明周期(重点、难点)
  • 掌握SQLSession的两种使用方式(重点)

二、MyBatis基本要素

MyBatis基本要素包括以下三个部分:

1、MyBatis的核心接口和类

  • SqlSessionFactoryBuilder
  • SqlSessionFactory
  • SQLSession

2、mybatis-config.xml 系统核心配置文件

3、mapper.xml SQL映射文件

本节课只来学习第一个基本要素,即核心接口和类。

三、MyBatis的核心接口和类

核心接口和类包括以下三个部分:
1、SqlSessionFactroyBuilder
2、SqlSessionFactory
3、SqlSession
三者关系如下:

image.png

注:1、SqlSessionFactory是我们MyBatis整个应用程序的中心;整个程序都是以SqlSessionFactory的实例为核心的。
2、SqlSessionFactory对象是由SqlSessionFactoryBuilder对象创建而来的。
3、SqlSessionFactoryBuilder是通过xml配置文件或者configuration类的实例去构造这个对象。然后调用build()方法去构造SqlSessionFactory对象。
4、使用SqlSessionFactory对象的openSession()方法来获取SqlSession对象,有了SqlSession对象,我们就可以去进行数据库操作了,因为SqlSession里面包含了以数据库为背景所有执行sql操作的方法。

3.1SqlSessionFactoryBuilder

  • 用过即丢,其生命周期只存在于方法体内
  • 可重用其来创建多个SqlSessionFactory实例
  • 负责构建SqlSessionFactory,并提供多个build方法的重载


    image.png

    在我们之前的测试中,使用的是读取xml文件,将其转换为输入流参数的形式提供给SqlSessionFactoryBuilder然后来构造SqlSessionFactory对象。
    对于SqlSessionFactoryBuilder来说,创建完SqlSessionFactory对象之后,其使命也就完成了,可以直接丢弃了。

3.2SqlSessionFactory对象

image.png

注:
1、在使用openSession()方法创建一个SqlSession对象的时候传了一个布尔型的参数,


image.png

问题:获取SqlSessionFactory的代码是否可以进行优化?

可以使用静态代码块,以保证SqlSessionFactory只被创建一次。
创建一个工具类如下:

package cn.smbms.utils;

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;
    
    static{
        String resource = "mybatis-config.xml";
        try {
            InputStream is = Resources.getResourceAsStream(resource);
            factory = new SqlSessionFactoryBuilder().build(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public static SqlSession createSqlSession() {
        return factory.openSession(false);
    }
    
    public static void closeSqlSession(SqlSession sqlSession) {
        if (sqlSession != null) {
            sqlSession.close();
        }
    }
    
}

工具类创建完成之后,就可以修改之前的测试代码了,如下:

package cn.smbms.dao.user;

import static org.junit.Assert.*;

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;
import org.apache.log4j.Logger;
import org.junit.Before;
import org.junit.Test;

import cn.smbms.utils.MyBatisUtil;

public class UserMapperTest {
    private Logger logger = Logger.getLogger(UserMapperTest.class);
    @Before
    public void setUp() throws Exception {
    }

    @Test
    public void test() {
        int count = 0;
        SqlSession sqlSession = null;
        try {
            sqlSession = MyBatisUtil.createSqlSession();
        // 4、调用mapper文件来对数据进行操作,操作之前必须将mapper文件引入到mabatis-config.xml中
            count = sqlSession.selectOne("cn.smbms.dao.user.UserMapper.count");
            logger.debug("UserMapperTest count ---->" + count);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            MyBatisUtil.closeSqlSession(sqlSession);
        }
        
    }

}

3.3SqlSession

  • 包含了自行SQL所需的所有方法
  • 对应一次数据库会话,会话结束必须关闭
  • 线程级别,不能共享
image.png

1、在SqlSession里可以执行多次SQL语句,但一旦关闭了SqlSession就需要重新创建。
2、SqlSession示例不能被共享,也不是线程安全的。所以其最佳作用域是reqeust作用域内或者方法体内的作用域内。


1、SqlSession的获取方式:

image.png

2.SqlSession的两种使用方式

image.png

第一种方式:
在之前的测试中,如下代码:

count = sqlSession.selectOne("cn.smbms.dao.provider.providerCount");

就是直接运行映射的SQL语句。

第二种方式:
基于mapper接口方式来操作数据,也是MyBatis比较推崇的方式。

四、SqlSession的两种使用方式

需求说明:使用SqlSession的两种使用方式实现用户表的查询操作。
分析:

  • 调用sqlSession.selectList()执行查询操作
  • 调用sqlSession.getmapper(Mapper.class)执行DAO接口方法来实现对数据的查询操作

4.1调用sqlSession.selectList()执行查询操作

首先,在UserMapper.xml文件中增加新的select标签:







    
    
    
    
    
    
    

然后,增加新的单元测试的方法:

@Test
    public void testGetuserList() {
        List userList = null;
        SqlSession sqlSession = null;
        try {
            sqlSession = MyBatisUtil.createSqlSession();
        // 4、调用mapper文件来对数据进行操作,操作之前必须将mapper文件引入到mabatis-config.xml中
            userList = sqlSession.selectList("cn.smbms.dao.user.UserMapper.getUserList");
        //  userList = sqlSession.getMapper(UserMapper.class).getUserList();
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            MyBatisUtil.closeSqlSession(sqlSession);
        }
        for (User user:userList) {
            logger.debug("testGetUserList userCode:" + user.getUserCode()
                    + "and userName" + user.getUserName() + user.getModifyDate());
        }
    }

4.2调用sqlSession.getmapper(Mapper.class)执行DAO接口方法来实现对数据的查询操作

在增加完UserMapper.xml中的标签后,在cn.smbms.dao.user下重新建立一个接口文件:

package cn.smbms.dao.user;

import java.util.List;

import cn.smbms.pojo.User;

public interface UserMapper {
    
    public List getUserList();

}

增加测试单元如下:

package cn.smbms.dao.user;

import static org.junit.Assert.*;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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.apache.log4j.Logger;
import org.junit.Before;
import org.junit.Test;

import cn.smbms.pojo.User;
import cn.smbms.utils.MyBatisUtil;

public class UserMapperTest {
    private Logger logger = Logger.getLogger(UserMapperTest.class);
    @Before
    public void setUp() throws Exception {
    }

    @Test
    public void test() {
        int count = 0;
        SqlSession sqlSession = null;
        try {
            sqlSession = MyBatisUtil.createSqlSession();
        // 4、调用mapper文件来对数据进行操作,操作之前必须将mapper文件引入到mabatis-config.xml中
            count = sqlSession.selectOne("cn.smbms.dao.user.UserMapper.count");
            logger.debug("UserMapperTest count ---->" + count);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            MyBatisUtil.closeSqlSession(sqlSession);
        }
    }

    @Test
    public void testGetuserList() {
        List userList = null;
        SqlSession sqlSession = null;
        try {
            sqlSession = MyBatisUtil.createSqlSession();
        // 4、调用mapper文件来对数据进行操作,操作之前必须将mapper文件引入到mabatis-config.xml中
        //  userList = sqlSession.selectList("cn.smbms.dao.user.UserMapper.getUserList");
            userList = sqlSession.getMapper(UserMapper.class).getUserList();
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            MyBatisUtil.closeSqlSession(sqlSession);
        }
        for (User user:userList) {
            logger.debug("testGetUserList userCode:" + user.getUserCode()
                    + "and userName" + user.getUserName() + user.getModifyDate());
        }
    }
}

注:1、接口的方法的名字必须同xml文件中的id一致。

五、总结

image.png

你可能感兴趣的:(三、MyBatis基本要素—核心对象)