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(){}, 會自動關閉

 

  源碼點此查看

 

學習資料:

  官方文檔

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM