欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MyBatis后端對(duì)數(shù)據(jù)庫(kù)進(jìn)行增刪改查等操作實(shí)例

 更新時(shí)間:2022年08月03日 15:10:31   作者:Fly?upward  
Mybatis是appach下開(kāi)源的一款持久層框架,通過(guò)xml與java文件的緊密配合,避免了JDBC所帶來(lái)的一系列問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于MyBatis后端對(duì)數(shù)據(jù)庫(kù)進(jìn)行增刪改查等操作的相關(guān)資料,需要的朋友可以參考下

1.MyBatis 是什么?

MyBatis 是?款優(yōu)秀的持久層框架,它?持?定義 SQL、存儲(chǔ)過(guò)程以及?級(jí)映射。MyBatis 去除了很多JDBC 代碼以及設(shè)置的參數(shù)和獲取結(jié)果集的工作。MyBatis 可以通過(guò)簡(jiǎn)單的 XML 或注解來(lái)配置和映射原始類型、接?和 Java POJO (Plain Old Java Object。普通老式 Java對(duì)象)為數(shù)據(jù)庫(kù)中的記錄。

2. MyBatis 的重要性

對(duì)于后端開(kāi)發(fā)來(lái)說(shuō),程序是由兩個(gè)重要部分組成的:

1.后端程序
2.數(shù)據(jù)庫(kù)

?這兩個(gè)重要的組成部分要通訊,就要依靠數(shù)據(jù)庫(kù)連接?具

1.JDBC
2. MyBatis

JDBC 的操作流程:

 

1. 創(chuàng)建數(shù)據(jù)庫(kù)連接池 DataSource
2. 通過(guò) DataSource 獲取數(shù)據(jù)庫(kù)連接 Connection
3. 編寫(xiě)要執(zhí)?帶 ? 占位符的 SQL 語(yǔ)句
4. 通過(guò) Connection 及 SQL 創(chuàng)建操作命令對(duì)象 Statement
5. 替換占位符:指定要替換的數(shù)據(jù)庫(kù)字段類型,占位符索引及要替換的值
6. 使? Statement 執(zhí)? SQL 語(yǔ)句
7. 查詢操作:返回結(jié)果集 ResultSet,更新操作:返回更新的數(shù)量
8. 處理結(jié)果集
9. 釋放資源 

對(duì)于 JDBC 來(lái)說(shuō),整個(gè)操作?常的繁瑣,我們不但要拼接每?個(gè)參數(shù),?且還要按照模板代碼的?式,?步步的操作數(shù)據(jù)庫(kù),并且在每次操作完,還要?動(dòng)關(guān)閉連接等,?所有的這些操作步驟都需要在每個(gè)?法中重復(fù)書(shū)寫(xiě)。 對(duì)于 MyBatis ,它可以幫助我們更?便、更快速的操作數(shù)據(jù)庫(kù)。

3. MyBatis 查詢

框架交互流程

MyBatis 也是?個(gè) ORM 框架, ORM(Object Relational Mapping),即對(duì)象關(guān)系映射。在?向?qū)?象編程語(yǔ)?中,將關(guān)系型數(shù)據(jù)庫(kù)中的數(shù)據(jù)與對(duì)象建?起映射關(guān)系,進(jìn)??動(dòng)的完成數(shù)據(jù)與對(duì)象的互相轉(zhuǎn)換:

1. 將輸?數(shù)據(jù)(即傳?對(duì)象)+SQL 映射成原? SQL
2. 將結(jié)果集映射為返回對(duì)象,即輸出對(duì)象ORM 把數(shù)據(jù)庫(kù)映射為對(duì)象:
        數(shù)據(jù)庫(kù)表(table)--> 類(class)
        記錄(record,?數(shù)據(jù))--> 對(duì)象(object)
        字段(field) --> 對(duì)象的屬性(attribute)

?般的 ORM 框架,會(huì)將數(shù)據(jù)庫(kù)模型的每張表都映射為?個(gè) Java 類。 也就是說(shuō)使? MyBatis 可以像操作對(duì)象?樣來(lái)操作數(shù)據(jù)庫(kù)中的表,可以實(shí)現(xiàn)對(duì)象和數(shù)據(jù)庫(kù)表之間的轉(zhuǎn)換。

3.1 創(chuàng)建數(shù)據(jù)庫(kù)和表

使? MyBatis 的?式來(lái)讀取?戶表中的所有?戶

創(chuàng)建用戶表

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 新項(xiàng)目添加MyBatis

在創(chuàng)建新項(xiàng)目時(shí),來(lái)到這一步,只需將下面的勾選即可

3.2.1 老項(xiàng)?添加 MyBatis

在 pom.xml 文件頁(yè)面 鼠標(biāo)右鍵進(jìn)行下面操作

3.3 配置連接字符串和MyBatis

3.3.1 配置連接字符串

將當(dāng)前運(yùn)行環(huán)境選擇開(kāi)發(fā)環(huán)境的配置

application-dev.yml

#開(kāi)發(fā)環(huán)境
#配置數(shù)據(jù)庫(kù)連接
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
 
# 開(kāi)啟 MyBatis SQL 打印
logging:
  level:
    com:
      example:
        demo: debug
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

application.yml

選擇開(kāi)發(fā)環(huán)境

spring:
  profiles:
    active: dev

3.3.2 配置mybatis 中的 xml 保存路徑

MyBatis 的 XML 中保存是查詢數(shù)據(jù)庫(kù)的具體操作 SQL,配置在 application.yml  中

#配置mybatis xml 保存路徑
mybatis:
  mapper-locations: classpsth:mybatis/**Mapper.xml

3.4 添加后端代碼

下?按照后端開(kāi)發(fā)的?程思路,也就是下?的流程來(lái)實(shí)現(xiàn) MyBatis 查詢所有?戶的功能

目錄結(jié)構(gòu):

3.4.1 添加實(shí)體類

先添加用戶實(shí)體類

/**
 * 普通用戶實(shí)體類
 */
@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 接口

數(shù)據(jù)持久層的接口定義:

/**
 * 實(shí)現(xiàn)數(shù)據(jù)庫(kù)映射
 */
 
@Mapper
public interface UserMapper {
    //查詢用戶 ID
    public UserInfo getUserById(@Param("id") Integer id);
}

3.4.3 添加UserMapper.xml

數(shù)據(jù)持久層的實(shí)現(xiàn),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 要設(shè)置是實(shí)現(xiàn)接口的具體包名加類名 -->
<mapper namespace="com.example.demo.mapper.UserMapper">
   
 
</mapper>

UserMapper.xml 查詢所有?戶的具體實(shí)現(xiàn) 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 要設(shè)置是實(shí)現(xiàn)接口的具體包名加類名 -->
<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>
 
    <!-- 根據(jù) id 查詢用戶 -->
    <select id="getUserById" resultMap="BaseMap">
        select * from userinfo where id=${id}
    </select>
 
</mapper>

標(biāo)簽說(shuō)明:

<mapper>標(biāo)簽:需要指定 namespace 屬性,表示命名空間,值為 mapper 接?的全限定名,包括全包名.類名。

<select>查詢標(biāo)簽:是?來(lái)執(zhí)?數(shù)據(jù)庫(kù)的查詢操作的:

  • id:是和 Interface(接?)中定義的?法名稱?樣的,表示對(duì)接?的具體實(shí)現(xiàn)?法。
  • resultType:是返回的數(shù)據(jù)類型,也就是開(kāi)頭我們定義的實(shí)體類

3.4.4 添加Service 

決定調(diào)用哪個(gè)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);
    }
 
}

以上代碼寫(xiě)完,整個(gè) MyBatis 的查詢功能就實(shí)現(xiàn)完了

4.增刪改操作

4.1 修改用戶操作

在 UserMapper 中增加修改的代碼

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

UserMapper.xml 中增加接口的實(shí)現(xiàn)標(biāo)簽和具體的執(zhí)行SQL

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

通過(guò)單元測(cè)試,實(shí)現(xiàn)成功

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

查詢SQL語(yǔ)句可知,已經(jīng)修改了

如果僅僅是為了測(cè)試功能是否實(shí)現(xiàn),而不修改數(shù)據(jù)庫(kù)中的內(nèi)容,可以加入注解 @Transactional

    @Test
    @Transactional // 添加此注解后,執(zhí)行完單元測(cè)試,不會(huì)修改數(shù)據(jù)庫(kù)中的內(nèi)容,即事務(wù)回滾
    void update() {
        int result = userMapper.update(2,"fei");
        Assertions.assertEquals(1,result);
    }

4.2 刪除用戶操作

在 UserMapper 中增加刪除的代碼

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

UserMapper.xml 中增加接口的實(shí)現(xiàn)標(biāo)簽和具體的執(zhí)行SQL

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

單元測(cè)試

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

4.3 增加用戶操作

在 UserMapper 中添加增加的代碼

    //增加用戶方法
    // 傳過(guò)來(lái)的是對(duì)象而不是某個(gè)成員變量
    public int add(UserInfo userInfo);

 UserMapper.xml 中增加接口的實(shí)現(xiàn)標(biāo)簽和具體的執(zhí)行SQL

    <!--增加操作,返回受影響的行數(shù)-->
    <insert id="add">
        insert into userinfo(username,password,photo)
        values(#{username}, #{password}, #{photo}); <!--和對(duì)象里面的屬性一一對(duì)應(yīng)-->
    </insert>

單元測(cè)試

    @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("添加的行數(shù): " + result);
        Assertions.assertEquals(1,result);
    }

4.4 增加用戶并有自增ID

在 UserMapper 中添加增加的代碼

     //添加用戶,返回自增ID
    public int addGetId(UserInfo userInfo);

  UserMapper.xml 中增加接口的實(shí)現(xiàn)標(biāo)簽和具體的執(zhí)行SQL

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

 單元測(cè)試

    @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("添加的行數(shù): " + result);
        Assertions.assertEquals(1,result);
    }

5. 參數(shù)占位符 #{} 和 ${} 

#{}:預(yù)編譯處理 。處理時(shí),成一個(gè) 問(wèn)號(hào)? ,賦值時(shí)會(huì)加上 單引號(hào) ‘ ’

${}:字符直接替換

區(qū)別:

1.定義不同
預(yù)編譯處理是指:MyBatis 在處理#{}時(shí),會(huì)將 SQL 中的 #{} 替換為?號(hào),使? PreparedStatement 的set ?法來(lái)賦值。
直接替換:是MyBatis 在處理 ${} 時(shí),就是把 ${} 替換成變量的值。
2.使用不同:#{} 適用于所有類型的參數(shù)匹配,但${} 只適用于數(shù)值類型
3.安全性不同:#{} 性能高,并且沒(méi)有安全問(wèn)題;但 ${} 存在SQL注入的安全問(wèn)題

#{}:預(yù)編譯處理 占位符,當(dāng)成 value 值來(lái)使用, 即加上 ‘ ’

    <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);
    }

 ${}:字符直接替換

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

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

單元測(cè)試結(jié)果 

5.1 desc 降序排序

//對(duì)用戶進(jìn)行排序
    public List<UserInfo> getOrderList(@Param("order") String order);

 此處使用的是 ${}, 如果使用 #{} 的話,會(huì)編譯出錯(cuò),因?yàn)樗鼤?huì)把 desc 當(dāng)成 ‘desc’ 一個(gè)value 值來(lái)使用,不構(gòu)成一個(gè) SQL命令語(yǔ)句

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

單元測(cè)試 

    @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) 在使用${} 時(shí),需要加單引號(hào),因?yàn)槭侵苯犹鎿Q

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

單元測(cè)試

    @Test
    void login() {
        String username = "Fly";
        String password = "";
        UserInfo userInfo = userMapper.login(username,password);
        log.info("用戶信息: " + userInfo);
 
    }

使用 " 'or 1=' 1" 時(shí),SQL注入,密碼會(huì)泄露,如下,因此在登錄時(shí)應(yīng)使用#{}

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

2)#{} 預(yù)編譯處理,不會(huì)出現(xiàn)密碼泄露

    <!--登錄功能-->
    <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)直接使用 #{} 會(huì)報(bào)錯(cuò)

因?yàn)橘x值時(shí)會(huì)加上單引號(hào) ‘’

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

就相當(dāng)于下面的語(yǔ)句,不符合查詢條件

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

2)使用${} 是不會(huì)報(bào)錯(cuò),但在業(yè)務(wù)層的值不能窮舉

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

 正確用法

因?yàn)?{} 在賦值的時(shí)候,會(huì)帶上單引號(hào)‘’ ,所以下面的#{}不需要帶單引號(hào)

    <!--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>

單元測(cè)試 

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

6.多表查詢

6.1 返回類型:resultType

絕大數(shù)查詢場(chǎng)景可以使用 resultType 進(jìn)行返回,如下

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

它的優(yōu)點(diǎn)是使??便,直接定義到某個(gè)實(shí)體類即可 6.2 返回字典映射:resultMap 使用場(chǎng)景:

字段名稱和程序中的屬性名不同的情況, 可使? resultMap 配置映射; 一對(duì)一和一對(duì)多關(guān)系可以使用  resultMap 映射并查詢數(shù)據(jù)

1)字段名程序中的屬性名不一致

 userMapper.xml 代碼如下

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

 查詢結(jié)果

這個(gè)時(shí)候就可以使? 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>
 
    <!-- 根據(jù) id 查詢用戶 -->
    <select id="getUserById" resultMap="BaseMap">
        select * from userinfo where id=${id}
    </select>

單元測(cè)試

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

查詢結(jié)果

6.3 一對(duì)一表查詢

 創(chuàng)建文章實(shí)體類  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 實(shí)現(xiàn)數(shù)據(jù)庫(kù)映射 ArticleMapper

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

數(shù)據(jù)庫(kù)命令,數(shù)據(jù)持久層的實(shí)現(xiàn), 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>標(biāo)簽,表示?對(duì)?的結(jié)果映射:

              property 屬性:指定 Article 中對(duì)應(yīng)的屬性,即?戶。

              resultMap 屬性:指定關(guān)聯(lián)的結(jié)果集映射,將基于該映射配置來(lái)組織?戶數(shù)據(jù)。

              columnPrefix 屬性:綁定?對(duì)?對(duì)象時(shí),因?yàn)閷?duì)應(yīng)的是用戶表 ,所以是“u-”是通過(guò)                                          columnPrefix+association.resultMap.column 來(lái)映射結(jié)果集字段。 association.resultMap.column是指 <association>標(biāo)簽中 resultMap屬性,對(duì)應(yīng)的結(jié)果集映射中,column字段

單元測(cè)試

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

查詢結(jié)果

6.4 一對(duì)多

 一個(gè)用戶對(duì)應(yīng)多篇文章

實(shí)體類

@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;
    //一對(duì)多
    private List<ArticleInfo> artlist;
}

mapper

   //一對(duì)多,多表查詢
    //根據(jù)用戶 id 查詢用戶及用戶發(fā)表的所有文章
    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>

單元測(cè)試

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

7.動(dòng)態(tài)SQL使用

動(dòng)態(tài)SQL是mybatis 的強(qiáng)大特性之一,能夠完成不同條件的SQL拼接

7.1 <if> 標(biāo)簽

在填寫(xiě)個(gè)人信息時(shí),會(huì)經(jīng)常遇到一些必填項(xiàng),一些非必填項(xiàng),如下

注冊(cè)分為兩種字段:必填字段和?必填字段,那如果在添加?戶的時(shí)候有不確定的字段傳?,程序應(yīng)該如何實(shí)現(xiàn)呢? 這個(gè)時(shí)候就需要使?動(dòng)態(tài)標(biāo)簽 <if> 來(lái)判斷了:

判斷一個(gè)參數(shù)是否有值,如果沒(méi)值,就會(huì)隱藏 if 中的SQL

 

 現(xiàn)在有一張用戶表

在新增用戶的時(shí)候,將 photo 設(shè)為非比傳參數(shù)

1)傳入photo 時(shí)

 mapper

    //動(dòng)態(tài)SQL,添加用戶,photo為非必傳參數(shù)
    public int add2(UserInfo userInfo);

UserMapper.xml

    <!--動(dòng)態(tài)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 和 #{},是傳?對(duì)象中的屬性,不是數(shù)據(jù)庫(kù)字段 

單元測(cè)試

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

添加結(jié)果

 2)不傳入 photo 時(shí)

不用像沒(méi)使用動(dòng)態(tài)SQL時(shí),將 userInfo.setPhoto(""); 設(shè)為空,直接忽略不寫(xiě)就行了

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

 動(dòng)態(tài)SQL直接忽略photo,添加成功

7.2 <trim> 標(biāo)簽

最主要的作用:去除SQL語(yǔ)句前后多余的某個(gè)字符

語(yǔ)法:

<trim>標(biāo)簽中有如下屬性:

prefix: 表示這個(gè)語(yǔ)句快,以prefix的值作為前綴
suffix:表示整個(gè)語(yǔ)句塊,以suffix的值作為后綴
prefixOverrides:表示整個(gè)語(yǔ)句塊要去除掉的前綴
suffixOverrides:表示整個(gè)語(yǔ)句塊要去除掉的后綴

 UserMapper

    //動(dòng)態(tài)SQL, <trim> 標(biāo)簽。添加用戶,photo為非必傳參數(shù)
    public int add3(UserInfo userInfo);

UserMapper.xml

    <!--動(dòng)態(tài)SQL,<trim> 標(biāo)簽。添加用戶-->
    <insert id="add3">
        insert into userinfo
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="name != null">
                <!--這里拼接的是數(shù)據(jù)庫(kù)中的字段-->
                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>

單元測(cè)試

 這里不傳photo,看拼接的字段前的一個(gè)逗號(hào)是否還在

    @Test
    void add3() {
        UserInfo userInfo = new UserInfo();
        userInfo.setName("黃小小");
        userInfo.setPassword("123");
        //userInfo.setPhoto("123.jpg"); 這里不傳,看拼接的字段前的一個(gè)逗號(hào)是否還在
        int result = userMapper.add2(userInfo);
        log.info("添加用戶:" + result);
    }

7.3 <where> 標(biāo)簽

 主要作用:實(shí)現(xiàn)查詢中的 where SQL替換,它可以實(shí)現(xiàn)如果沒(méi)有任何的查詢條件,那么他可以因此查詢中的 where SQL ,但如果存在查詢中條件,那么會(huì)生成where的 SQL查詢,并且使用 where 標(biāo)簽可以自動(dòng)的去除最后一個(gè) and字符。

1)SQL 替換

根據(jù) id 查詢用戶:

    <!-- 根據(jù) id 查詢用戶 -->
    <select id="getUserById" resultMap="BaseMap">
        select * from userinfo
        <where>
            <if test="id != null">
                id=#{id}
            </if>
 
        </where>
    </select>

 當(dāng)傳入的 id 為 null 時(shí)

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

 2)去除 and

或者通過(guò) id 或者 username 來(lái)查詢時(shí),如果username 為空就會(huì)去掉

7.4 <set> 標(biāo)簽

作用:進(jìn)行修改操作是,配合 if 來(lái)處理非必傳字段,他的特點(diǎn)是主動(dòng)去除最后一個(gè)英文逗號(hào)

語(yǔ)法:

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

1)修改用戶名

 UserMapper

    //動(dòng)態(tài)SQL, <set> 標(biāo)簽。修改用戶
    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>

單元測(cè)試

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

7.5 <foreach> 標(biāo)簽

對(duì)集合進(jìn)?遍歷時(shí)可以使?該標(biāo)簽。<foreach>標(biāo)簽有如下屬性:

collection: 綁定方法參數(shù)中的集合,如List 、Set、Map或數(shù)組對(duì)象
item: 遍歷時(shí)的每一個(gè)對(duì)象
open:語(yǔ)句塊開(kāi)頭的字符串
close:語(yǔ)句塊結(jié)束的字符串
separator:每次遍歷之間間隔的字符串

示例:根據(jù)用戶 id 來(lái)對(duì)用戶進(jìn)行刪除

 UserMapper

    //動(dòng)態(tài)SQL,<foreach>,刪除多個(gè)用戶
    public int delId(List<Integer> ids);

 UserMapper.xml

    <!--動(dòng)態(tài)SQL,刪除多個(gè)用戶-->
    <delete id="delId">
        delete from userinfo where id in
        <foreach collection="ids" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </delete>

單元測(cè)試

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

結(jié)果

總結(jié)

到此這篇關(guān)于MyBatis后端對(duì)數(shù)據(jù)庫(kù)進(jìn)行增刪改查等操作的文章就介紹到這了,更多相關(guān)MyBatis后端對(duì)數(shù)據(jù)庫(kù)操作內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java匿名內(nèi)部類實(shí)例代碼詳解

    java匿名內(nèi)部類實(shí)例代碼詳解

    這篇文章主要介紹了java匿名內(nèi)部類實(shí)例代碼詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • 詳解JVM虛擬機(jī)的類加載機(jī)制

    詳解JVM虛擬機(jī)的類加載機(jī)制

    這篇文章主要介紹了詳解JVM虛擬機(jī)的類加載機(jī)制,虛擬機(jī)把描述類的數(shù)據(jù)從 Class 文件加載到內(nèi)存,并對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)、轉(zhuǎn)換解析和初始化,最終形成可以被虛擬機(jī)直接使用的 Java 類型,這就是虛擬機(jī)的類加載機(jī)制,需要的朋友可以參考下
    2023-08-08
  • Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之圖片展覽館管理系統(tǒng)的實(shí)現(xiàn)

    Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之圖片展覽館管理系統(tǒng)的實(shí)現(xiàn)

    這是一個(gè)使用了java+Springboot+SpringMVC+JPA+Jsp+maven+mysql開(kāi)發(fā)的圖片展覽館管理系統(tǒng),是一個(gè)畢業(yè)設(shè)計(jì)的實(shí)戰(zhàn)練習(xí),具有圖片展覽管理該有的所有功能,感興趣的朋友快來(lái)看看吧
    2022-01-01
  • Java利用Strategy模式實(shí)現(xiàn)堆排序

    Java利用Strategy模式實(shí)現(xiàn)堆排序

    策略設(shè)計(jì)模式(Strategy):可以整體的替換一個(gè)算法的實(shí)現(xiàn)部分,能夠整體的替換算法,能讓我們輕松地用不同方法解決同一個(gè)問(wèn)題。本文將利用Strategy模式實(shí)現(xiàn)堆排序,感興趣的可以學(xué)習(xí)一下
    2022-09-09
  • Mybatis?Plus?中的LambdaQueryWrapper示例詳解

    Mybatis?Plus?中的LambdaQueryWrapper示例詳解

    這篇文章主要介紹了Mybatis?Plus?中的LambdaQueryWrapper,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • SpringBoot輕松整合MongoDB的全過(guò)程記錄

    SpringBoot輕松整合MongoDB的全過(guò)程記錄

    這篇文章主要給大家介紹了關(guān)于SpringBoot輕松整合MongoDB的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 帶你入門(mén)Java的方法

    帶你入門(mén)Java的方法

    這篇文章主要介紹了java基礎(chǔ)之方法詳解,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-07-07
  • java在網(wǎng)頁(yè)上面抓取郵件地址的方法

    java在網(wǎng)頁(yè)上面抓取郵件地址的方法

    這篇文章主要介紹了java在網(wǎng)頁(yè)上面抓取郵件地址的方法,是比較典型的Java正則匹配應(yīng)用實(shí)例,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2014-11-11
  • 詳解Java中字符流與字節(jié)流的區(qū)別

    詳解Java中字符流與字節(jié)流的區(qū)別

    這篇文章主要為大家詳細(xì)介紹了Java中字符流與字節(jié)流的區(qū)別,這兩個(gè)的概念易混淆,今天就為大家進(jìn)行詳細(xì)區(qū)分,感興趣的小伙伴們可以參考一下
    2016-04-04
  • lombok?找不到get/set方法的原因及分析

    lombok?找不到get/set方法的原因及分析

    這篇文章主要介紹了lombok?找不到get/set方法的原因及分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。
    2022-06-06

最新評(píng)論