1. 程式人生 > >mybatis教程3(映射文件)

mybatis教程3(映射文件)

解決問題 用法 mybatis教程 select value 靈活 process 復用 @param

MyBatis 的真正強大在於它的映射語句,也是它的魔力所在。由於它的異常強大,映射器的 XML 文件就顯得相對簡單。如果拿它跟具有相同功能的 JDBC 代碼進行對比,你會立即發現省掉了將近 95% 的代碼。MyBatis 就是針對 SQL 構建的,並且比普通的方法做的更好。

log4j

在程序的運行的過程中為了便於查詢sql的輸出,需要引入log4j

添加依賴

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.25</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.25</version>
</dependency>
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

添加log4j.properties文件

log4j.rootCategory=DEBUG, stdout , R
 
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n
 
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=C:\\tools\\logs\\dpb.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n

效果

技術分享圖片

#和$

由於MyBatis底層還是Jdbc,而Jdbc在操作數據庫傳遞參數時,有兩種方式,一種是使用Statement,還有一種是使用PreparedStatement:
使用statement時,存在SQL註入問題,PreparedStatement則通過預編譯解決了SQL註入問題。
在MyBatis種,引入參數有兩種方式,一種是使用#,還有一種是使用$,其中,使用#對應了Jdbc種的PreparedStatement,而使用$則對應了Jdbc種的Statement,因此在MyBatis種,推薦使用#。

## #的使用
技術分享圖片技術分享圖片技術分享圖片

## $的使用

加入可以使用$替換#,註意,如果使用$,需要在Mapper種指定參數名字

技術分享圖片技術分享圖片接口中的類型如果沒有指定@Param註解就會報錯
技術分享圖片給接口的參數前加註解描述
技術分享圖片技術分享圖片
推薦使用#方式

多個參數

如果Mapper接口中有多個參數,無論參數名是什麽,在Mapper.xml文件中,參數都是arg0、arg1....或者param1、param2....
如果非要使用自己的參數名,可以通過@Param註解自定義

<!--arg0  arg1 -->  
<insert id="addUser1" >
    insert into t_user(name,favorites)values(#{arg0},#{arg1})
</insert>
<!-- param1 param2 -->
<insert id="addUser2" parameterType="map">
    insert into t_user(name,age)values(#{param1},#{param2})
</insert>
    /**
     * 參數類型一致
     * @param name
     * @param favorites
     * @return
     */
    public int addUser1(String name,String favorites);
    
    /**
     * 參數類型不一致
     * @param name
     * @param age
     * @return
     */
    public int addUser2(String name,int age);
    
    /**
     * 參數類型不一致
     * @param name
     * @param age
     * @return
     */
    public int addUser3(@Param("name")String name,@Param("age")int age);

技術分享圖片==數據添加成功==

包裝對象

javaBean

public class UserWrapper {

    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

映射文件

<!-- 從包裝對象中獲取信息 包裝對象的別名. 取信息 -->
<insert id="addUser4" parameterType="UserWrapper">
    insert into t_user(name,age,favorites)values(#{user.name},#{user.age}
    ,#{user.favorites})
</insert>

測試技術分享圖片

技術分享圖片技術分享圖片

Map

也可以使用HashMap做參數,使用Map做參數,非常靈活,但是==不推薦==。

ResultType

對於簡單數據類型,例如查詢總記錄數、查詢某一個用戶名這一類返回值是一個基本數據類型的,直接寫Java中的基本數據類型即可。
如果返回的是一個對象或者集合,並且對象中的屬性和查詢的字段名是一一對應的,那麽resultType也可以直接寫一個對象。

ResultMap

resultMap主要用來解決屬性名和字段名不一致以及一對多、一對一查詢等問題 字段名不一致時,首先可以通過取別名解決,例如Bean的定義如下:

User對象

private int id;

// 該類型和字段不一致
private String username;

private int age;

映射文件

技術分享圖片

測試結果

技術分享圖片

解決方式一

查詢時,可以給查詢結果取別名
技術分享圖片技術分享圖片這種方式,可以解決問題,但是有缺陷,最大缺陷是不能復用(可以sql片段解決,但是不完美)。

解決方式二

最佳解決方案就是使用resultMap,用法如下:

<resultMap type="com.sxt.bean.User" id="baseMap">
    <id column="id" property="id"/>
    <result property="username" column="name"/>
    <result property="age" column="age"/>
</resultMap>
 <select id="getUserById" resultMap="baseMap"
     resultType="com.sxt.bean.User"> 
    select id ,name ,age  from t_user where id=${id}   
</select> 

使用
技術分享圖片

主鍵回寫

一般情況下,主鍵有兩種生成方式:
1.主鍵自增長
2.自定義主鍵(一般可以使用UUID)
如果是第二種,主鍵一般是在Java代碼中生成,然後傳入數據庫執行,如果是第一個主鍵自增長,此時,Java可能需要知道數據添加成功後的主鍵。
在MyBatis中,可以通過主鍵回填來解決這個問題(推薦)。

主鍵回填

<!-- 
    useGeneratedKeys:使用生成的主鍵
    keyProperty="id":將生成的主鍵的值保存到對象的id屬性中
 -->
<insert id="addEmp" parameterType="emp" 
    useGeneratedKeys="true" keyProperty="id">
    insert into t_emp(name,age)values(#{name},#{age})
</insert>

測試:
技術分享圖片

selectKey

另外,可以利用MySQL自帶的==last_insert_id()==函數查詢剛剛插入的id

<insert id="addEmp" parameterType="emp" >
    <selectKey keyProperty="id" resultType="int">
        select LAST_INSERT_ID()
    </selectKey>
    insert into t_emp(name,age)values(#{name},#{age})
</insert>

技術分享圖片

mybatis教程3(映射文件)