說明
mybatis最重要的最強大的功能就是結果集映射,它的結果集映射能力是遠遠超過其他orm工具。
本博客就是利用mybatis代碼中的結果集映射,形成一個工具類。
依賴:3.5
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.0</version>
</dependency>
工具
該工具需要三個元素,1.config 2.mapper_xml,3工具類
mybatis-config.xml在classpath下
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<mappers>
<mapper resource="ccc.xml"/>
<!-- <mapper resource="ddd.xml"/> -->
</mappers>
</configuration>
ccc.xml在classpath下
<?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="ccc">
<resultMap type="com.bai.btsql.domin.Stu" id="stuResult">
<id column="sid" property="sid" jdbcType="INTEGER"/>
<result column="sname" property="sname" jdbcType="VARCHAR"/>
<association property="te" javaType="com.bai.btsql.domin.Te">
<id column="tid" property="tid" jdbcType="INTEGER"/>
<result column="tname" property="tname" jdbcType="VARCHAR"/>
</association>
</resultMap>
<resultMap type="com.bai.btsql.domin.User" id="userResult">
<id column="iiid" property="id" jdbcType="INTEGER"/>
</resultMap>
</mapper>
工具類:
package com.bai.btsql.mybatis;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import org.apache.ibatis.executor.SimpleExecutor;
import org.apache.ibatis.executor.resultset.DefaultResultSetHandler;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.MappedStatement.Builder;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
/**
* mybatis的結果集映射做成一個工具
* 本類在真正調用之後不要忘記關閉流
* @author Administrator
*
*/
public class MybatisResultHandler {
public static String configSource = "mybatis-config.xml";
public static Configuration configuration;
static {
init();
}
public static void init() {
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(configSource);
} catch (IOException e) {
throw new RuntimeException(e);
}
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
configuration = sqlSessionFactory.getConfiguration();
}
/**
* 根據resultid對Statement進行處理映射
* @param resultid 格式爲"${namespace}.${resultMapid}"
* @param st
* @return
* @throws SQLException
*/
public static List<Object> handleResult(String resultMapid, Statement st) throws SQLException {
List<ResultMap> maps = new ArrayList<>();
ResultMap map = configuration.getResultMap(resultMapid);
maps.add(map);
MappedStatement.Builder builder = new Builder(configuration, "", null,
null).resultMaps(maps);
DefaultResultSetHandler handler = new DefaultResultSetHandler(
new SimpleExecutor(configuration, null), builder.build(), null,
null, null, new RowBounds());
return handler.handleResultSets(st);
}
/**
* 測試
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
String JDBC_DRIVER = "com.mysql.jdbc.Driver";
String DB_URL = "jdbc:mysql://localhost/test1";
String USER = "root";
String PASS = "123456";
Connection conn = null;
Statement stmt = null;
Class.forName(JDBC_DRIVER);
conn = DriverManager.getConnection(DB_URL, USER, PASS);
stmt = conn.createStatement();
String sql;
sql = " select id iiid from user where id = 20";
stmt.executeQuery(sql);
List<Object> list = handleResult("ccc.user", stmt);
}
}
解析:
1.該工具類的init方法是進行初始化,加載config,以及加載mapper_xml,
並將mapper_xml的resultMaps解析成 HashMap<String resultMapid,ResultMap>。
注意hashmap的鍵,每一個ResultMap都會生產兩個Entry,分別是Entry<resultMapid,ResultMap>和Entry<namespace.resultMapid,ResultMap>,第二個會在resultMapid的前面加上xml的namespace以及一個逗點。
這也是爲了防止不同的xml裏的resultMapid是相同的,導致map出現覆蓋現象。
所以在使用的時候,爲了以防萬一,我們一律要傳遞的是${namespace}.${resultMapid}
2.handleResult的方法就是處理statement的方法。
它需要傳入一個resultMapid,然後從 HashMap<String resultMapid,ResultMap>裏獲取到它的ResultMap.
由於Mybatis進行的結果映射處理類及方法是:DefaultResultSetHandler.handleResultSets,所以我們還需要去構建一個DefaultResultSetHandler。
DefaultResultSetHandler構造時又需要一個MappedStatement,所以還要構建一個MappedStatement順便把ResultMap傳進去。至於其他的參數,均只是爲了防止DefaultResultSetHandler.handleResultSets報錯的。不影響報錯的參數都已經置爲null了。
3.最後一個main方法是測試的,使用jdbc獲取statement使用本方法,執行映射成功
4.使用完請注意關閉流