MyBatis官方文件學習
介紹
MyBatis是一個基於Java的持久層框架,具備長期儲存能力,可以使用巨大的磁碟空間儲存相當量的資料。
- 持久化:將程式的資料在持久狀態和瞬時狀態轉化的過程
- 持久層:完成持久化框架的程式碼塊
MyBatis 可以通過簡單的 XML 或註解來配置和對映原始型別、介面和 Java POJO(Plain Old Java Objects,普通老式 Java 物件)為資料庫中的記錄。
此外,在MyBatis-Spring中提供了@Mapper註解和@MapperScan註解,用於和Spring進行整合。
為什麼使用MyBatis
在傳統JDBC中,我們除了提供SQL外,還需要操作Connection、Statment、ResultSet,不僅如此,為了訪問不同的表,不同欄位的資料,我們需要些很多雷同模板化的程式碼。而我們在使用了 MyBatis 之後,只需要提供 SQL 語句就好了
靈活,SQL寫在XML裡面,便於統一管理和優化。
解除SQL與程式程式碼的耦合,將業務邏輯和資料訪問邏輯分離,提高了可維護性。
提供對映標籤,支援物件與資料庫的orm欄位關係對映。
提供物件關係對映標籤,支援物件關係組建維護。
提供xml標籤,支援編寫動態sql。
MyBatis程式
程式碼塊
Java
package com.pojo; public class User { private Long id; private String name; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + '}'; } }
程式碼塊
Java
package com.dao;
public interface UserDao {
List<User> getUserList();
User getUserById(int id);
int addUser(User user);
int updateUser(User user);
int deleteUser(int id);
}
程式碼塊
XML
<!--UserMapper.xml(mapper配置檔案)--> <?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=繫結一個對應的Dao/Mapper介面--> <mapper namespace="com.dao.UserDao"> <!--id對應Dao裡面的方法名字--> <!--resultType是前面User類的路徑--> <select id="getUserList" resultType="com.pojo.User"> select * from user </select> <select id="getUserById" parameterType="int" resultType="com.pojo.User"> select * from user where id = #{id} </select> <!--物件中的屬性,可以直接取出來 eg:id,name--> <insert id="addUser" parameterType="com.pojo.User"> insert into user (id, name) values (#{id}, #{name}); </insert> <update id="updateUser" parameterType="com.pojo.User"> update user set name=#{name} where id=#{id}; </update> <!--parameter="int"等型別時可以省略--> <delete id="deleteUser" parameter="int"> delete from user where id=#{id}; </delete> </mapper>
XML對映器
1. namespace
namespace中的包名要和dao/mapper介面的包名一致
2. select,insert,update,delete
- id是對應的namespace中的方法名
- resultType:SQL語句執行的返回值。
- parameterType:引數型別
動態SQL
用於拼接SQL語句
1. if
使用動態 SQL 最常見情景是根據條件包含 where 子句的一部分。
比如:想利用兩個引數進行可選搜尋
程式碼塊
XML
<!--SELECT * FROM User WHERE name="Lisa" AND id=1;-->
<select id="queryUser" resultType="com.pojo.User">
select * from user where
<if test="name != null">
name = #{name}
</if>
<if test="id != null">
id = #{id}
</if>
</select>
2. choose,when,otherwise
不想使用所有條件的時候,想從多個條件中選擇一個使用,類似Java中的switch語句
eg:傳入了id就按id查詢,傳入了name就按name查詢,如果兩者都沒有傳入,就返回age為23的User
程式碼塊
XML
<select id="queryUser" resultType="User">
select * from user where
<choose>
<when test="id != null">
id = #{id}
</when>
<when test="name != null">
name = #{name}
</when>
<otherwise>
age = 23
</otherwise>
</choose>
</select>
3. where
上述情況會出現變數都沒有傳入的情況,導致查詢失敗
做如下調整:
程式碼塊
XML
<select id="queryUser" resultType="com.pojo.User">
select * from user
<where>
<if test="name != null">
name = #{name}
</if>
<if test="age != null">
and age = #{age}
</if>
</where>
</select>
where 元素只會在子元素返回任何內容的情況下才插入 “WHERE” 子句。而且,若子句的開頭為 “AND” 或 “OR”,where 元素也會將它們去除。
4. set
用於動態更新語句的類似解決方案是set,set元素可以用於動態包含需要更新的列,忽略其他不更新的列
程式碼塊
XML
<update id="updateUser">
update User
<set>
<if test="name != null">
name = #{name},
</if>
<if test="age != null">
age = #{age}
</if>
</set>
where id=#{id}
</update>
5. trim,prefix,prefixOverrides,suffix,suffixOverrides
trim標記是一個格式化的標記,可以完成set或者是where標記的功能
WHERE
程式碼塊
XML
select * from user
<trim prefix="WHERE" prefixOverride="AND |OR "> <!--後面的空格是有存在的必要的-->
<if test="id != null">
AND id= #{id}
</if>
<if test="name != null">
AND name= #{name}
</if>
</trim>
如果id和name都不為null的話,SQL為SELECT * FROM user WHERE id="**" AND name="***"
prefix:在trim標籤內sql語句加上字首。
prefixOverrides:指定去除多餘的字首內容 如:prefixOverrides = "and",去除trim標籤內sql語句多餘的字首"and"。
SET
程式碼塊
XML
insert into user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="name != null">
name,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=BIGINT},
</if>
<if test="name != null">
#{name. jdbcType=VARCHAR},
</if>
</trim>
suffix:在trim標籤內sql語句加上字尾。
suffixOverrides:指定去除多餘的字尾內容,如:suffixOverrides=",",去除trim標籤內sql語句多餘的字尾","。
6. inclue refid & resultMap
1、首先定義一個sql標籤,一定要定義唯一id
2、然後通過id引用
<select id="selectAll"> select <include refid="Base_Column_List" /> from 表名 </select>
resultMap可以將查詢到的複雜資料(比如查詢到幾個表中資料)對映到一個結果集當中。
eg:
程式碼塊
XML
<resultMap id="BaseResultMap" type="com.pojo.User">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="age" jdbcType="INTEGER" property="age" />
</resultMap>
<sql id="Base_Column_List">
id, name, age
</sql>
<select id="queryUser" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from user
where id = #{id,jdbcType=BIGINT}
order by id desc
<if test="pageNum != null and pageSize != null">
limit ${pageNum*pageSize}, #{pageSize}
<!--limit兩個引數,第一個表示從第幾行資料開始查,第二個表示查幾條資料-->
</if>
</select>