• 掌握MyBatis的核心对象


    一、获取SqlSessionFactoryBuilder对象

    1、SqlSessionFactoryBuilder的作用

    所有的MyBatis应用都是以SqlSessionFactory实例为中心。SqlSessionFactoryBuilder就是SqlSessionFactory的构造者,通过build()方法负责构建SqlSessionFactory。

    通过源码分析,可以发现都是在调用同一个签名方法build(InputStream inputStream, String environment, Properties properties)

    由于方法参数environment和properties都可以为null,去除重复的,真正的重载方法只有如下三种  

    • build(Reader reader, String environment, Properties properties)
    • build(InputStream inputStream, String environment, Properties properties)
    • build(Configuration config)

    通过上述分析,发现配置信息以三种形式提供给SqlSessionFactoryBuilder的build()方法,分别是InputStream(字节流)、Reader(字符流)、Configuration(类),由于字节流与字符流都属于读取配置文件的方式,所有从配置信息的来源去构建一个SqlSessionFactory有两种方式:读取XML配置文件构造方式和编程构造方式。我们以读取XML配置文件的方式来构造SqlSessionFactory。

    2、SqlSessionFactoryBuilder的生命周期和作用域

    SqlSessionFactoryBuilder的最大特点是用过即丢。一旦创建了SqlSessionFactory对象,这个类就不需要存在了,因此SqlSessionFactoryBuilder的最佳作用范围就是存在于方法体内,也就是局部变量。

    二、获取SqlSessionFactory对象

    1、SqlSessionFactory的作用

    SqlSessionFactory就是创建SqlSession实例的工厂。通过SqlSessionFactory提供的openSession()方法来获取SqlSession实例。

    openSession()方法的参数为boolean值时,若传入true表示关闭事务控制,自动提交;若传入false表示开启事务控制。若不传入参数,默认为true。

    2、SqlSessionFactory的生命周期和作用域

    SqlSessionFactory对象一旦创建,就会在整个应用运行过程中始终存在。没有理由去销毁或再创建它,并且在应用运行中也不建议多次创建SqlSessionFactory。因此SqlSessionFactory的最佳作用域是Application,即随着应用的生命周期一同存在。那么这种“存在于整个应用运行期间,并且同时只存在一个对象实例”的模式就是所谓的单例模式(指在应用运行期间有且仅有一个实例)。

    获取SqlSessionFactory,最简单的方式就是放在静态代码块下,以保证SqlSessionFactory对象只被创建一次,如下

    package edu.cn.dao.util;
    
    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;
    
    public class MyBatisUtil {
        private static SqlSessionFactory factory;
    
        static {
            try {
                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);
        }
        
        public static void closeSqlSession(SqlSession sqlSession){
            if (null != sqlSession){
                sqlSession.close();
            }
        }
    }

    三、获取SqlSession对象

    1、SqlSession的作用

    SqlSession是用于执行持久化操作的对象,类似于JDBC中的Connection。它提供了面向数据库执行SQL命令所需的所有方法,可以通过SqlSession实例直接运行已映射的SQL语句。

    2、SqlSession的声明周期和作用域

    SqlSession对应着一次数据库会话,由于数据库会话不是永久的,因此SqlSession的生命周期也不是永久的。相反,在每次访问数据库时都需要创建它(并不是说在SqlSession里只能执行一次SQL,它是完全可以执行多次的,但是若关闭了SqlSession,那么就需要重新创建它)。另外,关闭SqlSession是非常重要的,必须确保SqlSession在finally语句块中正常关闭。

    个线程都有自己的SqlSession实例,SqlSession实例不能被共享,也不是线程安全的。因此最佳的作用域范围是request作用域或者方法体作用域

    3、SqlSession的两种使用方式

    (1)通过SqlSession实例来直接执行已映射的SQL语句

    <select id="getUserList" resultType="edu.cn.pojo.User">
      select * from smbms_user
    </select>
    package edu.cn.dao;
    
    import edu.cn.dao.util.MyBatisUtil;
    import edu.cn.pojo.User;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import static org.junit.Assert.*;
    
    public class UserMapperTest {
        private static final Logger logger = LoggerFactory.getLogger(UserMapperTest.class);
        
        @Test
        public void testGetUserList(){
            SqlSession sqlSession = null;
            List<User> userList = new ArrayList<>();
            try {
                sqlSession = MyBatisUtil.createSqlSession();
                userList = sqlSession.selectList("cn.smbms.dao.user.UserMapper.getUserList");
            } catch (Exception e){
                e.printStackTrace();
            } finally {
                MyBatisUtil.closeSqlSession(sqlSession);
            }
            for (User user:userList){
                logger.debug("testGetUserList userCode:" + user.getUserCode()
                        + " and userName:" + user.getUserName());
            }
        }
    
    }

    (2)基于mapper接口方式操作数据

    创建绑定映射语句的接口,并提供接口方法,该接口称为映射器

    public interface UserMapper {
        public List<User> getUserList();
    }

    修改测试类中的关键语句如下

    try {
        sqlSession = MyBatisUtil.createSqlSession();
        userList = sqlSession.getMapper(UserMapper.class).getUserList();
    }

    第一种方式是旧版本的MyBatis提供的操作方式,现在也可以正常工作;第二种方式是Mybatis官方推荐使用的,其表达方式也更加直白,代码更加清晰,类型更加安全,也不用担心易错的字符串字面值以及强类型转。

  • 相关阅读:
    变量与常量
    .面向过程和面向对象的区别
    .JDK,JRE,JVM三者关系
    DEV C++, 利用链表实现目录内所有文件列表显示
    swith的用法和注意事项?
    Java排序(一)实现类的排序
    C++数据结构——树(基础知识篇)
    杀进程
    监控 monitor java 代码
    putty 直接连 快捷键方式
  • 原文地址:https://www.cnblogs.com/yanguobin/p/11711705.html
Copyright © 2020-2023  润新知