mybatis全域性配置檔案與對映檔案詳解
一、全域性配置檔案
1、概述
(1)SqlMapConfig.xml的配置內容和順序如下(順序不能亂):
Properties(屬性)
Settings(全域性引數設定)
typeAliases(類型別名)
typeHandlers(型別處理器)
objectFactory(物件工廠)
plugins(外掛)
environments(環境資訊集合)
environment(單個環境資訊)
transactionManager(事物)
dataSource(資料來源)
mappers(對映器)
2、全域性配置—properties
(1)全域性配置properties程式碼:
<!-- 載入Java配置檔案或宣告屬性資訊 -->
<properties resource="jdbcInfo.properties">
<!-- resource的載入順序比property標籤宣告的屬性更晚,因此會覆蓋 -->
<property name="jdbc.user" value="123"/>
</properties>
<!-- 配置mybatis的環境資訊,與spring整合是,該資訊由spring來配置 -->
<environments default="development">
<environment id="development">
<!-- 配置JDBC事務控制,由mybatis進行管理 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置資料來源,採用mybatis連線池 -->
<dataSource type="POOLED" >
<property name="driver" value="${jdbc.driverClass}"/>
<property name="url"
value="${jdbc.jdbcUrl}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
(2)資料庫配置檔案jdbcInfo.properties
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/mybatis
jdbc.user=root
jdbc.password=root
(3)載入的順序:
a、先載入properties中property標籤宣告的屬性
b、再載入properties標籤引入的java配置檔案中的屬性
c、parameterType的值會和properties的屬性值發生衝突
3、全域性配置—settings
4、全域性配置—typeAliases
(1)typeAliases:對po類進行別名的定義
(2)全域性配置程式碼:
<!-- 自定義別名 -->
<typeAliases>
<!-- 單個別名定義 -->
<!-- type:需要被取代的全限定類名 alias:別名
<typeAlias type="com.san.model.User" alias="user"/>
-->
<!-- 批量別名定義(推薦) -->
<!-- package:指定包名稱來為該包下的PO類宣告別名,預設的別名是型別(首字母大小寫都可以) -->
<package name="com.san.model"/>
</typeAliases>
(3)對映檔案程式碼:(次數對映檔案中的resultType就不需要使用全限定類名,直接使用別名就可以了)
<select id="findUserById" parameterType="int" resultType="user">
select * from user where id=#{id}
</select>
5、全域性配置—mappers
(1)使用相對於類路徑的資源
<mapper resource=’’/>
(2)使用完全限定路徑
<mapper url=’’/>
(3)使用mapper介面的全限定名
注意:此種方法要求mapper介面和mapper對映檔案要名稱相同,且放到同一個目錄下
<mapper class=’’/>
(4)註冊指定包下的所有對映檔案(推薦)
注意:此種方法要求mapper介面和mapper對映檔案要名稱相同,且放到同一個目錄下
<package name=’’/>
二、對映檔案之輸入對映
1、包裝pojo型別
(1)問題描述:
綜合查詢時,可能會根據使用者資訊、商品資訊、訂單資訊等作為條件進行查詢,使用者資訊中的查詢條件由;使用者的名稱和性別進行查詢
(2)編寫包裝pojo
public class UserQueryvo {
//使用者資訊
private User user;
private List<Integer> idList;
public List<Integer> getIdList() {
return idList;
}
public void setIdList(List<Integer> idList) {
this.idList = idList;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
(3)編寫對映檔案:
<!-- 綜合查詢,查詢使用者列表 -->
<!-- #{}中的引數名稱要和包裝pojo中的物件層級一致,並且屬性名稱要一致 -->
<select id="findUserList" parameterType="com.san.model.UserQueryvo" resultType="user">
select * from user
<!-- where標籤:預設去掉後面第一個and,如果沒有引數,則把自己幹掉 -->
<where>
<!-- 引入sql片段 -->
<include refid="whereClause"></include>
</where>
</select>
(4)mapper介面:
public List<User> findUserList(UserQueryvo vo);
(5)編寫測試:
@Test
//查詢使用者列表
public void Test2() throws IOException{
String resource="SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//sqlSession,它的內部含有一塊資料區域,存線上程不安全,因此宣告在方法內部
SqlSession sqlSession = sqlSessionFactory.openSession();
//建立UserMappper物件
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
//執行查詢語句
UserQueryvo vo=new UserQueryvo();
User user=new User();
user.setUsername("李四");
user.setSex("1");
vo.setUser(user);
List<User> list=userMapper.findUserList(vo);
System.out.println(list);
//關閉資源
sqlSession.close();
}
2、map型別
(1)對映檔案:
<!-- 傳遞hashmap綜合查詢使用者資訊 -->
<select id="findUserByHashmap" parameterType="hashmap" resultType="user">
select * from user where id=#{id} and username like '%${username}%'
</select>
(2)測試:
Public void testFindUserByHashmap()throws Exception{
//獲取session
SqlSession session = sqlSessionFactory.openSession();
//獲限mapper介面例項
UserMapper userMapper = session.getMapper(UserMapper.class);
//構造查詢條件Hashmap物件
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("id", 1);
map.put("username", "管理員");
//傳遞Hashmap物件查詢使用者列表
List<User>list = userMapper.findUserByHashmap(map);
//關閉session
session.close();
}
(3)異常測試:
傳遞的map中的key和sql中解析的key不一致
測試結果沒有報錯,只是通過key獲取值為空
三、對映檔案之輸出對映
1、resultType
(1)使用要求:
a、使用resultType進行結果對映時,需要查詢出的列名和對映的物件的屬性名一致,才能對映成功。
b、如果查詢的列名和物件的屬性名全部不一致,那麼對映的物件為空。
c、如果查詢的列名和物件的屬性名有一個一致,那麼對映的物件不為空,但是隻有對映正確那一個屬性才有值。
d、如果查詢的sql的列名有別名,那麼這個別名就是和屬性對映的列名。
(2)對映檔案:
<!-- 綜合查詢,查詢使用者的總數 -->
<select id="findUserCount" parameterType="com.san.model.UserQueryvo" resultType="int">
select count(*) from user
<where>
<include refid="whereClause"></include>
</where>
</select>
2、resultMap
(1)使用要求:
使用resultMap進行結果對映時,不需要查詢的列名和對映的屬性名必須一致。但是需要宣告一個resultMap,來對列名和屬性名進行對映。
(2)對映檔案:
<!-- id標籤:專門為查詢結果中唯一列對映 -->
<!-- result標籤:對映查詢結果中的普通列 -->
<!-- type標籤:返回型別 -->
<resultMap type="user" id="UserResMap">
<id column="id_" property="id"/>
<result column="username_" property="username"/>
<result column="sex_" property="sex"/>
</resultMap>
<select id="findUserRstMap" parameterType="int" resultMap="UserResMap">
select id id_,username username_,sex sex_ from user where id=#{id}
</select>
3、動態sql
(1)概述:
在mybatis中,它提供了一些動態sql標籤,可以讓程式設計師更快的進行mybatis的開發,這些動態sql可以通過sql的可重用性。
(2)常用的動態sql標籤:
if標籤、where標籤、sql片段、foreach標籤
(3)對映檔案(總的對映檔案):
<?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">
<!-- namespace:需要和mapper介面的全限定名一致 -->
<mapper namespace="com.san.mapper.UserMapper">
<!-- 通過ID查詢使用者 -->
<select id="findUserById" parameterType="int" resultType="user">
select * from user where id=#{id}
</select>
<!-- 定義sql片段 -->
<!-- sql片段內,可以定義sql語句中的任何內容 -->
<!-- sql片段內,最好不要使用where和select關鍵字宣告在內 -->
<sql id="whereClause">
<!-- if標籤:對輸入的引數進行判斷 -->
<!-- test標籤:指定判斷的表示式 -->
<if test="user!=null">
<!-- 判斷使用者名稱不為空 -->
<if test="user.username!=null and user.username!=''">
and username like '%${user.username}%'
</if>
<!-- 判斷性別不為空 -->
<if test="user.sex!=null and user.sex!=''">
and sex=#{user.sex}
</if>
</if>
<!-- 判斷集合 -->
<!-- collection:表示pojo中集合屬性的屬性名稱 -->
<!-- item:為遍歷出的結果宣告一個變數名稱 -->
<!-- open:遍歷開始時,需要拼接的字串 -->
<!-- close:遍歷結束時,需要拼接的字串 -->
<!-- separator:遍歷中間需要拼接的字串 -->
<if test="idList!=null">
and id in
<foreach collection="idList" item="id" open="(" close=")" separator=",">
<!-- and id in (#{id},#{id},#{id}) -->
#{id}
</foreach>
</if>
</sql>
<!-- 綜合查詢,查詢使用者列表 -->
<!-- #{}中的引數名稱要和包裝pojo中的物件層級一致,並且屬性名稱要一致 -->
<select id="findUserList" parameterType="com.san.model.UserQueryvo" resultType="user">
select * from user
<!-- where標籤:預設去掉後面第一個and,如果沒有引數,則把自己幹掉 -->
<where>
<!-- 引入sql片段 -->
<include refid="whereClause"></include>
</where>
</select>
<!-- 綜合查詢,查詢使用者的總數 -->
<select id="findUserCount" parameterType="com.san.model.UserQueryvo" resultType="int">
select count(*) from user
<where>
<include refid="whereClause"></include>
</where>
</select>
<!-- id標籤:專門為查詢結果中唯一列對映 -->
<!-- result標籤:對映查詢結果中的普通列 -->
<!-- type標籤:返回型別 -->
<resultMap type="user" id="UserResMap">
<id column="id_" property="id"/>
<result column="username_" property="username"/>
<result column="sex_" property="sex"/>
</resultMap>
<select id="findUserRstMap" parameterType="int" resultMap="UserResMap">
select id id_,username username_,sex sex_ from user where id=#{id}
</select>
</mapper>