美文网首页
三、MyBatis基本要素—核心对象

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

作者: lifeline张 | 来源:发表于2018-08-24 15:15 被阅读0次

    一、本课目标

    • 了解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标签:

    <?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(其实是本xml文件的路径名),其作用是用来区分其他不同的mapper,来达到全局唯一-->
    <!-- 因为每一个实体类都有一个mapper.xml文件,所以最后会有很多个mapper -->
    
    <mapper namespace="cn.smbms.dao.user.UserMapper">
        
        <!-- 查询用户表的记录数 -->
        <!-- 每一个子节点元素都会有一个id,id属性是表示该命名空间下的唯一标识符 
            resultType属性是指返回的结果类型
        -->
        <select id="count" resultType="int">
            select count(1) as count from smbms_user
        </select>
        
        <!-- 查询用户列表 -->
        <select id="getUserList" resultType="cn.smbms.pojo.User">
            select * from smbms_user
        </select>
    </mapper>
    

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

    @Test
        public void testGetuserList() {
            List<User> 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<User> 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<User> 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基本要素—核心对象

          本文链接:https://www.haomeiwen.com/subject/wtjbiftx.html