2.MyBatis

来源:https://www.cnblogs.com/wenjie2000/archive/2023/01/08/17035101.html
-Advertisement-
Play Games

MyBatis 筆記目錄:(https://www.cnblogs.com/wenjie2000/p/16378441.html) 視頻教程(P47~P60) ==看前提醒==:如果之前學過一些框架,只想知道mybatis怎麼用,那麼就不太建議看任何第三方教程,更建議直接去看官方文檔,從入門到具體配 ...


MyBatis

筆記目錄:(https://www.cnblogs.com/wenjie2000/p/16378441.html)

視頻教程(P47~P60)

看前提醒:如果之前學過一些框架,只想知道mybatis怎麼用,那麼就不太建議看任何第三方教程,更建議直接去看官方文檔,從入門到具體配置都有。如果之前沒學過框架,也建議先試著去看,實在不行再繼續看博客或教學視頻內容。(官方文檔不跟你廢話,內容更加精煉)

什麼是MyBatis?

  • MyBatis是一款優秀的持久層框架,用於簡化JDBC開發
  • MyBatis本是Apache 的一個開源項目iBatis, 2010年這個項目由apache softwarefoundation遷移到了google code,並且改名為MyBatis。2013年11月遷移到Github
  • MyBatis官方參考文檔(有中文,必看): https://mybatis.org/mybatis-3/zh/index.html

持久層

  • 負責將數據到保存到資料庫的那一層代碼
  • JavaEE三層架構:表現層、業務層、持久層

框架

  • 框架就是一個半成品軟體,是一套可重用的、通用的、軟體基礎代碼模型
  • 在框架的基礎之上構建軟體編寫更加高效、規範、通用、可擴展

JDBC缺點

  1. 硬編碼(不方便設置修改 資料庫連接和sql語句,不便於後期維護)
  2. 操作繁瑣(很多參數需要手動設置,需要手動封裝結果集)

MyBatis簡化

  1. 硬編碼 → 配置文件
  2. 操作繁瑣 →MyBatis輔助,簡化代碼

MyBatis快速入門

參考網站:https://mybatis.org/mybatis-3/zh/getting-started.html

查詢user表中所有數據

  1. 創建user表,添加數據

  2. 創建模塊,導入坐標(建議先去學習maven基礎)

  3. 編寫MyBatis核心配置文件-->替換連接信息解決硬編碼問題

  4. 編寫SQL映射文件-->統一管理sql語句,解決硬編碼問題

  5. 編碼

    1. 定義POJO類

    2. 載入核心配置文件,獲取 SqlSessionFactory 對象

    3. 獲取SqISession對象,執行SQL語句

    4. 釋放資源

具體操作

  1. 在mysql中創建數據表(直接用,沒必要手敲)(我用的mysql-5.7.38)

    DROP TABLE IF EXISTS `t_user`;
    CREATE TABLE `t_user`  (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `password` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `age` int(11) NULL DEFAULT NULL,
      `gender` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    
    INSERT INTO `t_user` VALUES (1, 'admin', '123456', 23, '男', '[email protected]');
    INSERT INTO `t_user` VALUES (2, 'root', '123', 23, '男', '[email protected]');
    INSERT INTO `t_user` VALUES (4, 'admin2', '123456', 23, '男', '[email protected]');
    
  2. 創建模塊,導入坐標(考慮到某些人沒學過maven,這裡步驟比較詳細。但還是建議先去看maven入門,要不了多少時間。)

    IDEA界面中:左上角 File(文件)-->New(新建)-->Project...(項目)

    選擇maven

    可以看到生成的結構

    將以下內容放到pom.xml中(需要註意依賴、mysql驅動版本)

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.example</groupId>
        <artifactId>mybatis-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <dependencies>
            <!--mybatis依賴-->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.7</version>
            </dependency>
            <!--mysql驅動 版本僅供參考,根據自己電腦中安裝的mysql版本來-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.9</version>
            </dependency>
    
            <!--junit 單元測試-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
            <!--列印日誌 需要相應的配置文件-->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
        </dependencies>
    
    </project>
    

    在resources文件夾中創建文件log4j.xml,並且寫入以下內容(內容固定,拿來用就行,不需要背)

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
    <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
        <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
            <param name="Encoding" value="UTF-8"/>
            <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS}%m (%F:%L) \n"/>
            </layout>
        </appender>
        <logger name="java.sql">
            <level value="debug"/>
        </logger>
        <logger name="org.apache.ibatis">
            <level value="info"/>
        </logger>
        <root>
            <level value="debug"/>
            <appender-ref ref="STDOUT"/>
        </root>
    </log4j:configuration>
    
  3. 編寫MyBatis核心配置文件

    在resources中創建文件mybatis-config.xml,並寫入以下內容(需要根據自己資料庫修改部分內容):

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
    				<!--資料庫鏈接信息 根據自己情況修改-->
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
    			<!--選擇需要載入的sql映射文件(存放需要執行的sql語句的配置文件),下一步會創建-->
                <mapper resource="UserMapper.xml"/>
        </mappers>
    </configuration>
    
  4. 編寫SQL映射文件

    在resources文件夾中創建sql映射文件mybatis-config.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">
    <mapper namespace="test">
    	<!--resultType為返回的數據所對應的類-->
        <select id="selectAll" resultType="com.atguigu.pojo.User">
        select * from t_user
      </select>
    </mapper>
    

    在java文件夾中創建類com.atguigu.pojo.User (存放查詢資料庫時所返回的數據)

    package com.atguigu.pojo;
    
    public class User {
        private Integer id;
        private String username;
        private String password;
        private Integer age;
        private String gender;
        private String email;
    
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
        public Integer getAge() {
            return age;
        }
        public void setAge(Integer age) {
            this.age = age;
        }
        public String getGender() {
            return gender;
        }
        public void setGender(String gender) {
            this.gender = gender;
        }
        public String getEmail() {
            return email;
        }
        public void setEmail(String email) {
            this.email = email;
        }
        
        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", username='" + username + '\'' +
                    ", password='" + password + '\'' +
                    ", age=" + age +
                    ", gender='" + gender + '\'' +
                    ", email='" + email + '\'' +
                    '}';
        }
    }
    
  5. 編碼

    在java文件夾中創建類com.atguigu.MyBatisDemo ,內容如下(不要背,只需要理解每一步的作用):

    package com.atguigu;
    
    import com.atguigu.pojo.User;
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    
    public class MyBatisDemo {
        public static void main(String[] args) throws IOException {
            //1.載入mybatis核心配置文件
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            //2.根據配置文件創建SqlSession工廠
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            //3.通過工廠獲取SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();
            //4.用SqlSession執行sql語句   此處的“test.selectAll”就是sql映射文件中的sql語句位置
            List<User> users = sqlSession.selectList("test.selectAll");
            System.out.println(users);
            //5.釋放資源
            sqlSession.close();
        }
    }
    

    運行MyBatisDemo。出現以下內容則成功

雖然相對於學習JDBC時只是在一個文件中操作而言,看起來似乎更加麻煩,但是也需要考慮實際開發中代碼量大和後續維護困難程度的問題。

Mappr代理開發

List<User> users = sqlSession.selectList("test.selectAll");

你可能會註意到,這種方式和用全限定名調用 Java 對象的方法類似。這樣,該命名就可以直接映射到在命名空間中同名的映射器類,並將已映射的 select 語句匹配到對應名稱、參數和返回類型的方法。因此你就可以像上面那樣,不費吹灰之力地在對應的映射器介面調用方法,就像下麵這樣:

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> users = userMapper.selectAll();

第二種方法有很多優勢,首先它不依賴於字元串字面值,會更安全一點;其次,如果你的 IDE 有代碼補全功能,那麼代碼補全可以幫你快速選擇到映射好的 SQL 語句。

使用Mapper代理方式完成入門案例

  1. 定義與SQL映射文件同名的Mapper介面,並且將Mapper介面和SQL映射文件放置在同一目錄下

    由於maven進行編譯會將java文件夾和resource文件夾下的內容都放到target/classes文件夾中,所以只需要兩者對於java和resources文件夾的相對路徑一致(因此此處沒必要在寫代碼時把配置文件也放到介面同目錄)(註意在resources中創建結構使用“com/atguigu/mapper”的方式,如果使用“com.atguigu.mapper”不會創建多級目錄)

    以下為編譯後的文件結構,兩者在同一目錄中

  2. 設置SQL映射文件的namespace屬性為Mapper介面全限定名

    namespace="com.atguigu.mapper.UserMapper"
    

  3. 在Mapper介面中定義方法,方法名就是SQL映射文件中sql語句的id,並保持參數類型和返回值類型一致

    List<User> selectAll();
    

    修改mybatis配置文件中的sql映射文件的新的路徑

    <mapper resource="com/atguigu/mapper/UserMapper.xml"/>
    

  4. 編碼

    1. 通過SqlSession的 getMapper方法獲取Mapper介面的代理對象
    2. 調用對應方法完成sql的執行
    //獲取UserMapper介面的代理對象
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    List<User> users = userMapper.selectAll();
    

細節:如果Mapper介面名稱和SQL映射文件名稱相同,併在同一目錄下,則可以使用包掃描的方式簡化SQL映射文件的載入

方法如下:

修改mybatis配置文件mybatis-config.xml中<mappers>下的內容

<!--sql映射文件-->
<mappers>
 <!--<mapper resource="com/atguigu/mapper/UserMapper.xml"/>-->

	<package name="com.atguigu.mapper"/>
</mappers>

MyBatis核心配置文件

我只會介紹一些重要的部分,不可能都講完。詳細的可以去官網。

官方文檔(如果需要詳細瞭解就必須去看):https://mybatis.org/mybatis-3/zh/configuration.html

mybatis-config.xml

environments:配置資料庫連接環境信息。可以配置多個environment,通過default屬性切換不同的environment

mappers:配置sql映射文件(上面已經講過了)

typeAliases:類型別名。可以減少需要書寫的類的長度

例如:

在mybatis-config.xml的中加入下麵的內容:

<!--掃描"com.atguigu.pojo"下的所有類,並取一個別名,預設為類名(不區分大小寫)-->
<typeAliases>
 <package name="com.atguigu.pojo"/>
</typeAliases>

後面需要使用com.atguigu.pojo中的類時就只需要寫類名,前面不需要附加包名。例如包中的User類:

當然,也可以對每個類進行單獨的配置。但一般不使用那種方式。如想瞭解可以自行去官網查找。

細節:配置各個標簽時,需要遵守下列的前後順序(必須遵守,否則會報錯)

配置文件完成增刪改查

完成品牌數據的增刪改查操作

產品原型地址:

https://www.pmdaniu.com/storages/122645/74ccff58678d80583ea43a55547173eb-1818/電商後臺高保真原型(首頁).html

  • 要完成的功能列表清單:

    1. 查詢

      查詢所有數據

      查看詳情

      條件查詢

    2. 添加

    3. 修改

      修改全部欄位

      修改動態欄位

    4. 刪除

      刪除一個

      批量刪除

準備環境

①資料庫表tb_brand

-- 刪除tb_brand表
drop table if exists tb_brand;
-- 創建tb_brand表
create table tb_brand(
	-- id主鍵
	id int primary key auto_increment,
	-- 品牌名稱
	brand_name varchar(20),
	-- 企業名稱
	company_name varchar(20),
	-- 排序欄位
	ordered int,
	-- 描述信息
	description varchar(100),
	-- 狀態∶0:禁用1∶啟用
	status int
);
-- 添加數據
insert into tb_brand (brand_name,company_name,ordered,description,status)
values ('三隻松鼠','三隻松鼠股份有限公司',5,'好吃不上火',0),
		('華為','華為技術有限公司', 100,'華為致力於把數字世界帶入每個人、每個家庭、每個組織,構建萬物互聯的智能世界',1),
		('小米','小米科技有限公司',50,'are you ok', 1);
SELECT * FROM tb_brand;

②實體類Brand(放在main/java文件夾下,位置看package)

package com.atguigu.pojo;

public class Brand {
private Integer id;//主鍵
private String brandName;//品牌名稱
private String companyName;//企業名稱
private Integer ordered;//排序欄位
private String description;//描述信息
private Integer status;//狀態

public Integer getId() {return id;}
public void setId(Integer id) {this.id = id;}
public String getBrandName() {return brandName;}
public void setBrandName(String brandName) {this.brandName = brandName;}
public String getCompanyName() {return companyName;}
public void setCompanyName(String companyName) {this.companyName = companyName;}
public Integer getOrdered() {return ordered;}
public void setOrdered(Integer ordered) {this.ordered = ordered;}
public String getDescription() {return description;}
public void setDescription(String description) {this.description = description;}
public Integer getStatus() {return status;}
public void setStatus(Integer status) {this.status = status;}

@Override
public String toString() {
 return "Brand{" +
         "id=" + id +
         ", brandName='" + brandName + '\'' +
         ", companyName='" + companyName + '\'' +
         ", ordered=" + ordered +
         ", description='" + description + '\'' +
         ", status=" + status +
         '}';
}
}

後續如果不想寫資料庫表對應的實體類,也可以使用自動生成,(再根據實際需求進行修改):

先連接資料庫(右側的 Database(資料庫) →"+"→Data Source(數據源)→MySQL→配置好資料庫信息→OK)

創建實體類(也可以使用之前配置好 右側的 Database(資料庫)→schemas→找到表名右鍵→Scripted Extensions(腳本擴展)→Generate POHOs.grovy)

這不是MyBatis的主要內容,我就不詳細說了。
如果想看詳細流程截圖→:https://blog.csdn.net/weixin_42575720/article/details/125093184

③測試用例(放在test/java文件夾下,位置:src/test/java/com/itheima/test/MyBatisTest.java)

④安裝MyBatisX插件(非必要,但開發更加方便)

  • MybatisX是一款基於IDEA的快速開發插件,為效率而生。

  • 安裝:

  • 主要功能:
    XML和介面方法相互跳轉(通過點擊代碼區域左側的鳥)

    根據介面方法生成statement(配置文件中寫sql語句的位置)

    如果在介面中創建方法,但沒寫對應的配置文件會出現如下報錯(如果不安裝這個插件則不會出現):

    Alt+Enter 它可以幫你在配置文件中幫你定義好對應的結構(事先必須要創建配置文件,它不能幫你創建)

    框出的內容為它生成的(只需要手動加上sql語句)

    如果寫sql語句時沒提示可以在 設置中→搜索SQL Dialects(SQL方言)→Global SQL Dialect(全局SQL方言)設置為MySQL

1. 查詢

1.1查詢所有數據

和入門案例類似,以下為基本要點(一定要自己上手,可以複製之前寫的代碼再修改)

代碼參考:

package com.atguigu.mapper;

import com.atguigu.pojo.Brand;

import java.util.List;

public interface BrandMapper {
    List<Brand> selectAll();
}
<?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">
<mapper namespace="com.atguigu.mapper.BrandMapper">

    <select id="selectAll" resultType="Brand">
        SELECT * FROM tb_brand
    </select>
</mapper>
package com.itheima.test;

import com.atguigu.mapper.BrandMapper;
import com.atguigu.pojo.Brand;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class MyBatisTest {
    @Test
    public void testSelectAll() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        SqlSession sqlSession = sqlSessionFactory.openSession();

        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
        List<Brand> brands = brandMapper.selectAll();

        for (Brand brand : brands) {
            System.out.println(brand);
        }
        
        sqlSession.close();
    }
}

運行結果:

這裡可以看到 brandName和companyName並沒有獲取到數據。是因為資料庫中(brand_name,company_name)和實體類欄位名稱( brandName,companyName)不一樣,對不上。需要手動設置。

方法一 起別名:修改sql語句,對不一樣的列名起別名,讓別名和實體類的屬性名一樣(缺點:每次查詢都要定義一次別名。不推薦)

方法二 resultMap(結果映射):

  1. 定義<resultMap>標簽
  2. 在<select>標簽中使用resultMap屬性替換resultType屬性

具體修改如下所示(註意看我的註釋):

<?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">
<mapper namespace="com.atguigu.mapper.BrandMapper">

    <!--
        id:唯一標識
        type:映射的類型,支持別名
    -->
    <resultMap id="brandResultMap" type="brand">
        <!--
            id:完成主鍵欄位的映射
                column:表的列名
                property:實體類的屬性名
            result:完成一般欄位的映射
                column:表的列名
                property:實體類的屬性名
        -->
        <result property="brandName" column="brand_name"/>
        <result property="companyName" column="company_name"/>
    </resultMap>

    <select id="selectAll" resultMap="brandResultMap">
        SELECT * FROM tb_brand
    </select>
</mapper>

現在就能正常顯示了

1.2查看詳情

註意其中配置文件中的#{id}與方法中的id對應,為用作傳遞參數的參數占位符。

//測試方法
@Test
public void testSelectById() throws IOException {
    int id=1;//接收參數
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

    SqlSession sqlSession = sqlSessionFactory.openSession();

    BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
    Brand brand = brandMapper.selectById(id);

    System.out.println(brand);
    sqlSession.close();
}

參數占位符:

  1. #{}:會將其替換為?,為了防止SQL註入。(詳細情況我在JDBC中的Statement部分內容有說明)
  2. ${}:拼接SQL。會存在SQL註入問題。(儘量不用)
  3. 使用時機:
    • 參數傳遞的時候:#{}
    • 表名或者列名不固定的情況下:${}會存在SQL註入問題

註意特殊字元需要特地處理:

例如select * from tb_brand where id<3;由於是在xml文件中“<”不能被正常識別。

  1. 轉義字元

    < 改為 &lt;

  2. CDATA區(輸入CD會出現提示)

    <![CDATA[ < ]]>

1.3條件查詢

條件查詢中經常會出現傳入多個參數的情況,此時就不能只用之前的傳參方式了(因為不知道怎麼匹配)。

處理方法是在介面中對應方法處指出對應關係。

方式如下,主要內容已經給出(不難,我就不粘貼完整代碼了,自己完成)

SQL語句設置多個參數的三種方式

  1. 散裝參數:需要使用@Param("SQL中的參數占位符名稱")

    @Param("配置文件中的標識")形參(例如:@Param("status")int status)

    如果不加@Param(""),mybatis就會自動命名。(mybatis會預設使用arg0,arg1,arg2....或param1,param2,param3...作為標識)

  2. 實體類封裝參數

    *只需要保證SQL中的參數名和實體類屬性名對應上,即可設置成功
    將參數放到實體類對象中,直接傳該對象。其中變數名對應標識,變數名對應值。
    (例如:此處可以把status、companyName、brandName存放到Brand對象中)

  3. map集合

    *只需要保證SQL中的參數名和map集合的鍵的名稱對應上,即可設置成功
    創建hashMap。將配置文件中的標識符作為key,對應的值為value存放到其中。

但是上面這樣寫SQL語句在實際使用中會出現Bug。因為當存在框中內容為空的情況下,sql語句對應位置的參數就為null,因而導致查詢結果錯誤。因此需要用到動態SQL


動態SQL

官方教程:https://mybatis.org/mybatis-3/zh/dynamic-sql.html

SQL語句會隨著用戶的輸入或外部條件的變化而變化,我們稱為動態SQL

  • MyBatis 對動態SQL有很強大的支撐,利用下列標簽可以實現動態SQL:

    if

    choose (when, otherwise)

    trim (where, set)

    foreach

if

用於判斷參數是否有值,使用test屬性進行條件判斷

使用動態 SQL 最常見情景是根據條件包含 where 子句的一部分。比如:

<select id="selectByCondition" resultMap="brandResultMap">
  SELECT * FROM tb_brand
  WHERE id = 1
  <if test="status != null">
    AND status = #{status}
  </if>
</select>

對於之前的題目,就能利用if判斷是否有值來執行動態的SQL語句。

但是對於存在多個搜索條件的情況下,則會出現一些問題。例如:

# 第一個條件不需要邏輯運算符and,or等連接
select * from tb_brand where
status = #{status}
and company_name like #{companyName}
and brand_name like #{brandName}

對於上面的sql語句,轉換為動態SQL,需要進行針對性的處理。對此有兩種方法:

  1. 使用恆等式(加入1=1)(僅需瞭解,實際情況儘量不用或少用)

    select * from tb_brand where 
    1=1
    <if test="status != null">
      and status = #{status}
    </if>
    <if test="companyName != null">
      and company_name like #{companyName}
    </if>
    <if test="brandName != null">
      and brand_name like #{brandName}
    </if>
    
  2. 使用替換where關鍵字(where標簽很智能,如果where後面跟的有and,會自動刪除。如果where後面沒內容,where也會刪除)

    select * from tb_brand 
    <where> 
        <if test="status != null">
          and status = #{status}
        </if>
        <if test="companyName != null">
          and company_name like #{companyName}
        </if>
        <if test="brandName != null">
          and brand_name like #{brandName}
        </if>
    <where> 
    

choose (when, otherwise)

choose有點像 Java 中的 switch 語句。

select *
from tb_brand where
<choose> <!--類似於switch-->
    <when test="status !=null"> <!--類似於case-->
        status= #{status}
    </when>
    <when test="companyName != null and companyName !=''">
        company_name like #{companyName}
    </when>
    <when test="brandName != null and brandName !=''">
        brand_name like #{brandName}
    </when>
    <otherwise> <!--類似於default-->
    	1=1
    </otherwise>
</choose>

2.添加

要點已給出,具體代碼自行完成.(註意這裡不用<select>,使用<insert>)

有些人會出現程式運行成功,但資料庫中沒有數據的情況,是因為mybatis預設開啟事務,只需在創建sqlSession時,傳入參數true(設置是否自動提交)。或是執行後加上sqlSession.commit();實現手動提交

SqlSession sqlSession = sqlSessionFactory.openSession(true);

添加-主鍵返回

經常會出現添加數據後需要獲取數據對應的主鍵。

可以使用實體類封裝參數(例如此處的Brand brand),然後將獲取的主鍵存放到對象中(然後再訪問brand中存放的主鍵值)。

3.修改

3.1 修改全部欄位

3.2修改動態欄位

註意此處可以用<set>標簽代替set。(<set>可以去掉末尾的逗號,如果<set>中沒有內容,則不會加上set)

4.刪除

4.1刪除一個

4.2批量刪除

註意:mybatis預設會將數組參數封裝為一個Map集合。

  • 預設key為“array”,value為數組
  • 也可以使用@Param註解改變map集合的預設key的名稱(例如:@Param("ids")int[] ids)

MyBatis參數傳遞

MyBatis介面方法中可以接收各種各樣的參數,MyBatis底層對於這些參數進行不同的封裝處理方式(MyBatis提供了ParamNameResolver類來進行參數封裝)

如果想要加深理解可以去看源碼或視頻(源碼部分筆記不好寫):https://www.bilibili.com/video/BV1Qf4y1T7Hx/?p=59

單個參數:

  1. POJO類型:直接使用,鍵名和參數占位符名稱一致

  2. Map集合:直接使用,鍵名和參數占位符名稱一致

  3. Collection:封裝為Map集合,,可以使用@Param註解,替換Map集合中預設的arg鍵名

    map.put("arg0",collection集合);

    map.put("collection",collection集合);

  4. List:封裝為Map集合,,可以使用@Param註解,替換Map集合中預設的arg鍵名

    map.put("arg0",list集合);

    map.put("collection",list集合);

    map.put("list",list集合);

  5. Array:封裝為Map集合,可以使用@Param註解,替換Map集合中預設的arg鍵名

    map.put("arg0",array集合);

    map.put("array",array集合);

  6. 其他類型(例如int):直接用,#{}中寫啥都能接收到

多個參數:封裝為Map集合(但不推薦使用預設的,因為可讀性差。過段時間再看就不知道傳的是什麼東西了。建議∶將來都使用@Param註解來修改Map集合中預設的鍵名(arg)、並使用修改後的名稱來獲取值,這樣可讀性更高!

map.put("arg0",參數1)

map.put("arg1",參數2)

map.put("param1",參數1)

map.put("param2",參數2)

---------------------------------(@Param("username")參數1,參數2)

map.put("username",參數1)

map.put("arg1",參數2)

map.put("param1",參數1)

map.put("param2",參數2)

使用註解完成增刪改查

使用註解開發會比配置文件開發更加方便(僅針對完成簡單的功能)

@Select("select * from tb_user where id = #{id}")
public User selectByld(int id);


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 利用 GetSystemTimes 可以獲得 Windows 系統的 Idle Time、 Kernel Time 和 User Time。Idle Time 是系統空閑的時間,也就是系統沒有利用的時間。Kernel Time 是系統在內核模式下的執行時間。User Time 是系統在用戶模式下的執 ...
  • 官網下載: https://www.snipaste.com Snipaste 免費,支持 Windows、Mac,Windows 上的功能相當多而且,Mac 也夠用了 不僅僅是個截圖工具,具有強大功能: 截圖 貼圖(直接將截圖貼在桌面上,當標簽貼使用) 取色器 常用快捷健 fn + F1: 開始截 ...
  • Vue02 7.修飾符 7.1基本說明 修飾符(Modifiers)是以.指明的尾碼,指出某個指令以特殊方式綁定 官方文檔:修飾符 Vue中的修飾符有: 事件修飾符 按鍵修飾符 系統修飾符 事件修飾符 <!-- 阻止單擊事件繼續傳播 --> <a v-on:click.stop="doThis">< ...
  • 變數作用域: 1、全局變數:在全局作用域下聲明的變數 ​ 在函數內部沒有聲明直接賦值的變數也是屬於全局變數 全局變數:只有瀏覽器關閉的時候才會銷毀,比較占記憶體資源 局部變數 :當我們程式執行完畢就會銷毀,比較節約記憶體資源 作用域鏈:內部函數訪問外部函數的變數,採取的是鏈式查找的方式來決定取哪個值 這 ...
  • 歡迎閱讀本系列其他文章 【前端調試】- 更好的調試方式 VSCode Debugger 【前端調試】- 斷點調試的正確打開方式 介紹 首先簡單過一下Performance的使用,打開網頁點擊控制台Performance,錄製5s的數據 其中 Main 這部分就是網頁的主線程,也就是執行 Event ...
  • 方法 System.out.println();//是什麼嗎? //系統類+對象+方法 Java方法是一對語句的集合,他們一起負責執行一個功能 方法是解決一類問題的步驟的有序組合 方法包含於類或對象中 方法在程式中被創建,在其他地方被引用 設計原則: 方法本意是功能塊**(類似C語言的函數)**, ...
  • 一、列表是什麼 列表:由一系列按特定順序排列的元素組成(列表是有序集合)。 表示:用方括弧[]來表示,並用逗號來分隔其中的元素。 訪問:訪問列表元素,可指出列表的名稱,再指出元素的索引,並將其放在方括弧內。請求獲取列表元素時,Python只返回該元素,而不包括方括弧和引號。 列表索引從0開始:在Py ...
  • 實踐環境 Odoo 14.0-20221212 (Community Edition) Odoo Web Login Screen 14.0 https://apps.odoo.com/apps/modules/14.0/odoo_web_login/# 操作步驟 1、把下載的odoo web lo ...
一周排行
    -Advertisement-
    Play Games
  • C#TMS系統代碼-基礎頁面BaseCity學習 本人純新手,剛進公司跟領導報道,我說我是java全棧,他問我會不會C#,我說大學學過,他說這個TMS系統就給你來管了。外包已經把代碼給我了,這幾天先把增刪改查的代碼背一下,說不定後面就要趕鴨子上架了 Service頁面 //using => impo ...
  • 委托與事件 委托 委托的定義 委托是C#中的一種類型,用於存儲對方法的引用。它允許將方法作為參數傳遞給其他方法,實現回調、事件處理和動態調用等功能。通俗來講,就是委托包含方法的記憶體地址,方法匹配與委托相同的簽名,因此通過使用正確的參數類型來調用方法。 委托的特性 引用方法:委托允許存儲對方法的引用, ...
  • 前言 這幾天閑來沒事看看ABP vNext的文檔和源碼,關於關於依賴註入(屬性註入)這塊兒產生了興趣。 我們都知道。Volo.ABP 依賴註入容器使用了第三方組件Autofac實現的。有三種註入方式,構造函數註入和方法註入和屬性註入。 ABP的屬性註入原則參考如下: 這時候我就開始疑惑了,因為我知道 ...
  • C#TMS系統代碼-業務頁面ShippingNotice學習 學一個業務頁面,ok,領導開完會就被裁掉了,很突然啊,他收拾東西的時候我還以為他要旅游提前請假了,還在尋思為什麼回家連自己買的幾箱飲料都要叫跑腿帶走,怕被偷嗎?還好我在他開會之前拿了兩瓶芬達 感覺感覺前面的BaseCity差不太多,這邊的 ...
  • 概述:在C#中,通過`Expression`類、`AndAlso`和`OrElse`方法可組合兩個`Expression<Func<T, bool>>`,實現多條件動態查詢。通過創建表達式樹,可輕鬆構建複雜的查詢條件。 在C#中,可以使用AndAlso和OrElse方法組合兩個Expression< ...
  • 閑來無聊在我的Biwen.QuickApi中實現一下極簡的事件匯流排,其實代碼還是蠻簡單的,對於初學者可能有些幫助 就貼出來,有什麼不足的地方也歡迎板磚交流~ 首先定義一個事件約定的空介面 public interface IEvent{} 然後定義事件訂閱者介面 public interface I ...
  • 1. 案例 成某三甲醫預約系統, 該項目在2024年初進行上線測試,在正常運行了兩天後,業務系統報錯:The connection pool has been exhausted, either raise MaxPoolSize (currently 800) or Timeout (curren ...
  • 背景 我們有些工具在 Web 版中已經有了很好的實踐,而在 WPF 中重新開發也是一種費時費力的操作,那麼直接集成則是最省事省力的方法了。 思路解釋 為什麼要使用 WPF?莫問為什麼,老 C# 開發的堅持,另外因為 Windows 上已經裝了 Webview2/edge 整體打包比 electron ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...