一.全局配置文件配置
1.1 properties標簽
Properties標簽可以用來加載配置文件.例如,我們可以將數據庫的連接信息放入到一個配置文件(db.properties中..)
下為db.properties
db.driverClass=com.mysql.jdbc.Driver db.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8 db.username=root db.password=root
在全局配置文件SqlMapConfig.xml中引入該配置文件.
然后就可以在全局配置文件的關於數據庫的配置信息里使用配置文件的信息了
加載properties的順序:
1. 先加載<properties>標簽下的property標簽.觀察有沒有對應的鍵值對
2. 加載properties的resource屬性指定的配置文件.注意.這一步如果與上一步重名.那么將會覆蓋上一步聲明的屬性.例如:
圖中的property聲明的屬性將會被后加載的配置文件的相同的屬性給覆蓋
3.優先級最高的是paramterType中傳入的值.(這也是在配置文件中寫db.username而不寫username的原因..避免不必要的覆蓋!)
1.2 typeAlias.
1.2.1 mybatis默認支持的別名
別名 |
映射的類型 |
_byte |
byte |
_long |
long |
_short |
short |
_int |
int |
_integer |
int |
_double |
double |
_float |
float |
_boolean |
boolean |
string |
String |
byte |
Byte |
long |
Long |
short |
Short |
int |
Integer |
integer |
Integer |
double |
Double |
float |
Float |
boolean |
Boolean |
date |
Date |
decimal |
BigDecimal |
bigdecimal |
BigDecimal |
1.2.2 自定義別名
Mybatis對於基本的數據類型定義了別名,我們可以為我們自己創建的Pojo類定義別名.定義別名采用的是<typeAliases>標簽.
現在我們就可以使用別名了:
批量定義別名.(用於定義包)包下面的類的別名默認為類名.首字母大小寫即可.
使用別名:
1.3 mapper標簽
mapper標簽用於引入mapper配置文件.
1.3.1 <mapper resource=’’”/>
使用相對於類路徑的資源
如:<mapper resource="sqlmap/User.xml" />
1.3.2 <mapper url=’’”/>
使用完全限定路徑
如:<mapper url="file:///D:\workspace_spingmvc\mybatis_01\config\sqlmap\User.xml" />
1.3.3<mapper class=’’”/>
使用mapper接口的全限定名
如:<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
注意:此種方法要求mapper接口和mapper映射文件要名稱相同,且放到同一個目錄下;
1.3.4 <package name=’’/>(推薦)
注冊指定包下的所有映射文件
如:<package name="cn.itcast.mybatis.mapper"/>
注意:此種方法要求mapper接口和mapper映射文件要名稱相同,且放到同一個目錄下;
如下所示:
2.Mapping映射文件配置
2.1 傳遞輸入參數
2.1.1 傳遞包裝Pojo
包裝Pojo即一個類,當中有一個屬性為一個Pojo.而我們所需要的屬性被封裝在Pojo
下面是示例:我們將要查詢的信息封裝在一個Pojo類User中.然后將User類封裝在UserQueryVO中.
public class UserQueryVO { private User user ; public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
緊接着我們需要在mapper配置文件的輸入參數parameterType中聲明這個類.
然后需要寫SQL語句了.獲取對應的屬性值直接屬性名.屬性值即可.(無論嵌套多少層都沒事)
2.1.2 傳入HashMap
同傳遞POJO對象一樣,map的key相當於pojo的屬性。
@Test public void testMapper2() { SqlSession session = factory.openSession(); UserMapper mapper = session.getMapper(UserMapper.class);//建立代理對象 Map<String,String> map=new HashMap<>(); map.put("username", "小明"); map.put("sex", "1"); List<User> users = mapper.findUserByQueryMap(map); System.out.println(users); }
2.2 輸出映射
2.2.1 resultType的要點
查詢的列名和映射的pojo的屬性名一致,使用resultType映射才會成功。
如果查詢的列名和映射的pojo的屬性名全部不一致,則映射的pojo為null。
如果查詢的列名和映射的pojo的屬性名有一個一致,則映射的pojo不為null,而且只有一致的那一個屬性才有值。
2.2.2 resultType為簡單類型
@Test public void testResult1() { SqlSession session = factory.openSession(); UserMapper mapper = session.getMapper(UserMapper.class);//建立代理對象 int count = mapper.selectCount(); System.out.println(count); }
2.2.3 Pojo/Pojo集合
ResultType為單列的數據的類型.
2.2.4 resultMap
使用要求:
使用resultMap進行結果映射時,不需要查詢出的列名和映射的pojo的屬性名一致。但是需要定義一個resultMap標簽來完成列名和屬性名的映射關系。
需求:
將以下sql查詢出的結果進行映射。
Select id id_,username username_,sex sex_ from user where id = 1
由於查詢出的數據的名稱與Pojo類的屬性不一致,因此無法直接用resultType對結果進行映射.
所以我們采用resultMap進行映射.
具體方法如下:
1.在UserMapper.xml中進行配置
2/在UserMapper中添加方法
3.進行測試
@Test public void testResult2() { SqlSession session = factory.openSession(); UserMapper mapper = session.getMapper(UserMapper.class);//建立代理對象 User user = mapper.selectByResultMap(1); System.out.println(user); }
2.3 動態sql拼接
在mybatis提供了一些動態標簽,可以幫助開發人員更快,更方便的開發出持久層的代碼,常見的動態標簽有if標簽,
Where標簽,foreach標簽,sql片段標簽.
2.3.1 if標簽
在前面的關聯查詢中,我們用了下面的sql語句去根據關鍵字查詢.但是這樣實際是不合理的.
因為可能用戶在輸入的時候,根本就沒有輸入Username,只輸入了其中的一項(這時候只能根據這一項進行查詢),或者甚至什么都沒有輸入(這時候應該查詢出全部).而我們是沒有辦法提前去判斷用戶的輸入條件的.這時候就
需要根據用戶輸入的條件,動態的改變sql語句.用到了if標簽.if標簽用法如下,在if中書寫需要判斷的表達式,mybatis將會根據判斷的結果動態的將sql語句拼接起來.
<!-- 通過if標簽完成檢索 --> <select id="findUserByQuery" parameterType="com.xyy.po.UserQueryVO" resultType="user"> SELECT * FROM USER WHERE 1=1 <!-- 如果用戶輸入了username的情況下,才會進行關聯查詢.test內書寫表達式 --> <if test="user!=null"> <if test="user.username!=null and user.username!=''"> AND username LIKE '%${user.username}%' </if> <!-- 如果用戶輸入了sex的情況下,才會進行關聯查詢.test內書寫表達式 --> <if test="user.sex!=null and user.sex!=''"> and sex=#{user.sex}; </if> </if> </select>
2.3.2 where標簽
實際上在關聯查詢的where后面先拼接1=1是不好的做法,因為它會降低效率.更好的做法是用where標簽去替代:
Where標簽可以判斷后面有沒有內容.如果后面只有1個內容,就會將and去掉.並且拼接上where.如果后面有兩個或者以上的條件,那么將第一個條件,即where后面的條件,去掉and,然后將其他條件的and保留.如果后面沒有
條件,則在主的sql語句后面不會添加where關鍵字.具體做法如下:
<select id="findUserByQuery" parameterType="com.xyy.po.UserQueryVO" resultType="user"> SELECT * FROM USER <!-- 什么都沒輸,直接輸出SELECT * FROM USER --> <where> <!-- 如果user.username!=null而user.sex==null那么將會輸出WHERE username LIKE '%${user.username}%'.(默認去掉where后的第一個and) --> <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> </where> </select>
2.3.3 sql片段
Sql片段方便我們將一些sql語句中相同的部門提取出來,先聲明為sql片段,然后在書寫sql語句的時候,直接引用這些sql片段即可.注意,sql片段應該具有可復用性.具體做法如下所示:
<sql id="queryUser"> <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> </sql> <!-- 通過if標簽完成檢索 --> <select id="findUserByQuery" parameterType="com.xyy.po.UserQueryVO" resultType="user"> SELECT * FROM USER <!-- 什么都沒輸,直接輸出SELECT * FROM USER --> <where> <include refid="queryUser"></include> </where> </select>
2.3.4 foreach標簽.
例如,如果需要根據傳入的一系列的id,去查詢對應的用戶,要怎么做呢?
這種需求所對應的sql語句應該如下:
SELECT * FROM USER WHERE id IN (…)
括號內放的是傳入的所有id值.而我們在mybatis可以通過foreach標簽來完成對於傳入的集合的遍歷.具體做法如下所示:
<!-- 使用foreach標簽遍歷集合 --> <!-- collection為要遍歷的元素.open為在遍歷前要拼接的語句,close為要遍歷后要拼接的語句 --> <!-- separator為遍歷的每一個項目之間的分隔符,item為遍歷的項目的標識(相當於JSTLeach標簽的var) --> <if test="ids!=null and ids.size>0"> AND id IN <foreach collection="ids" open="(" close=")" separator="," item="id" > #{id} </foreach> <!-- 上述形式不固定,只要能拼接成AND id IN (id,id,id)即可(id表示每次遍歷得到的id) --> </if>
上面的是通過POJO對象傳入List集合,實際上我們可以直接傳入List集合.代碼如下:
需要注意的是獲取這個List集合,mybatis聲明的變量為list.而這個變量變量名是不可以改變的.
<!-- 通過直接傳入List集合完成檢索 --> <select id="findUserByQueryList" parameterType="java.util.List" resultType="user"> SELECT * FROM USER <!-- 什么都沒輸,直接輸出SELECT * FROM USER --> <where> <if test="list!=null and list.size>0"> id IN <foreach collection="list" open="(" close=")" item="id" separator=","> #{id} </foreach> </if> </where> </select>