Mybatis應用手冊

xbhog發表於2023-03-26

重學mybatis框架,匯成應用手冊,整理mybatis中用法且附相關例項,方便日常回顧
目錄結構:

imgimg

-----------------

Github手冊地址https://github.com/xbhog/MyBatisAppManual

----------------

MyaBtis基本知識點

mybatis初始對應關係需要注意:

  1. pojo類對應資料庫中表中的欄位。
  2. mapper介面對應的xml中的名稱空間。
  3. 介面中的抽象方法對應xml中的id值。
  4. 最後需要引入對映檔案檔案:
<mapper resource="mapper/UserMapper.xml"/>

對於增刪改來說,返回值都是整形,可以預設,對於查詢來說就比較複雜一些。

查詢的標籤select必須設定屬性resultType或resultMap,用於設定實體類和資料庫表的對映

關係

當查詢的資料為多條時,不能使用實體類作為返回值,只能使用集合,否則會丟擲異常

  1. resultType:自動對映,用於屬性名和表中欄位名一致的情況
  2. resultMap:自定義對映,用於一對多或多對一或欄位名和屬性名不一致的情況

以下使用需要注意順序

可以使用properties標籤引入properties檔案。

配置的方式可以有三種:

  1. 完全在mybatis-config.xml配置中寫
  2. 生成xxx.properties,透過外部xml配置引入
  3. 一部分在xml中配置,一部分透過外部引入實現

更多的請看MyBatis官網-屬性

MyBatis的使用:資料庫表--> pojo -->mapperService -->mapper.xml

其中在mapper.xml中透過<select></select>返回的值是物件,就需要透過resultType/resultMap返回結果集,如果不使用別名,那麼我們需要使用類的全限定名稱。

<select id="getUserAll" resultType="com.xbhog.pojo.User">
        select * from user
</select>

別名的使用,用的最多的為<typeAliases> <package/></typeAliases>(以包為單位,設定該包下所有的型別都擁有預設的別名(類名即別名),且類名不區分大小寫)。方便,不用使用全類名了。

<typeAliases>
        <package name="com.xbhog.pojo"/>
</typeAliases>
<!--不區分大小寫user/User -->
<select id="getUserAll" resultType="User">
        select * from user
</select>

結束

對映器(Mappers):

既然 MyBatis 的行為已經由上述元素配置完了,我們現在就要來定義 SQL 對映語句了。 但首先,我們需要告訴 MyBatis 到哪裡去找到這些語句。 在自動查詢資源方面,Java 並沒有提供一個很好的解決方案,所以最好的辦法是直接告訴 MyBatis 到哪裡去找對映檔案。 你可以使用相對於類路徑的資源引用,或完全限定資源定位符(包括 file:/// 形式的 URL),或類名和包名等

有四種實現方式:

詳情檢視MyBatis官網--對映器(Mappers)

我們說最後一個:

resource中的mapper,也可以以包為單位,將包下所有的對映檔案引入核心配置檔案

注意:此方式必須保證mapper介面和mapper對映檔案必須在相同的包下

建立的時候需要在resource不支援像Java一樣的使用 ,我們可以使用 xxx/xxx/xxx;

<!--引入對映檔案-->
<mappers>
<!--<mapper resource="mapper/UserMapper.xml"/>-->
   <package name="com.xbhog.mapper"/>
</mappers>

MyBatis傳參的方式

獲取引數值的兩種方式(重要) xxx表示傳入的引數

${} 本質為字串拼接:形式:**xxx**,有sql注入的風險,單引號需要手動字串拼接

#{}本質為佔位符賦值:形式:**?** -->**'xxx'**

第一種情況:單個字面量傳入

若mapper介面中的方法引數為單個的字面量型別(例:String name) ,此時可以使用${}#{}以任意的名稱(xxx)獲取引數的值,注意**${}**-->字串(傳啥就是啥),所以需要手動加單引號.

// java
private void getParams(UserMapper mapper) {
    User aaa = mapper.getUserByParams("aaa");
    System.out.println(aaa);
}
//mapper
User getUserByParams(@Param("username") String username);
//xml
<select id="getUserByParams" resultType="user">
    select * from user where name=#{username};
</select>

第二種情況:多個字面量傳入

若mapper介面中的方法引數為多個時,此時MyBatis會自動將這些引數放在一個map集合中,以arg0,arg1...為鍵,以引數為值;以 param1,param2...為鍵,以引數為值;因此只需要透過\({}和#{}訪問map集合的鍵就可以獲取相對應的值**,注意**`**\){}`需要手動加單引號 ;**

//java
 private void moreArgs(UserMapper mapper) {
    User userByName = mapper.getUserByName("xbhog");
    User userByNameAndPwd = mapper.getUserByNameAndPwd("xbhog", "14646");

    System.out.println(userByName + "----" + userByNameAndPwd);
}
//mapper
User getUserByName(String name);
User getUserByNameAndPwd(String name,String pwd);

//xml
<select id="getUserByName" resultType="User">
    <!--select * from user where name=#{username}-->
    select * from user where name='${username}'
</select>
<select id="getUserByNameAndPwd" resultType="user">
    <!--select  * from user where name=#{arg0} and pwd=#{arg1}-->
    select  * from user where name='${param1}' and pwd='${param2}'
</select>

相關對映:

img

img

img

第三種情況:map傳入

若mapper介面中的方法需要的引數為多個時,出來MyBatis自動建立Map,我們也可以手動建立map集合,將這些資料放在map中 ;

只需要透過${}和#{}訪問map集合的鍵就可以獲取相對應的值,注意${}需要手動加單引號

//java
private void mapArgs(UserMapper mapper) {
        Map<String, Object> map = Map.of("username","xbhog");
        User user = mapper.checkLogin(map);
        System.out.println(user);
}
//mapper
User checkLogin(Map map);
//xml
<select id="checkLogin" resultType="user">
        select * from user where name=#{username}
</select>

第四種情況:物件傳入

若mapper介面中的方法引數為實體類物件時

此時可以使用${}和#{},透過訪問實體類物件中的屬性名獲取屬性值,注意${}需要手動加單引號

//java
private void insertObject(UserMapper mapper) {
        int i = mapper.insertUserByUser(new User(null, "aaa", "aaa"));
        System.out.println(i);
}
//mapper
int insertUserByUser(User user);
//xml
<insert id="insertUserByUser" >
        insert into user values (null,#{name},#{pwd});
</insert>

第五種情況:@param()傳入

需求:之前傳參後接受引數的名字都是不固定的,最好我們自己給它限定名字。

對於單個或多個自變數使用@param()來確定傳入的引數名****(這才是重重點)

可以透過@Param註解來標識mapper介面中方法引數名的確定名

此時,會將這些引數放在map集合中,以@Param註解的value屬性值為鍵,以引數為值;以

param1,param2...為鍵,以引數為值;只需要透過${}和#{}訪問map集合的鍵就可以獲取相對應的值,

注意${}需要手動加單引號

//java
User aaa = mapper.getUserByParams("aaa");
            System.out.println(aaa);
/*mapper:mybatis會把param中的username當作key,String後面的作為value*/
User getUserByParams(@Param("username") String username);
//xml
<select id="getUserByParams" resultType="user">
        select * from user where name=#{username};
</select>

MyaBtis各種查詢功能

查詢一個實體類或者查詢一個List集合

/*** 根據使用者id查詢使用者資訊 * @param id * @return */ 
//mapper 查詢一個實體類
User getUserById(@Param("id") int id); 
/*xml*/
<select id="getUserById" resultType="User"> 
select * from t_user where id = #{id} 
</select>
//-------------------------------------------------------------------
//mapper  查詢一個List集合
List<User> getUserAll();
/*xml(如果在核心配置中使用了別名,可以直接使用user,不用使用全類名)*/
<select id="getUserAll" resultType="com.xbhog.pojo.User">
        select * from user
</select>
/*上簡化
---核心配置mybatis-config.xml*/
<typeAliases>
        <package name="com.xbhog.pojo"/>
</typeAliases>
/*簡化 別名不區分大小寫*/
<select id="getUserAll" resultType="User">
        select * from user
</select>

查詢一條/多條資料為map集合

//java
private void getUserToMap(UserMapper mapper) {
        List<Map<String, Object>> userToMap = mapper.getUserToMap();
        System.out.println(userToMap);
}
//mapper  以MapKey設定的欄位為key,map中的key不能重複,所以選擇id作為key,
List<Map<String,Object>> getUserToMap();
//xml
<select id="getUserToMap" resultType="map">
        select * from user where id=#{id};
</select>
 
//map無序,結果
{name=世傑, id=1, pwd=123456}
//以MapKey設定的欄位為key,返回的結果為map且其中key不能重複,所以選擇id作為key;
/**查詢所有使用者資訊為map集合
將表中的資料以map集合的方式查詢,一條資料對應一個map;若有多條資料,就會產生多個map集合,
並且最終要以一個map的方式返回資料,此時需要透過@MapKey註解設定map集合的鍵,
值是每條資料所對應的map集合 */
//mapper
@MapKey("id")
Map<String,Object> getUserToMap();
//Usermapper.xml
<select id="getUserToMap" resultType="map">
        select *  from user;
</select>
 //java
Map<String, Object> userToMap = mapper.getUserToMap();
System.out.println(userToMap);
//結果
{1={name=世傑, id=1, pwd=123456}, 3={name=Update, id=3, pwd=success}, 
 4={name=xbhog, id=4, pwd=14646}, 5={name=ylj, id=5, pwd=111111}, 
 6={name=ylj, id=6, pwd=111111}, 7={name=ylj, id=7, pwd=111111}, 
 8={name=aaa, id=8, pwd=aaa}}

List版本:

//將表中的資料以map集合的方式查詢,一條資料對應一個map;
//若有多條資料,就會產生多個map集合,此時可以將這些map放在一個list集合中獲取
List<Map<String,Object>> getUserToMap();
<select id="getUserToMap" resultType="map">
        select * from user;
</select>
//結果  
[{name=世傑, id=1, pwd=123456}, {name=Update, id=3, pwd=success},
 {name=xbhog, id=4, pwd=14646}, {name=ylj, id=5, pwd=111111}, 
 {name=ylj, id=6, pwd=111111}, {name=ylj, id=7, pwd=111111}, 
 {name=aaa, id=8, pwd=aaa}]

特殊Sql的執行(都需要使用${})

模糊匹配:

//java
private void mohuTest(UserMapper mapper) {
        List<User> xbhog = mapper.testMohu("x");
        System.out.println(xbhog);
}
//mapper
List<User> testMohu(@Param("mohu") String mohu);

//三種方式都能實現
<select id="testMohu" resultType="user">
    select * from user where name like '%${mohu}%'
    //mysql函式拼接
    //select * from user where name like concat('%',#{mohu},'%')
    //select * from user where name like "%"#{mohu}"%"
</select>
//使用#{}
//select * from user where name like '%#{mohu}%'報錯
select * from user where name like '%?%'

批次刪除:

//java
 private void batchDelete(UserMapper mapper) {
        int i = mapper.deleteAll("1,2,10");
        System.out.println(i);
}
//mapper
int deleteAll(@Param("ids") String ids);	
//xml
<delete id="deleteAll">
        delete from user where id in (#{ids});
</delete>

//如果使用#{}--->?
delete from user where id in (?);  //報錯,不符合mysql語法格式,所以需要使用${}
//正確方式開啟
delete from user where id in (${ids});

動態設定表名:

/**
 * 動態設定表名
*/
List<User> getAllByTableName(@Param("tableName") String tableName);
//xml,使用#{}會造成 'user' 報錯,
// ${} --> user
<select id="getAllByTableName" resultType="user">
        select * from ${tableName};
</select>
//test
List<User> user = mapper.getAllByTableName("user");
user.forEach(System.out::println);
//result
User(id=3, name=Update, pwd=success)
...

獲取自增的主鍵

useGeneratedKeys:設定使用自增的主鍵

keyProperty:因為增刪改有統一的返回值是受影響的行數,因此只能將獲取的自增的主鍵放在傳輸的參

數user物件的某個屬性中

//java
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher t1 = new Teacher(null, "aaa");
mapper.insertDemo(t1);
System.out.println(t1);
//mapper
int insertDemo(Teacher teacher);
//xml
<insert id="insertDemo" useGeneratedKeys="true" keyProperty="id">
        insert into teacher values (null,#{name});
</insert>

無法獲取自增後的id:

資料庫中的id需要設定主鍵且自增。

資料庫中的主鍵一直沒法自增,在設計表的選項中無法修改自增。這應該是表設計的問題。

img

自定義對映ResultMap

解決的問題

因為屬性中命名規範和資料庫中的命名規範不同(empName---emp_name);reslutType只能獲取屬性和資料庫中相同的屬性的值,所以這時候需要使用ResultMap.

若欄位名和實體類中的屬性名不一致,則可以透過resultMap設定自定義對映

多對一:多個員工對應一個部門

一對多:一個部門對應多個員工

所以部門中的員工實體類是List結合,員工實體類中是物件屬性;

實體類:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dept {
    private Integer did;
    private String deptName;
    private List<Emp> emps;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Emp {
    private Integer eid;
    private String empName;
    private Integer age;
    private Dept dept;

}

多對一:物件

聯表查詢:

//java
private void selectTableQuery(EmpMapper mapper) {
        //連表查詢
        Emp empAllDate = mapper.getEmpAllDate(3);
        System.out.println(empAllDate);
}
/**
 * mapper 聯表查詢多對一
 */
Emp getEmpAllDate(@Param("eid") Integer eid);
//對映檔案 xml
<resultMap id="getEmpAndDept" type="Emp">
    <id property="eid" column="eid"/>
    <result property="empName" column="emp_name"/>
    <result property="age" column="age"/>
    <result property="dept.did" column="did"/>
    <result property="dept.deptName" column="dept_name"/>
</resultMap>
<select id="getEmpAllDate" resultMap="getEmpAndDept">
    select * from t_emp e left join t_dept d on e.did=d.did where
    e.eid=#{eid}
</select>

//結果
Emp(eid=3, empName=王五, age=24, dept=Dept(did=3, deptName=C, emps=null))

注意的幾點:dept.xxx會爆紅,可忽略

  1. resutMap id對應的是select中reslutMap;
  2. resultMap返回的型別對應的是select返回的資料;
  3. 對於emp實體類中的dept需要單獨將屬性拿出來對應

association

//java
private void associationQuery(EmpMapper mapper) {
        Emp empAndDept = mapper.getEmpAndDept(3);
        System.out.println(empAndDept);
}
//mapper
Emp getEmpAndDept(@Param("eid") Integer eid);
//xml
 <!--多對一常用association標籤-->
    <resultMap id="getEmp" type="Emp">
        <id property="eid" column="eid"/>
        <result property="age" column="age"/>
        <result property="empName" column="emp_name"/>
        <association property="dept" javaType="Dept">
            <id property="did" column="did"/>
            <result property="deptName" column="dept_name"/>
        </association>
    </resultMap>
<select id="getEmpAndDept" resultMap="getEmp">
        select * from t_emp emp left join t_dept dept on emp.eid = dept.did where eid=#{eid};
</select>
//結果
DEBUG 06-03 15:49:36,486 ==>  Preparing: select * from t_emp emp left join t_dept dept on emp.eid = dept.did where eid=?; (BaseJdbcLogger.java:137) 
DEBUG 06-03 15:49:36,503 ==> Parameters: 3(Integer) (BaseJdbcLogger.java:137) 
DEBUG 06-03 15:49:36,533 <==      Total: 1 (BaseJdbcLogger.java:137) 
Emp(eid=3, empName=王五, age=24, dept=Dept(did=3, deptName=C, emps=null))

基於association的分步查詢:

先查emp,在查dept,最後綜合。

//java
private void splitSept(EmpMapper mapper) {
        //分步查詢
        Emp empAndDeptStepOne = mapper.getEmpAndDeptStepOne(3);
        System.out.println(empAndDeptStepOne.getEmpName());
}
/**mapper
 * 分步查詢 stepOne
 */
Emp getEmpAndDeptStepOne(@Param("eid") Integer eid);
//xml
<resultMap id="getEmpSetpOne" type="Emp">
        <id property="eid" column="eid"/>
        <result property="age" column="age"/>
        <result property="empName" column="emp_name"/>
    <association property="dept"
    select="com.xbhog.mapper.DeptMapper.getDeptSetupTwo"
    fetchType="eager"
    column="did"/>
</resultMap>
<select id="getEmpAndDeptStepOne" resultMap="getEmpSetpOne">
        select * from t_emp where t_emp.eid=#{eid}
</select>
/**
     * 分步查詢:stepTwo,
     */
Dept getDeptSetupTwo(@Param("did") Integer did);

 <select id="getDeptSetupTwo" resultType="dept">
        select * from t_dept where t_dept.did=#{did};
</select>
  1. select:設定下一步查詢點,使用絕對定位,名稱空間+id值
  2. column:欄位值是作為下一步的入參
  3. 在mybatis-config.xml開啟懶載入,
<!--開啟懶載入-->
<setting name="lazyLoadingEnabled" value="true"/>
  1. fetchType:控制延遲載入的效果,懶載入開啟是前提,eager,(全部執行),lazy表示延遲載入(用到啥執行啥)
DEBUG 06-03 15:54:30,048 ==>  Preparing: select * from t_emp where t_emp.eid=? (BaseJdbcLogger.java:137) 
DEBUG 06-03 15:54:30,066 ==> Parameters: 3(Integer) (BaseJdbcLogger.java:137) 
DEBUG 06-03 15:54:30,098 ====>  Preparing: select * from t_dept where t_dept.did=?; (BaseJdbcLogger.java:137) 
DEBUG 06-03 15:54:30,098 ====> Parameters: 3(Integer) (BaseJdbcLogger.java:137) 
DEBUG 06-03 15:54:30,123 <====      Total: 1 (BaseJdbcLogger.java:137) 
DEBUG 06-03 15:54:30,123 <==      Total: 1 (BaseJdbcLogger.java:137) 
Emp(eid=3, empName=王五, age=24, dept=Dept(did=3, deptName=C, emps=null))

單查:
DEBUG 06-03 15:55:46,779 ==>  Preparing: select * from t_emp where t_emp.eid=? (BaseJdbcLogger.java:137) 
DEBUG 06-03 15:55:46,796 ==> Parameters: 3(Integer) (BaseJdbcLogger.java:137) 
DEBUG 06-03 15:55:46,899 <==      Total: 1 (BaseJdbcLogger.java:137) 
王五

一對多:集合(collection)

//java
public void demoTest2() throws IOException {
        SqlSession sqlSession = getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        Dept deptAndEmpByStepOne = mapper.getDeptAndEmpByStepOne(1);
        System.out.println(deptAndEmpByStepOne);

}
/**mapper
 * 透過id查詢部門中的員工資訊,一對多
 * @param did
 * @return
 */
Dept getDeptAndEmpByStepOne(@Param("did") Integer did);
//xml
<resultMap id="getDeptAndEmp" type="Dept">
        <id property="did" column="did"/>
        <result property="deptName" column="dept_name"/>
        <collection property="emps"
                    select="com.xbhog.mapper.DeptMapper.getDeptAndEmpByStepTwo"
                    column="did"/>
</resultMap>
<select id="getDeptAndEmpByStepOne" resultMap="getDeptAndEmp">
        select * from t_dept dept where dept.did=#{did};
</select>
<select id="getDeptAndEmpByStepTwo" resultType="Emp">
        select * from t_emp emp where did = #{did};
</select>
DEBUG 06-03 16:43:46,330 ==>  Preparing: select * from t_dept dept where dept.did=?; (BaseJdbcLogger.java:137) 
DEBUG 06-03 16:43:46,346 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:137) 
DEBUG 06-03 16:43:46,402 <==      Total: 1 (BaseJdbcLogger.java:137) 
DEBUG 06-03 16:43:46,402 ==>  Preparing: select * from t_emp emp where did = ?; (BaseJdbcLogger.java:137) 
DEBUG 06-03 16:43:46,403 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:137) 
DEBUG 06-03 16:43:46,422 <==      Total: 2 (BaseJdbcLogger.java:137) 
Dept(did=1, deptName=A, emps=[Emp(eid=1, empName=張三, age=22, dept=null), Emp(eid=4, empName=趙六, age=25, dept=null)])

需要注意的是集合採用的用collection標籤

動態sql:

標籤的作用在我看來是對sql的一步一步的解耦,方便後續的擴充和使用。

常用的標籤如下:

  1. **<if> <where>**
  2. **<trim>**
  3. <choose> <when><otherwise>
  4. forEach
  5. sql片段

if與where標籤

if標籤可透過test屬性的表示式進行判斷,若表示式的結果為true,則標籤中的內容會執行;反之標籤中

的內容不會執行。

  1. 若where標籤中的if條件都不滿足,則where標籤沒有任何功能,即不會新增where關鍵字
  2. 若where標籤中的if條件滿足,則where標籤會自動新增where關鍵字,並將條件最前方多餘的and去掉
User getDemo(User user);

 <select id="getDemo" resultType="User">
        select * from user
        <where>
            <if test="name != null and name != ''">
                and name =#{name}
            </if>
            <if test="pwd != null and pwd != ''">
                and pwd=#{pwd};
            </if>
        </where>
    </select>
//測試
User xbhog = mapper.getDemo(new User(null, "xbhog", null));
System.out.println(xbhog);
//結果
DEBUG 06-03 20:58:12,645 ==>  Preparing: select * from user WHERE name =? (BaseJdbcLogger.java:137) 
DEBUG 06-03 20:58:12,668 ==> Parameters: xbhog(String) (BaseJdbcLogger.java:137) 
DEBUG 06-03 20:58:12,758 <==      Total: 1 (BaseJdbcLogger.java:137) 
User(id=2, name=xbhog, pwd=111111)

其中注意點:

  1. 使用**<where>**標籤只能忽略**<if>**標籤中前面的and,不能忽略後面的and

如果不知道什麼原因,sql正確,語法正確,對應關係、實體類和資料庫都對應但是還無法查出資料,請檢視MySQL對應關係和版本資訊(大機率是它的鍋)

trim標籤

<where>去掉<if>標籤前面的內容,<trim>去掉<if>標籤後面的內容

用於去掉或新增標籤中的內容

prefix:在trim標籤中的內容的前面新增某些內容

prefixOverrides:在trim標籤中的內容的前面去掉某些內容

如果lastName= null,sql: ....where and age = ?(錯誤)

透過prefixOverrides 可以除去把首個“and”去掉

<trim prefix="where">
  <if test="lastName != null">
    last_name=#{lastName}
  </if>
  <if test="age != null">
    and age=#{age}
  </if>
  <if test="phone != null">
    and phone=#{phone}
  </if>
</trim>

suffix:在trim標籤中的內容的後面新增某些內容

suffixOverrides:在trim標籤中的內容的後面去掉某些內容

最後一個if條件不成立,去除最後的引號欄位:suffixOverrides=“”

choose&when&otherwise標籤

相當於if...else if..else

foreach標籤

屬性:

  1. collection:設定要迴圈的陣列或集合
  2. item:表示集合或陣列中的每一個資料
  3. separator:設定迴圈體之間的分隔符
  4. open:設定foreach標籤中的內容的開始符
  5. close:設定foreach標籤中的內容的結束符

主要用來批處理資料

Integer insertAllUser(@Param("users") List<User> users);

<insert id="insertAllUser">
        insert into user values
        <foreach collection="users" item="user" separator=",">
            (null,#{user.name},#{user.age},#{user.pwd})
    </foreach>
</insert>
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user1 = new User(null, "a1", 22, "aaa");
User user2 = new User(null, "a2", 22, "aaa");
User user3 = new User(null, "a3", 22, "aaa");
List<User> users = Arrays.asList(user1, user2, user3);
Integer i = mapper.insertAllUser(users);
System.out.println(i);
DEBUG 06-03 22:04:15,713 ==>  Preparing: insert into user values (null,?,?,?) , (null,?,?,?) , (null,?,?,?) (BaseJdbcLogger.java:137) 
DEBUG 06-03 22:04:15,736 ==> Parameters: a1(String), 22(Integer), aaa(String), a2(String), 22(Integer), aaa(String), a3(String), 22(Integer), aaa(String) (BaseJdbcLogger.java:137) 
DEBUG 06-03 22:04:15,779 <==    Updates: 3 (BaseJdbcLogger.java:137) 
3

需要注意的是,在獲取user中的屬性的時候,一定要使用xxx.屬性名的格式,否則找不到對應。

Integer deleteAllUser(@Param("userIds") List<Integer> userIds);
<delete id="deleteAllUser">
        delete from user where
        <foreach collection="userIds" item="userId" separator="or" open="(" close=")">
            id=#{userId}
        </foreach>
</delete>
//另一種寫法
<delete id="deleteAllUser">
        delete from user where id in
        <foreach collection="userIds" item="userId" separator="," open="(" close=")">
            #{userId}
        </foreach>
</delete>

List<Integer> userIds = Arrays.asList(10, 11, 12);
Integer integer = mapper.deleteAllUser(userIds);

sql片段

sql片段,可以記錄一段公共sql片段,在使用的地方透過include標籤進行引入

 <sql id="userColums">
        name,age,pwd
</sql>
<select id="getAllUser" resultType="user">
        select <include refid="userColums"></include> from user where id=#{id};
</select>

快取:

官網-快取

mybatis有一級快取和二級快取,並且支援使用第三方快取,

一級快取規則:SqlSession級別的,就是透過同一個引數使用sqlsession查詢出來的資料才會放到一級快取中。

二級快取規則:SqlSessionFactory級別,透過同一個SqlSessionFactory建立的SqlSession查詢的結果會被快取;此後若再次執行相同的查詢語句,結果就會從快取中獲取。

二級快取必須在SqlSession關閉或提交之後有效,一級二級快取在中間出現增刪改mybatis都會清除快取(失效)中的資料。

查詢順序:

  1. 先查詢二級快取,因為二級快取中可能會有其他程式已經查出來的資料,可以拿來直接使用。
  2. 如果二級快取沒有命中,再查詢一級快取
  3. 如果一級快取也沒有命中,則查詢資料庫
  4. SqlSession關閉之後,一級快取中的資料會寫入二級快取

MyBatis的逆向工程

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <!--
    targetRuntime: 執行生成的逆向工程的版本
    MyBatis3Simple: 生成基本的CRUD(清新簡潔版)
    MyBatis3: 生成帶條件的CRUD(奢華尊享版)
    -->
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <!-- 資料庫的連線資訊 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://81.69.251.xx:3306/mybatis"
                        userId="mybatis"
                        password="xxxxxxx">
        </jdbcConnection>
        <!-- javaBean的生成策略-->
        <javaModelGenerator targetPackage="com.xbhog.mybatis.pojo" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!-- SQL對映檔案的生成策略 -->
        <sqlMapGenerator targetPackage="com.xbhog.mybatis.mapper"
                         targetProject=".\src\main\resources">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>
        <!-- Mapper介面的生成策略 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.xbhog.mybatis.mapper" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>
        <!-- 逆向分析的表 -->
        <!-- tableName設定為*號,可以對應所有表,此時不寫domainObjectName -->
        <!-- domainObjectName屬性指定生成出來的實體類的類名 -->
        <table tableName="t_emp" domainObjectName="Emp"/>
        <table tableName="t_dept" domainObjectName="Dept"/>
    </context>
</generatorConfiguration>

尚矽谷-mybatis

相關文章