首頁 > 軟體

MyBatis後端對資料庫進行增刪改查等操作範例

2022-08-03 18:05:16

1.MyBatis 是什麼?

MyBatis 是⼀款優秀的持久層框架,它⽀持⾃定義 SQL、儲存過程以及⾼級對映。MyBatis 去除了很多JDBC 程式碼以及設定的引數和獲取結果集的工作。MyBatis 可以通過簡單的 XML 或註解來設定和對映原始型別、接⼝和 Java POJO (Plain Old Java Object。普通老式 Java物件)為資料庫中的記錄。

2. MyBatis 的重要性

對於後端開發來說,程式是由兩個重要部分組成的:

1.後端程式
2.資料庫

⽽這兩個重要的組成部分要通訊,就要依靠資料庫連線⼯具

1.JDBC
2. MyBatis

JDBC 的操作流程:

 

1. 建立資料庫連線池 DataSource
2. 通過 DataSource 獲取資料庫連線 Connection
3. 編寫要執⾏帶 ? 預留位置的 SQL 語句
4. 通過 Connection 及 SQL 建立操作命令物件 Statement
5. 替換預留位置:指定要替換的資料庫欄位型別,預留位置索引及要替換的值
6. 使⽤ Statement 執⾏ SQL 語句
7. 查詢操作:返回結果集 ResultSet,更新操作:返回更新的數量
8. 處理結果集
9. 釋放資源 

對於 JDBC 來說,整個操作⾮常的繁瑣,我們不但要拼接每⼀個引數,⽽且還要按照模板程式碼的⽅式,⼀步步的運算元據庫,並且在每次操作完,還要⼿動關閉連線等,⽽所有的這些操作步驟都需要在每個⽅法中重複書寫。 對於 MyBatis ,它可以幫助我們更⽅便、更快速的運算元據庫。

3. MyBatis 查詢

框架互動流程

MyBatis 也是⼀個 ORM 框架, ORM(Object Relational Mapping),即物件關係對映。在⾯向對 象程式設計語⾔中,將關係型資料庫中的資料與物件建⽴起對映關係,進⽽⾃動的完成資料與物件的互相轉換:

1. 將輸⼊資料(即傳⼊物件)+SQL 對映成原⽣ SQL
2. 將結果集對映為返回物件,即輸出物件ORM 把資料庫對映為物件:
        資料庫表(table)--> 類(class)
        記錄(record,⾏資料)--> 物件(object)
        欄位(field) --> 物件的屬性(attribute)

⼀般的 ORM 框架,會將資料庫模型的每張表都對映為⼀個 Java 類。 也就是說使⽤ MyBatis 可以像操作物件⼀樣來運算元據庫中的表,可以實現物件和資料庫表之間的轉換。

3.1 建立資料庫和表

使⽤ MyBatis 的⽅式來讀取⽤戶表中的所有⽤戶

建立使用者表

drop table if exists  userinfo;
create table userinfo(
    id int primary key auto_increment,
    username varchar(100) not null,
    password varchar(32) not null,
    photo varchar(500) default '',
    createtime datetime default now(),
    updatetime datetime default now(),
    `state` int default 1
) default charset 'utf8mb4';

3.2 新增MyBatis框架⽀持

3.2.1 新專案新增MyBatis

在建立新專案時,來到這一步,只需將下面的勾選即可

3.2.1 老項⽬新增 MyBatis

在 pom.xml 檔案頁面 滑鼠右鍵進行下面操作

3.3 設定連線字串和MyBatis

3.3.1 設定連線字串

將當前執行環境選擇開發環境的設定

application-dev.yml

#開發環境
#設定資料庫連線
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/myblog?characterEncoding=utf8
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
 
# 開啟 MyBatis SQL 列印
logging:
  level:
    com:
      example:
        demo: debug
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

application.yml

選擇開發環境

spring:
  profiles:
    active: dev

3.3.2 設定mybatis 中的 xml 儲存路徑

MyBatis 的 XML 中儲存是查詢資料庫的具體操作 SQL,設定在 application.yml  中

#設定mybatis xml 儲存路徑
mybatis:
  mapper-locations: classpsth:mybatis/**Mapper.xml

3.4 新增後端程式碼

下⾯按照後端開發的⼯程思路,也就是下⾯的流程來實現 MyBatis 查詢所有⽤戶的功能

目錄結構:

3.4.1 新增實體類

先新增使用者實體類

/**
 * 普通使用者實體類
 */
@Data
public class UserInfo {
    private Integer id;
    private String name;
    private String password;
    private String photo;
    private String createtime;
    private String updatetime;
    private int state;
}

3.4.2 新增 mapper 介面

資料持久層的介面定義:

/**
 * 實現資料庫對映
 */
 
@Mapper
public interface UserMapper {
    //查詢使用者 ID
    public UserInfo getUserById(@Param("id") Integer id);
}

3.4.3 新增UserMapper.xml

資料持久層的實現,mybatis 的固定 xml 格式

<?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 namespace="com.example.demo.mapper.UserMapper">
   
 
</mapper>

UserMapper.xml 查詢所有⽤戶的具體實現 SQL:

<?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 namespace="com.example.demo.mapper.UserMapper">
    <resultMap id="BaseMap" type="com.example.demo.model.UserInfo">
    <!-- 主鍵對映 -->
    <id column="id" property="id"></id>
    <!-- 普通屬性對映 -->
    <result column="username" property="name"></result>
    </resultMap>
 
    <!-- 根據 id 查詢使用者 -->
    <select id="getUserById" resultMap="BaseMap">
        select * from userinfo where id=${id}
    </select>
 
</mapper>

標籤說明:

<mapper>標籤:需要指定 namespace 屬性,表示名稱空間,值為 mapper 接⼝的全限定名,包括全包名.類名。

<select>查詢標籤:是⽤來執⾏資料庫的查詢操作的:

  • id:是和 Interface(接⼝)中定義的⽅法名稱⼀樣的,表示對接⼝的具體實現⽅法。
  • resultType:是返回的資料型別,也就是開頭我們定義的實體類

3.4.4 新增Service 

決定呼叫哪個mapper

@Service
public class UserService {
 
    @Resource
    private UserMapper userMapper;
 
    public UserInfo getUserById(Integer id) {
        return userMapper.getUserById(id);
    }
 
}

3.4.5 新增 Controller

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
 
    @Autowired
    private UserService userService;
 
    @RequestMapping("/getuserbyid")
    public UserInfo getUserById(Integer id) {
        if (id == null) return null;
        return userService.getUserById(id);
    }
 
}

以上程式碼寫完,整個 MyBatis 的查詢功能就實現完了

4.增刪改操作

4.1 修改使用者操作

在 UserMapper 中增加修改的程式碼

    //修改方法根據 ID 修改名稱
    public int update(@Param("id") Integer id,
                      @Param("name") String username);

UserMapper.xml 中增加介面的實現標籤和具體的執行SQL

    <update id="update" >
        update userinfo set username=#{name} where id=#{id}
    </update>

通過單元測試,實現成功

   @Test
    void update() {
        int result = userMapper.update(2,"fei");
        Assertions.assertEquals(1,result);
    }

查詢SQL語句可知,已經修改了

如果僅僅是為了測試功能是否實現,而不修改資料庫中的內容,可以加入註解 @Transactional

    @Test
    @Transactional // 新增此註解後,執行完單元測試,不會修改資料庫中的內容,即事務回滾
    void update() {
        int result = userMapper.update(2,"fei");
        Assertions.assertEquals(1,result);
    }

4.2 刪除使用者操作

在 UserMapper 中增加刪除的程式碼

    //刪除方法
    public int del(@Param("id") Integer id);

UserMapper.xml 中增加介面的實現標籤和具體的執行SQL

    <!--刪除操作-->
    <delete id="del">
        delete from userinfo where id=#{id};
    </delete>

單元測試

    @Test
    @Transactional
    void del() {
        int result = userMapper.del(2);
        System.out.println("刪除行數: " + result);
        Assertions.assertEquals(1,result);
    }

4.3 增加使用者操作

在 UserMapper 中新增增加的程式碼

    //增加使用者方法
    // 傳過來的是物件而不是某個成員變數
    public int add(UserInfo userInfo);

 UserMapper.xml 中增加介面的實現標籤和具體的執行SQL

    <!--增加操作,返回受影響的行數-->
    <insert id="add">
        insert into userinfo(username,password,photo)
        values(#{username}, #{password}, #{photo}); <!--和物件裡面的屬性一一對應-->
    </insert>

單元測試

    @Test
    //@Transactional
    void add() {
        UserInfo userInfo = new UserInfo();
        userInfo.setName("y");
        userInfo.setPassword("123");
        userInfo.setPhoto("");
        System.out.println("新增之前的 id: " + userInfo.getId());
        int result = userMapper.add(userInfo);
        System.out.println("新增之後的 id: " + userInfo.getId());
        System.out.println("新增的行數: " + result);
        Assertions.assertEquals(1,result);
    }

4.4 增加使用者並有自增ID

在 UserMapper 中新增增加的程式碼

     //新增使用者,返回自增ID
    public int addGetId(UserInfo userInfo);

  UserMapper.xml 中增加介面的實現標籤和具體的執行SQL

    <!--增加操作,返回受影響的行數和自增ID-->
    <insert id="addGetId" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
        insert into userinfo(username,password,photo)
        values(#{name}, #{password}, #{photo}); <!--和物件裡面的屬性一一對應-->
    </insert>

 單元測試

    @Test
    //@Transactional
    void addGetId() {
        UserInfo userInfo = new UserInfo();
        userInfo.setName("yang");
        userInfo.setPassword("123");
        userInfo.setPhoto("");
        System.out.println("新增之前的 id: " + userInfo.getId());
        int result = userMapper.addGetId(userInfo);
        System.out.println("新增之後的 id: " + userInfo.getId());
        System.out.println("新增的行數: " + result);
        Assertions.assertEquals(1,result);
    }

5. 引數預留位置 #{} 和 ${} 

#{}:預編譯處理 。處理時,成一個 問號? ,賦值時會加上 單引號 ‘ ’

${}:字元直接替換

區別:

1.定義不同
預編譯處理是指:MyBatis 在處理#{}時,會將 SQL 中的 #{} 替換為?號,使⽤ PreparedStatement 的set ⽅法來賦值。
直接替換:是MyBatis 在處理 ${} 時,就是把 ${} 替換成變數的值。
2.使用不同:#{} 適用於所有型別的引數匹配,但${} 只適用於數值型別
3.安全性不同:#{} 效能高,並且沒有安全問題;但 ${} 存在SQL隱碼攻擊的安全問題

#{}:預編譯處理 預留位置,當成 value 值來使用, 即加上 ‘ ’

    <select id="gerUserFullById" resultType="com.example.demo.model.UserInfo">
        select * from userinfo where username=#{name}
    </select>
    @Test
    void gerUserFullById() {
        UserInfo userInfo = userMapper.gerUserFullById("fei");
        System.out.println("userInfo: " + userInfo);
    }

 ${}:字元直接替換

不加任何符合,直接替換上去,連成一個SQL 命令

    <select id="gerUserFullById" resultType="com.example.demo.model.UserInfo">
        select * from userinfo where username=${name}
    </select>

單元測試結果 

5.1 desc 降序排序

//對使用者進行排序
    public List<UserInfo> getOrderList(@Param("order") String order);

 此處使用的是 ${}, 如果使用 #{} 的話,會編譯出錯,因為它會把 desc 當成 ‘desc’ 一個value 值來使用,不構成一個 SQL命令語句

    <select id="getOrderList" resultType="com.example.demo.model.UserInfo">
        select * from userinfo order by createtime ${order}
    </select>

單元測試 

    @Test
    void getOrderList() {
        List<UserInfo> list = userMapper.getOrderList("desc");
        log.info("列表: " + list);
    }

5.2 登入(SQL隱碼攻擊)

    //登入功能
    public UserInfo login(@Param("name") String username,
                          @Param("password") String password);

1) 在使用${} 時,需要加單引號,因為是直接替換

    <select id="login" resultType="com.example.demo.model.UserInfo">
        select * from userinfo where username='${name}' and password='${password}';
    </select>

單元測試

    @Test
    void login() {
        String username = "Fly";
        String password = "";
        UserInfo userInfo = userMapper.login(username,password);
        log.info("使用者資訊: " + userInfo);
 
    }

使用 " 'or 1=' 1" 時,SQL隱碼攻擊,密碼會洩露,如下,因此在登入時應使用#{}

    @Test
    void login() {
        String username = "Fly";
        //String password = "";
        String password = "'or 1='1";
        UserInfo userInfo = userMapper.login(username,password);
        log.info("使用者資訊: " + userInfo);
 
    }

2)#{} 預編譯處理,不會出現密碼洩露

    <!--登入功能-->
    <select id="login" resultType="com.example.demo.model.UserInfo">
        <!--select * from userinfo where username='${name}' and password='${password}'; -->
        select * from userinfo where username=#{name} and password=#{password};
    </select>

5.3 like 查詢

    //like 模糊查詢
    public List<UserInfo> getUserByName(@Param("name") String username);

1)直接使用 #{} 會報錯

因為賦值時會加上單引號 ‘’

select * from userinfo where username like '%#{name}%'

就相當於下面的語句,不符合查詢條件

select * from userinfo where username like '%'name'%'

2)使用${} 是不會報錯,但在業務層的值不能窮舉

3)#{} 在like中的正確用法,加上contat 拼接,演示如下

 正確用法

因為#{} 在賦值的時候,會帶上單引號‘’ ,所以下面的#{}不需要帶單引號

    <!--like 模糊查詢-->
    <select id="getUserByName" resultType="com.example.demo.model.UserInfo">
        <!-- select * from userinfo where username like '%#{name}%'-->
        select * from userinfo where username like concat('%',#{name},'%')
    </select>

單元測試 

    @Test
    void getUserByName() {
        String username = "l";
        List<UserInfo> list= userMapper.getUserByName(username);
        log.info("使用者列表: " + list);
    }

6.多表查詢

6.1 返回型別:resultType

絕大數查詢場景可以使用 resultType 進行返回,如下

    <!-- 根據 id 查詢使用者 -->
    <select id="getUserById" resultType="com.example.demo.model.UserInfo">
        select * from userinfo where id=${id}
    </select>

它的優點是使⽤⽅便,直接定義到某個實體類即可 6.2 返回字典對映:resultMap 使用場景:

欄位名稱和程式中的屬性名不同的情況, 可使⽤ resultMap 設定對映; 一對一和一對多關係可以使用  resultMap 對映並查詢資料

1)欄位名程式中的屬性名不一致

 userMapper.xml 程式碼如下

    <!-- 根據 id 查詢使用者 -->
    <select id="getUserById" resultType="com.example.demo.model.UserInfo">
        select * from userinfo where id=${id}
    </select>

 查詢結果

這個時候就可以使⽤ resultMap 了,resultMap 的使⽤如下

 userMapper.xml 程式碼如下

    <resultMap id="BaseMap" type="com.example.demo.model.UserInfo">
        <!--主鍵對映-->
        <id column="id" property="id"></id>
        <!--普通屬性對映-->
        <result column="username" property="name"></result>
        <result column="password" property="password"></result>
        <result column="photo" property="photo"></result>
        <result column="createtime" property="createtime"></result>
        <result column="updatetime" property="updatetime"></result>
 
    </resultMap>
 
    <!-- 根據 id 查詢使用者 -->
    <select id="getUserById" resultMap="BaseMap">
        select * from userinfo where id=${id}
    </select>

單元測試

    @Test
    void getUserById() {
       UserInfo userInfo = userMapper.getUserById(1);
        //Assertions.assertNotNull(userInfo);
        log.info("查詢行數:" + userInfo);
    }

查詢結果

6.3 一對一表查詢

 建立文章實體類  ArticleInfo

@Data
public class ArticleInfo {
    private int id;
    private String title;
    private String content;
    private String createtime;
    private String updatetime;
    private int uid;
    private int rcount;
    private int state;
    private UserInfo userInfo;
}

mapper 實現資料庫對映 ArticleMapper

@Mapper
public interface ArticleMapper {
    //根據文章 id 獲取文章
    public ArticleInfo getArticleById(@Param("id") Integer id); //文章id
}

資料庫命令,資料持久層的實現, ArticleMapper.xml

<mapper namespace="com.example.demo.mapper.ArticleMapper">
    <resultMap id="BaseMap" type="com.example.demo.model.ArticleInfo">
        <!--主鍵對映-->
        <id column="id" property="id"></id>
        <!--普通屬性對映-->
        <result column="title" property="title"></result>
        <result column="content" property="content"></result>
        <result column="createtime" property="createtime"></result>
        <result column="uid" property="uid"></result>
        <result column="rcount" property="rcount"></result>
        <result column="state" property="state"></result>
        <association property="userInfo"
                     resultMap="com.example.demo.mapper.UserMapper.BaseMap"
                     columnPrefix="u_"></association>
    </resultMap>
 
    <select id="getArticleById" resultMap="BaseMap">
       select a.*,u.* from articleinfo a left join userinfo u on a.uid=u.id
    </select>
</mapper>

以上使⽤ <association>標籤,表示⼀對⼀的結果對映:

              property 屬性:指定 Article 中對應的屬性,即⽤戶。

              resultMap 屬性:指定關聯的結果集對映,將基於該對映設定來組織⽤戶資料。

              columnPrefix 屬性:繫結⼀對⼀物件時,因為對應的是使用者表 ,所以是“u-”是通過                                          columnPrefix+association.resultMap.column 來對映結果集欄位。 association.resultMap.column是指 <association>標籤中 resultMap屬性,對應的結果集對映中,column欄位

單元測試

    //將類屬性注入
    @Resource
    private ArticleMapper articleMapper;
 
    @Test
    void getArticleById() {
        ArticleInfo articleInfo = articleMapper.getArticleById(1);
        log.info("查詢結果:" + articleInfo  );
    }

查詢結果

6.4 一對多

 一個使用者對應多篇文章

實體類

@Data
public class UserInfo {
    private Integer id;
    //private String username;//用於resultType
    private String name; //用於 resultMap
    private String password;
    private String photo;
    private String createtime;
    private String updatetime;
    private int state;
    //一對多
    private List<ArticleInfo> artlist;
}

mapper

   //一對多,多表查詢
    //根據使用者 id 查詢使用者及使用者發表的所有文章
    public UserInfo getUserAndArticleByUid(@Param("uid") Integer uid);

XML

<resultMap id="BaseMap" type="com.example.demo.model.UserInfo">
        <!--主鍵對映-->
        <id column="id" property="id"></id>
        <!--普通屬性對映-->
        <result column="username" property="name"></result>
        <result column="password" property="password"></result>
        <result column="photo" property="photo"></result>
        <result column="createtime" property="createtime"></result>
        <result column="updatetime" property="updatetime"></result>
        <result column="state" property="state"></result>
        <!--多表查詢-->
        <collection property="artlist"
                    resultMap="com.example.demo.mapper.ArticleMapper.BaseMap"
                    columnPrefix="a_">
        </collection>
    </resultMap>
 
    <!--多表查詢-->
    <select id="getUserAndArticleByUid" resultMap="BaseMap">
 
        select u.*,a.id a_id,a.title a_title,a.content a_content,
        a.createtime a_createtime,
        a.updatetime a_updatetime from userinfo u left join articleinfo a
        on u.id=a.uid where u.id=#{uid}
 
    </select>

單元測試

   @Test
    void getUserAndArticleByUid() {
        UserInfo userInfo = userMapper.getUserAndArticleByUid(1);
        log.info("使用者詳情:" + userInfo);
    }

7.動態SQL使用

動態SQL是mybatis 的強大特性之一,能夠完成不同條件的SQL拼接

7.1 <if> 標籤

在填寫個人資訊時,會經常遇到一些必填項,一些非必填項,如下

註冊分為兩種欄位:必填欄位和⾮必填欄位,那如果在新增⽤戶的時候有不確定的欄位傳⼊,程式應該如何實現呢? 這個時候就需要使⽤動態標籤 <if> 來判斷了:

判斷一個引數是否有值,如果沒值,就會隱藏 if 中的SQL

 

 現在有一張使用者表

在新增使用者的時候,將 photo 設為非比傳引數

1)傳入photo 時

 mapper

    //動態SQL,新增使用者,photo為非必傳引數
    public int add2(UserInfo userInfo);

UserMapper.xml

    <!--動態SQL,新增使用者-->
    <insert id="add2">
        insert into userinfo(username,password
        <if test="photo !=null">
            ,photo
        </if>
        ) values(#{name}, #{password}
        <if test="photo !=null">
            , #{photo}
        </if>
        )
    </insert>

注意 test 中的 photo 和 #{},是傳⼊物件中的屬性,不是資料庫欄位 

單元測試

    @Test
    void add2() {
        UserInfo userInfo = new UserInfo();
        userInfo.setName("楊通");
        userInfo.setPassword("123");
        userInfo.setPhoto("123.jpg");
        int result = userMapper.add2(userInfo);
        log.info("新增使用者:" + result);
        
    }

新增結果

 2)不傳入 photo 時

不用像沒使用動態SQL時,將 userInfo.setPhoto(""); 設為空,直接忽略不寫就行了

    @Test
    void add2() {
        UserInfo userInfo = new UserInfo();
        userInfo.setName("黃空");
        userInfo.setPassword("123");
        //userInfo.setPhoto("123.jpg");
        int result = userMapper.add2(userInfo);
        log.info("新增使用者:" + result);
 
    }

 動態SQL直接忽略photo,新增成功

7.2 <trim> 標籤

最主要的作用:去除SQL語句前後多餘的某個字元

語法:

<trim>標籤中有如下屬性:

prefix: 表示這個語句快,以prefix的值作為字首
suffix:表示整個語句塊,以suffix的值作為字尾
prefixOverrides:表示整個語句塊要去除掉的字首
suffixOverrides:表示整個語句塊要去除掉的字尾

 UserMapper

    //動態SQL, <trim> 標籤。新增使用者,photo為非必傳引數
    public int add3(UserInfo userInfo);

UserMapper.xml

    <!--動態SQL,<trim> 標籤。新增使用者-->
    <insert id="add3">
        insert into userinfo
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="name != null">
                <!--這裡拼接的是資料庫中的欄位-->
                username,
            </if>
            <if test="password != null">
                password,
            </if>
            <if test="photo != null">
                photo
            </if>
        </trim>
        values
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="name != null">
                #{name},
            </if>
            <if test="password != null">
                #{password},
            </if>
            <if test="photo != null">
                #{photo}
            </if>
        </trim>
    </insert>

單元測試

 這裡不傳photo,看拼接的欄位前的一個逗號是否還在

    @Test
    void add3() {
        UserInfo userInfo = new UserInfo();
        userInfo.setName("黃小小");
        userInfo.setPassword("123");
        //userInfo.setPhoto("123.jpg"); 這裡不傳,看拼接的欄位前的一個逗號是否還在
        int result = userMapper.add2(userInfo);
        log.info("新增使用者:" + result);
    }

7.3 <where> 標籤

 主要作用:實現查詢中的 where SQL替換,它可以實現如果沒有任何的查詢條件,那麼他可以因此查詢中的 where SQL ,但如果存在查詢中條件,那麼會生成where的 SQL查詢,並且使用 where 標籤可以自動的去除最後一個 and字元。

1)SQL 替換

根據 id 查詢使用者:

    <!-- 根據 id 查詢使用者 -->
    <select id="getUserById" resultMap="BaseMap">
        select * from userinfo
        <where>
            <if test="id != null">
                id=#{id}
            </if>
 
        </where>
    </select>

 當傳入的 id 為 null 時

  @Test
    void getUserById() {
       UserInfo userInfo = userMapper.getUserById(null);
        //Assertions.assertNotNull(userInfo);
        log.info("查詢行數:" + userInfo);
    }

 2)去除 and

或者通過 id 或者 username 來查詢時,如果username 為空就會去掉

7.4 <set> 標籤

作用:進行修改操作是,配合 if 來處理非必傳欄位,他的特點是主動去除最後一個英文逗號

語法:

update table_name
  <set>
    <if test="xxx">
        ...
    </if>
    ...
  </set>
  where ...

1)修改使用者名稱

 UserMapper

    //動態SQL, <set> 標籤。修改使用者
    public int update2(UserInfo userInfo);

UserMapper.xml

    <update id="update2">
        update userinfo
        <set>
            <if test="name != null">
                username=#{name},
            </if>
            <if test="password != null">
                password = #{password},
            </if>
            <if test="photo != null">
                photo = #{photo}
            </if>
        </set>
    </update>

單元測試

    @Test
    void update2() {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(1); //查詢 id 為 1 的使用者
        userInfo.setName("fei"); // 將使用者名稱修改為 fei
        int result = userMapper.update2(userInfo);
        log.info("修改結果: " + result);
    }

7.5 <foreach> 標籤

對集合進⾏遍歷時可以使⽤該標籤。<foreach>標籤有如下屬性:

collection: 繫結方法引數中的集合,如List 、Set、Map或陣列物件
item: 遍歷時的每一個物件
open:語句塊開頭的字串
close:語句塊結束的字串
separator:每次遍歷之間間隔的字串

範例:根據使用者 id 來對使用者進行刪除

 UserMapper

    //動態SQL,<foreach>,刪除多個使用者
    public int delId(List<Integer> ids);

 UserMapper.xml

    <!--動態SQL,刪除多個使用者-->
    <delete id="delId">
        delete from userinfo where id in
        <foreach collection="ids" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </delete>

單元測試

    @Test
    void delId() {
        List<Integer> list = new ArrayList<>();
        list.add(2);
        list.add(3);
        list.add(4);
        int result = userMapper.delId(list);
        log.info("刪除的行數:" + result);
    }

結果

總結

到此這篇關於MyBatis後端對資料庫進行增刪改查等操作的文章就介紹到這了,更多相關MyBatis後端對資料庫操作內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com