mybatis从入门到精通(五) sqlSession API的使用

mybatis从入门到精通(五) sqlSession API的使用

 一丶简介

  SqlSession类似于mybatis对外的接口层, 它几乎囊括了所有对外的api, 因此, 学习SqlSession的使用方法对于了解mybatis还是有必要的.

对应官方文档

二丶配置SqlSession的环境<environment/>

   <environment/> 主要包括了两种配置, 事务管理和数据源. 这里的配置仅仅是用于学习, 实际应用一般是将事务交由Spring容器管理, 数据源一般选用成熟的数据库连接池, 如druid, HikariCP

    <environments default="development">
        <environment id="development" >
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

三丶使用配置构建对应的SqlSessionFactory

        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        this.sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

四丶使用SqlSessionFactory获取SqlSession

  在获取SqlSession实例之前, 需要考虑以下3件事:

    事务处理:我需要在 session 使用事务或者使用自动提交功能(auto-commit)吗?(通常意味着很多数据库和/或 JDBC 驱动没有事务)
    连接:我需要依赖 MyBatis 获得来自数据源的配置吗?还是使用自己提供的配置?
    执行语句:我需要 MyBatis 复用预处理语句和/或批量更新语句(包括插入和删除)吗?

  4.1) 默认方法

    @Test
    public void sqlSessionTest(){
        // openSession() 会开启一个事务, 它不会自动提交
        // 会从当前环境配置的Datasource实例中获取Connection
        // 事务隔离级别使用jdbc或数据源默认的配置
        // 不会复用预处理语句, 每次都是新建一个处理语句
        try(SqlSession sqlSession=this.sqlSessionFactory.openSession();){
            UserMapper mapper=sqlSession.getMapper(UserMapper.class);
            User user=mapper.selectUser(1);
            sqlSession.commit();
            Assert.assertTrue(user.getUserId() == 1);
        }
    }

  4.2) 批量执行(自定义)

    /*
    SqlSession openSession() //默认开启事务, 不自动提交
    SqlSession openSession(boolean autoCommit)  // 可设置是否自定提交
    SqlSession openSession(Connection connection)  // 需要使用自定义的connection, 传递参数即可, 注意并未覆写同时设置 Connection 和 autoCommit 两者的方法,因为 MyBatis 会使用正在使用中的、设置了 Connection 的环境
    SqlSession openSession(TransactionIsolationLevel level) // 事务隔离级别
    SqlSession openSession(ExecutorType execType,TransactionIsolationLevel level)
    SqlSession openSession(ExecutorType execType)
    SqlSession openSession(ExecutorType execType, boolean autoCommit)
    SqlSession openSession(ExecutorType execType, Connection connection)
    Configuration getConfiguration();

    ExecutorType.SIMPLE:这个执行器类型不做特殊的事情。它为每个语句的执行创建一个新的预处理语句。
    ExecutorType.REUSE:这个执行器类型会复用预处理语句。
    ExecutorType.BATCH:这个执行器会批量执行所有更新语句,如果 SELECT 在它们中间执行,必要时请把它们区分开来以保证行为的易读性。
     */
    @Test
    public void sqlSessionTest2(){
        SqlSession sqlSession=null;
        try{
            /*
            批量执行
            DEBUG [main] - ==>  Preparing: insert into user(user_id, user_name, age, country) values (?, ?, ?, ?)
            DEBUG [main] - ==> Parameters: 11(Integer), ttxxxxxx(String), 11(Integer), null
            DEBUG [main] - ==> Parameters: 12(Integer), ttxxxxx12(String), 12(Integer), null
             */
            sqlSession=sqlSessionFactory.openSession(ExecutorType.BATCH);
            UserMapper userMapper=sqlSession.getMapper(UserMapper.class);

            User user=new User();
            user.setUserId(11);
            user.setAge(11);
            user.setUserName("ttxxxxxx");
            userMapper.insertUser(user);

            user.setUserId(12);
            user.setAge(12);
            user.setUserName("ttxxxxx12");
            userMapper.insertUser(user);

            sqlSession.commit();

        }catch (Exception e){
            e.printStackTrace();
            if(sqlSession!=null){
                sqlSession.rollback();
            }
        }finally {
            if(sqlSession!=null){
                sqlSession.close();
            }
        }
    }

  4.3) 使用statement指定对应的方法,执行对应的sql

  该方法更加原始,更接近底层. 之前使用sqlSession.getMapper(UserMapper.class)获取对应的mapper实例, 不过是使用动态代理, 生成的代理类, 里面的方法也是使用stement指定对应的方法, 执行对应的sql

    /*
    sqlSession执行语句的的方法
    注意, statement是mapper对应的类名+方法名, 用于指定对应的sql语句

    <T> T selectOne(String statement, Object parameter)
    <E> List<E> selectList(String statement, Object parameter)
    <T> Cursor<T> selectCursor(String statement, Object parameter)  //返回一个游标, 可延迟获取数据
    <K,V> Map<K,V> selectMap(String statement, Object parameter, String mapKey)
    int insert(String statement, Object parameter)
    int update(String statement, Object parameter)
    int delete(String statement, Object parameter)
     */
    @Test
    public void execSqlTest(){
        try(SqlSession sqlSession=this.sqlSessionFactory.openSession()){

            Cursor<User> userCursor=sqlSession.selectCursor("com.ttx.example.mapper.UserMapper.selectUser", 1); // statement 是 类名+方法名

            Iterator<User> iter=userCursor.iterator();
            while (iter.hasNext()){
                User user=iter.next();
                System.out.println(user.getUserId()+" : "+ user.getUserName());
            }
        }
    }

  4.4) @SqlProvider 在java代码中编写sql

UserSqlProvider.java

public static String buildSelectUserById(){
        return new SQL(){{
            SELECT("*");
            FROM("user");
            WHERE("user_id = #{userId}");
            ORDER_BY("user_id");
        }}.toString();
    }

  UserSqlProviderMapper.java

    @ResultMap("UserMap")
    @SelectProvider(type = UserSqlProvider.class, method = "buildSelectUserById")
    User selectUserById(@Param("userId") int userId);

  UserSqlProviderMapper.xml

<?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="com.ttx.example.mapper.UserSqlProviderMapper">

    <!-- resultMap, 结果映射 -->
    <resultMap id="UserMap" type="com.ttx.example.entity.User">
        <constructor></constructor>  <!-- 用于引用构造参数, 可以省略掉 -->
        <id column="user_id" property="userId"/>  <!-- id 元素表示的结果将是对象的标识属性 -->
        <result column="user_name" property="userName"/>
        <result column="age" property="age"/>
        <result column="country" property="country"/>
    </resultMap>

</mapper>

  测试代码

    // 注解 @SelectProvider
    @Test
    public void sqlProviderTest(){

        try(SqlSession sqlSession=this.sqlSessionFactory.openSession()){
            UserSqlProviderMapper mapper=sqlSession.getMapper(UserSqlProviderMapper.class);
            User user=mapper.selectUserById(1);

            Assert.assertTrue(user.getUserId()==1);
        }

    }
    

  注意事项, 使用SqlSession之后, 需要关闭连接, 上面中的代码使用了try(){}, 会自动关闭

  源码点此查看

学习资料:

  官方文档

原文地址:https://www.cnblogs.com/timfruit/p/11391887.html

时间: 2024-07-29 02:23:39

mybatis从入门到精通(五) sqlSession API的使用的相关文章

mybatis从入门到精通(二) 增删查改

mybatis从入门到精通(二) 增删查改 一丶前言 "增删查改"是后台开发的常用操作, 因此, 学习mybatis或者其他orm框架有必要统一学习一下"增删查改". 二丶准备开发环境 使用"mybatis从入门到精通(一) 入门"准备的开发环境 三丶查 -- <select/> UserMapper.java User selectUser(@Param("userId") int userId); UserMa

mybatis从入门到精通(四) 动态SQL

mybatis从入门到精通(四) 动态SQL 一丶简介 Mybatis的强大特性之一是动态SQL, 它可以动态拼接sql语句, 减轻开发的工作量. Mybatis的动态sql标签如下4种类型 1. if 2. choose (when, otherwise) 3. trim (where, set) 4. foreach 二丶<if/> <if/>标签相当于java语言中的if语句, 通过判断是否符合预置条件来拼接sql语句.其中判断条件可以使用ongl表达式, 如e.method

MyBatis从入门到精通(一):MyBatis入门

最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 1. MyBatis简介 ? 2001年,Clinton Begin发起了一个名为iBATIS的开源项目,最初侧重于密码软件的研发,后来发展成为一款基于Java的持久层框架. ? 2004年,Clinton将iBATIS的名字和源码捐赠给了Apache软件基金会. ? 2010年,核心开发团队决定离开Apache软件基金会,并且将iBATIS改名

MyBatis从入门到精通(六):MyBatis动态Sql之if标签的用法

最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 本篇博客主要讲解如何使用if标签生成动态的Sql,主要包含以下3个场景: 根据查询条件实现动态查询 根据参数值实现动态更新某些列 根据参数值实现动态插入某些列 1. 使用if标签实现动态查询 假设有这样1个需求:根据用户的输入条件来查询用户列表,如果输入了用户名,就根据用户名模糊查询,如果输入了邮箱,就根据邮箱精确查询,如果同时输入了用户名和邮箱

MyBatis从入门到精通(十一):MyBatis高级结果映射之一对多映射

最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 本篇博客主要讲解MyBatis中如何使用collection标签实现查询结果一对多映射. 1. 使用collection标签 需求:根据用户id查询用户信息的同时获取用户拥有的角色,一个用户可以拥有1个或多个角色. 一般情况下,不建议直接修改数据库表对应的实体类. 所以这里我们延用之前博客中新建的类SysUserExtend,并添加如下代码,如下

MyBatis从入门到精通(十二):使用collection标签实现嵌套查询

最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 本篇博客主要讲解使用collection标签实现嵌套查询的方法. 1. 需求升级 在上篇博客中,我们实现了需求:根据用户id查询用户信息的同时获取用户拥有的角色. 因为角色可以拥有多个权限,所以本篇博客我们升级需求为:根据用户id查询用户信息的同时获取用户拥有的角色以及角色包含的权限. 2. 实现方式 因为我们需要使用到权限表的映射,所以我们需要

MyBatis基础入门《十五》ResultMap子元素(collection)

MyBatis基础入门<十五>ResultMap子元素(collection) 描述: 见<MyBatis基础入门<十四>ResultMap子元素(association )> >>collection >> 复杂类型集合,一对多 >> 内部嵌套 > 映射一个嵌套结果集到一个列表 >> 属性 > property : 映射数据库列的实体对象的属性 > ofType : 完整java类名或别名(集合所包括的

mybatis从入门到精通(三) 结果映射

mybatis从入门到精通(三) 结果映射 一丶什么是结果映射 结果映射是用于将数据库表字段和实体类中的属性名映射起来, 即究竟是哪个字段名与属性名对应. 映射之后, 即可通过mybatis将从数据库查询的结果转换成对应的实体类对象类型, 除去了人工转换的麻烦. 二丶自动映射 所谓的自动映射, 即是默认java实体类的属性名是驼峰式, 而数据库表字段名是以下划线分隔, 如 属性名userName 与 表字段user_name相对应, 如果是这种简单通用的规则, 即可通过配置mybatis, 使得

MyBatis从入门到精通:select用法

第一步,在接口中添加方法: public interface UserMapper { SysUser selectById(Long id); } 第二步,完成映射文件: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd