Mybatis基礎最全總結

2021-02-14 樂享Coding
Mybatis框架★

ORMapping:對象關係映射

關係指關係型資料庫的映射

Java到MySQL的映射,開發者可以以面向對象的思想進行開發。

」優點SQL寫在XML文件裡,降低耦合度,便於統一管理和優化,並可重用。提供映射標籤,支持對象與資料庫的ORM欄位關係映射。缺點SQL語句編寫工作量較大,尤其是欄位多,關聯表多時,更是複雜。SQL語句依賴資料庫,不同資料庫SQL語句存在細微差異,不能隨意更換資料庫。開發方式初步使用

導入依賴

<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<!--mysql驅動-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>

CREATE TABLE t_account(
 id INT PRIMARY KEY AUTO_INCREMENT,
 username VARCHAR(11) ,
 pwd VARCHAR(11),
 age INT
)

@Data
public class Account {
    private Integer id;
    private String username;
    private String pwd;
    private Integer age;
}

全局配置核心文件SqlMapperConfig.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>
    <!--配置mybatis運行環境-->
    <environments default="development">
        <environment id="development">
            <!--配置jdbc事務管理-->
            <transactionManager type="JDBC"/>
            <!--配置JDBC數據源連接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatisExercise?useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="77549252"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

使用原生接口

1.Mybatis框架需要開發者自定義SQL語句,寫在Mapper.xml文件中,實際開發中,會為每個實體類創建對應的Mapper.xml,定義管理該對象數據的SQL。

★namespace通常設置為文件所在包+文件名的形式。id是實際調用Mybatis方法時需要用到的參數。parameterType是調用對應方法時參數的數據類型」
<?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.Long.Mapper.XML.AccountMapper">
<!--    <select id=""></select>-->
<insert id="add" parameterType="com.Long.Entity.Account">
insert into t_account(username,pwd,age) values (#{username},#{pwd},#{age});
</insert>
<!--    <delete id=""></delete>-->
<!--    <update id=""></update>-->
</mapper>

2.AccountMapper.xml註冊到全局配置核心文件SqlMapperConfig.xml文件中

<!--註冊AccountMapper.xml-->
<mappers>
    <!--這裡路徑用/-->
    <mapper resource="com/Long/Mapper/XML/AccountMapper.xml"></mapper>
</mappers>

3.pom.xml配置java目錄下的xml文件生效,默認只是resource目錄下xml文件生效

<!--配置java目錄下xml文件生效-->
<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
</build>

4.測試

public class testMybatis {
    public static void main(String[] args) {
        //加載Mybatis配置文件
        InputStream InputStream = testMybatis.class.getClassLoader().getResourceAsStream("SqlMapperConfig.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory Factory = sqlSessionFactoryBuilder.build(InputStream);
        SqlSession sqlSession = Factory.openSession();
        String statement="com.Long.Mapper.XML.AccountMapper.add";
        Account account =new Account(1,"張三","123456",18);
          //提交事務
        sqlSession.commit(); //查詢不需要,增刪改必須提交
        //關閉連接池
        sqlSession.close();
    }
}

通過Mapper代理實現自定義接口(重要)

自定義Mapper接口

public interface AccountMapper {
    int add(Account account);
    int update(Account account);
    int deleteById(Integer id);
    List<Account> findAll();
    Account findById(Integer id);
}

2.創建對應的Mapper.xml,定義接口方法對應的SQL語句。

標籤可選insert,delete,update,select。

Mybatis框架會根據規則自動創建接口實現類的代理對象。(代理的是接口,代理對象為實現類)

映射規則:

parameterType屬性值和接口中對應方法傳遞的參數類型一致。resultType屬性值和接口中對應方法返回值類型一致(只有查用寫,增刪改都是返回int)。
@Test
public  void test2() {
InputStream InputStream = testMybatis.class.getClassLoader().getResourceAsStream("SqlMapperConfig.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory Factory = sqlSessionFactoryBuilder.build(InputStream);
SqlSession sqlSession = Factory.openSession();
//獲取實現接口的代理對象
AccountMapper mapper = sqlSession.getMapper(AccountMapper.class);
//增
Account account1 = new Account(1,"小風","14525",18);
mapper.add(account1);
sqlSession.commit();
//查
List<Account> accountList = mapper.findAll();
for (Account account:accountList
) {
System.out.println(account);
}
//刪
mapper.deleteById(1);
sqlSession.commit();
//查
System.out.println(mapper.findById(2));
//改
Account account2 = new Account(3, "小雨", "145256", 18);
mapper.update(account2);
sqlSession.commit();
//關閉連接池
sqlSession.close();
}

★總結」

先解析resource文件夾下Config.xml文件配置的環境(如何連接資料庫)和註冊的mapper.xml文件。

Mapper.xml文件配置實體類(JavaBean)屬性與資料庫欄位如何進行映射。

級聯查詢

class表

student表

Java實體類映射【Student】和【Classes】

@Data
public class Student {
    private Integer id;
    private String name;
    private Classes classes;
}

@Data
public class Classes {
    private Integer id;
    private String name;
    private List<Student> students;
}

連接查詢一對一

連接student表和class表,查詢id為1的學生(包含所在班級名稱)

SQL語句

select * from student s,class c where s.cid=c.id and s.id =1;

xml配置文件

<mapper namespace="com.Long.Mapper.StudentMapper">
<resultMap id="studentMap" type="com.Long.Entity.Student">
<id column="id" property="id"/>
<result column="name" property="name"/>
<association property="classes" javaType="com.Long.Entity.Classes">
    <id column="cid" property="id"/>
    <result column="cname" property="name"/>
</association>
</resultMap>
<select id="findByIdAndClass" parameterType="Integer" resultMap="studentMap">
select s.id,s.name,c.id as cid,c.name as cname from student s,class c where s.id = #{id} and s.cid = c.id
</select>

總結

」查詢操作返回值映射

resultType屬性

直接映射,即根據資料庫欄位名稱和Java對象屬性名稱和類型一一映射,

resultmap屬性

根據column屬性(資料庫欄位名稱)和property屬性(Java對象屬性名)進行名稱映射的。包含多個欄位的java對象需要association標籤包含多個欄位的java集合需要association標籤一對多

連接student表和class表,查詢id為2的班級中所有學生信息

SQL語句

select s.id,s.name ,c.id,c.name from student s,class c where c.id =2 and s.cid = c.id

xml配置文件

<mapper namespace="com.Long.Mapper.StudentMapper">
<resultMap id="studentMap" type="com.Long.Entity.Student">
<id column="id" property="id"/>
<result column="name" property="name"/>
<association property="classes" javaType="com.Long.Entity.Classes">
    <id column="cid" property="id"/>
    <result column="cname" property="name"/>
</association>
</resultMap>
<select id="findByIdAndClass" parameterType="Integer" resultMap="studentMap">
select s.id,s.name ,c.id,c.name from student s,class c where s.id = #{id} and s.cid = c.id;
</select>

測試

@Test
public void test3() {
    InputStream InputStream = Student.class.getClassLoader().getResourceAsStream("SqlMapperConfig.xml");
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    SqlSessionFactory Factory = sqlSessionFactoryBuilder.build(InputStream);
    SqlSession sqlSession = Factory.openSession();
    //獲取實現接口的代理對象
    ClassesMapper mapper = sqlSession.getMapper(ClassesMapper.class);
    System.out.println(mapper.findStudentsByClassId(2)); //返回的集合不用for循環遍歷
    sqlSession.close();
}

多對多(一對多的升級)逆向工程(代碼自動生成)★

傳統的開發中上述的三個組件需要開發者手動創建,逆向工程可以幫助開發者來自動創建三個組件,減輕開發者的工作量,提高工作效率。

MyBatis 框架需要(三個組件):

MyBatis Generator,簡稱 MBG,是⼀個專門為 MyBatis 框架開發者定製的代碼⽣成器,可自動生成MyBatis 框架所需上述三組件,也可支持基本的 CRUD 操作,但是⼀些相對複雜的 SQL 需要開發者自己來完成。

相關jar包
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
</dependency>

創建 MBG 配置文件 config.xml

1、jdbcConnection 配置資料庫連接信息。

2、javaModelGenerator 配置 JavaBean 的生成策略。

3、sqlMapGenerator 配置 SQL 映射文件生成策略。

4、javaClientGenerator 配置 Mapper 接口的生成策略。

5、table 配置目標數據表(tableName:表名,domainObjectName:JavaBean 類名)。

resouce目錄下的config.xml配置文件
<?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>
    <context id="testTables" targetRuntime="MyBatis3">
        <jdbcConnection
                driverClass="com.mysql.cj.jdbc.Driver"
                connectionURL="jdbc:mysql://localhost:3306/mybatisExercise?useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=UTC"
                userId="root"
                password="77549252"
        />
        <javaModelGenerator targetPackage="com.Long.Entity"
                            targetProject="Genertor/src/main/java"/>
        <sqlMapGenerator targetPackage="com.Long.Mapper.XML"
                         targetProject="Genertor/src/main/java"/>
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.Long.Mapper" targetProject="Genertor/src/main/java">
        </javaClientGenerator>
        <table tableName="t_account" domainObjectName="Account"/>
    </context>
</generatorConfiguration>

Genertor類測試
public class Genertor {
    public static void main(String[] args) {
        List<String> warings = new ArrayList<String>();
        boolean overwrite = true;
        String genCig = "/config.xml";
        File configFile = new File(Genertor.class.getResource(genCig).getFile());
        ConfigurationParser configurationParser = new
                ConfigurationParser(warings);
        Configuration configuration = null;
        try {
            configuration = configurationParser.parseConfiguration(configFile);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (XMLParserException e) {
            e.printStackTrace();
        }
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = null;
        try {
            myBatisGenerator = new
                    MyBatisGenerator(configuration, callback, warings);
        } catch (InvalidConfigurationException e) {
            e.printStackTrace();
        }
        try {
            myBatisGenerator.generate(null);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

目錄結構延遲加載 (懶加載)★

延遲加載也叫懶加載、惰性加載,使⽤延遲加載可以提高程序的運行效率,針對於數據持久層的操左, 在某些特定的情況下去訪問特定的資料庫,在其他情況下可以不訪問某些表,從⼀定程度上減少了 Java 應用與資料庫的交互次數。

查詢學生和班級的時,學生和班級是兩張不同的表,如果當前需求只需要獲取學生的信息,那麼查詢學生單表即可。

如果需要通過學生獲取對應的班級信息,則必須查詢兩張表。

不同的業務需求,需要查詢不同的表,根據具體的業務需求來動態減少數據表查詢的工作就是延遲加載。

之前查詢任務實現懶加載

連接student表和class表,查詢id為1的學生(包含所在班級名稱)

select * from student s,class c where s.cid=c.id and s.id =1;

select * from  student where id =1;

當需要班級信息時,需要執行下面SQL語句,id參數為第一條語句查詢到的cid

select * from  class where id =#{id};

懶加載目的:不需要獲取班級信息的需求時不需要執行第二條sql語句,增加效率,根據需求可以動態改變。

resouce目錄下的config.xml配置文件配置懶加載

<settings>
    <!-- 列印SQL-->
    <setting name="logImpl" value="STDOUT_LOGGING" />
    <!-- 開啟延遲加載 -->
    <setting name="lazyLoadingEnabled" value="true"/>
</settings>

StudentMapper接口和ClassesMapper接口各定義查找方法

// ClassesMapper接口
public interface ClassesMapper {
    Classes findById(Integer id);
}

public interface StudentMapper {
    Student findById(Integer id);
}

配置文件配置兩條SQL語句的關係

StudentMapper.xml文件下配置

<mapper namespace="com.Long.Mapper.StudentMapper">
<resultMap id="studentMap" type="com.Long.Entity.Student">
    <id column="id" property="id"/>
    <result column="name" property="name"/>
    <collection property="classes" javaType="com.Long.Entity.Classes"
                select="com.Long.Mapper.ClassesMapper.findById" column="cid"/>
</resultMap>
<select id="findById" parameterType="Integer" resultMap="studentMap">
    select * from  student where id =#{id};
</select>
</mapper>

ClassesMapper.xml文件下配置

<mapper namespace="com.Long.Mapper.ClassesMapper">
    <select id="findById" parameterType="Integer" resultType="com.Long.Entity.Classes">
        select * from  class where id =#{id};
</select>
</mapper>

測試

@Test
public void test3() {
    InputStream InputStream = test.class.getClassLoader().getResourceAsStream("SqlMapperConfig.xml");
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    SqlSessionFactory Factory = sqlSessionFactoryBuilder.build(InputStream);
    SqlSession sqlSession = Factory.openSession();
    StudentMapper StudentMapper = sqlSession.getMapper(StudentMapper.class);
    Student student = StudentMapper.findById(1);
    System.out.println(student.getName()); //懶加載下不需要加載班級信息,執行1條SQL語句
//  System.out.println(student.getClasses()); //懶加載下需要加載班級信息,執行2條SQL語句
    sqlSession.close();
}

緩存★

使用緩存可以減少 Java 應用與資料庫的交互次數,從而提升程序的運行效率。比如查詢出 id = 1 的對象,第⼀次查詢出之後會⾃動將該對象保存到緩存中,當下⼀次查詢時,直接從緩存中取出對象即可,無需再次訪問資料庫。

分類1、⼀級緩存:SqlSession 級別,默認開啟,並且不能關閉。

操作資料庫時需要創建SqlSession對象,在對象中有⼀個HashMap用於存儲緩存數據,不同的SqlSession 之間緩存數據區域是互不影響的。

⼀級緩存的作用域是SqlSession範圍的,當在同⼀個SqlSession中執行兩次相同的 SQL 語句事,第⼀次執行完畢會將結果保存到緩存中,第二次查詢時直接從緩存中獲取。

需要注意的是,如果SqlSession執行了 DML 操作(insert、update、delete),MyBatis 必須將緩存清空以保證數據的準確性。

驗證
@Test
public void test4() {
    InputStream InputStream = test.class.getClassLoader().getResourceAsStream("SqlMapperConfig.xml");
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    SqlSessionFactory Factory = sqlSessionFactoryBuilder.build(InputStream);
    SqlSession sqlSession = Factory.openSession();
    StudentMapper StudentMapper = sqlSession.getMapper(StudentMapper.class);
    Student student = StudentMapper.findById(1);
    System.out.println(student.getName());
    sqlSession.close();
    SqlSession sqlSession1 = Factory.openSession(); //創建不同的SqlSession
    StudentMapper StudentMapper1 = sqlSession1.getMapper(StudentMapper.class);
    Student student1 = StudentMapper1.findById(1);
    System.out.println(student1.getName());
    sqlSession1.close();
}

@Test
public void test4() {
    InputStream InputStream = test.class.getClassLoader().getResourceAsStream("SqlMapperConfig.xml");
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    SqlSessionFactory Factory = sqlSessionFactoryBuilder.build(InputStream);
    SqlSession sqlSession = Factory.openSession();
    StudentMapper StudentMapper = sqlSession.getMapper(StudentMapper.class);
    Student student = StudentMapper.findById(1);
    Student student1 = StudentMapper.findById(1);
    System.out.println(student.getName());
    System.out.println(student1.getName());
    sqlSession.close();
}

2、二級緩存:Mapper級別,默認關閉,可以開啟。使用二級緩存時,多個SqlSession使用同⼀個Mapper的 SQL 語句操作資料庫,得到的數據會存在二級緩存區。同樣是使用HashMap進行數據存儲,相比較於⼀級緩存,二級緩存的範圍更大,多個SqlSession 可以共用二級緩存,★

二級緩存是多個 SqlSession 共享的,其作用域是Mapper的同⼀個namespace,不同的SqlSession兩次執行相同的 namespace 下的 SQL 語句,參數也相等,則第⼀次執行成功之後會將數據保存到二級緩存中,第二次可直接從二級緩存中取出數據。

」Mybatis自帶二級緩存

Resource目錄下的config.xml文件配置

<!-- 開啟⼆級緩存 -->
<setting name="cacheEnabled" value="true"/>

Entity包下的實體類實現序列化接口

@Data
public class Student  implements Serializable {
    private Integer id;
    private String name;
    private Classes classes;
}

驗證

@Test
public void test4() {
    InputStream InputStream = test.class.getClassLoader().getResourceAsStream("SqlMapperConfig.xml");
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    SqlSessionFactory Factory = sqlSessionFactoryBuilder.build(InputStream);
    SqlSession sqlSession = Factory.openSession();
    StudentMapper StudentMapper = sqlSession.getMapper(StudentMapper.class);
    Student student = StudentMapper.findById(1);
    System.out.println(student.getName());
    sqlSession.close();
    SqlSession sqlSession1 = Factory.openSession(); //創建不同的SqlSession
    StudentMapper StudentMapper1 = sqlSession1.getMapper(StudentMapper.class);
    Student student1 = StudentMapper1.findById(1);
    System.out.println(student1.getName());
    sqlSession1.close();
}

ehcache二級緩存

pom.xml導入相關jar包

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.0.0</version>
</dependency>
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache-core</artifactId>
    <version>2.4.3</version>
</dependency>

添加Resource目錄下的ehcache.xml,配置相關配置。

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
    <diskStore/>
    <defaultCache
            maxElementsInMemory="1000"
            maxElementsOnDisk="10000000"
            eternal="false"
            overflowToDisk="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
    </defaultCache>
</ehcache>

爆紅請參考

https://blog.csdn.net/qq_45738810/article/details/107908914?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522161218684316780266289407%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fall.%252522%25257D&request_id=161218684316780266289407&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~times_rank-1-107908914.pc_search_result_no_baidu_js&utm_term=ehcache.xml

Resource目錄下的config.xml文件配置

<!-- 開啟⼆級緩存 -->
<setting name="cacheEnabled" value="true"/>

Mapper.xml配置緩存策略

<cache type="org.mybatis.caches.ehcache.EhcacheCache">
 <!-- 緩存創建之後,最後⼀次訪問緩存的時間至緩存失效的時間間隔 -->
 <property name="timeToIdleSeconds" value="3600"/>
 <!-- 緩存⾃創建時間起⾄失效的時間間隔 -->
 <property name="timeToLiveSeconds" value="3600"/>
 <!-- 緩存回收策略,LRU表示移除近期使⽤最少的對象 -->
 <property name="memoryStoreEvictionPolicy" value="LRU"/>
</cache>

Entity包下的實體類不需要實現序列化接口

@Data
public class Student {
    private Integer id;
    private String name;
    private Classes classes;
}

動態SQL標籤★

使用動態SQL可簡化代碼的開發,減少開發者的工作量,程序可以自動根據業務參數來決定SQL的組成。

AccountMapper AccountMapper = sqlSession.getMapper(AccountMapper.class);
Account account = new Account(1,"小明","123",22);
System.out.println(AccountMapper.findByAccount(account));
Account accountOne = new Account("小明","123");
System.out.println(AccountMapper.findByAccount(accountOne));

<!--動態執行該SQL語句,當需要根據id和username查時不需要額外的語句-->
<select id="findByAccount" parameterType="com.Long.Entity.Account" resultType="com.Long.Entity.Account">
    select * from t_account where id =#{id} and username =#{username} and pwd=#{pwd} and age =#{age};
</select>

上述代碼無動態SQL語句時,當只知道帳戶姓名和密碼時確匹配失敗,原因在於SQL語句多餘傳了默認值。

if 標籤★

if 標籤可以自動根據表達式的結果來決定是否將對應的語句添加到 SQL 中,如果條件不成立則不添加, 如果條件成立則添加。

」where 標籤 (和if標籤連用)

注意:where 標籤不會檢測SQL語句末尾多餘的and並刪除,因此and寫在前面

where 標籤可以自動判斷是否要刪除語句塊中的 and 關鍵字,如果檢測到 where 直接跟 and 拼接,則自動刪除 and,通常情況下 if 和 where 結合起來使用。

<select id="findByAccount" parameterType="com.Long.Entity.Account" resultType="com.Long.Entity.Account">
    select * from t_account
    <where>
    <if test="id!=null">
         id =#{id}
    </if>
    <if test="username!=null">
        and  username =#{username}
    </if>
    <if test="pwd!=null">
        and  pwd=#{pwd}
    </if>
    <if test="age!=null">
        and age =#{age}
    </if>
    </where>
</select>

choose 、when  、otherwise 標籤★

有時候,我們不想使用所有的條件,而只是想從多個條件中選擇一個使用。針對這種情況,MyBatis 提供了 choose 元素,它有點像 Java 中的 switch 語句。choose執行過程中按順序判斷 when 中的條件出否成立,如果有一個成立,則 choose 結束。當 choose 中所有 when的條件都不滿則時,則執行 otherwise 中的 sql。

<!--動態執行該SQL語句,當需要根據id和username查時不需要額外的語句-->
<select id="findByAccount" parameterType="com.Long.Entity.Account" resultType="com.Long.Entity.Account">
    select * from t_account
    <where>
    <choose>
    <when test="id!=null">
         id =#{id}
    </when>
    <when test="username!=null">
        and  username =#{username}
    </when>
    <when test="pwd!=null">
        and  pwd=#{pwd}
    </when>
    <when test="age!=null">
        and age =#{age}
    </when>
    <otherwise>
        <!--如果傳入參數都為null那麼就返回id=1的數據-->
        id = 1
    </otherwise>
    </choose>
    </where>
</select>

trim 標籤★

trim 標籤中的 prefix 和 suffix 屬性會被用於生成實際的 SQL 語句,會和標籤內部的語句進行拼接,如果語句前後出現了 prefixOverrides或者suffixOverrides 屬性中指定的值,MyBatis 框架會自動將其刪除。

用trim標籤實現where標籤的作用

<!--where後面發現緊跟著and就自動刪除-->
<trim prefix="where" prefixOverrides="and">

set 標籤★

set 標籤用於 update 操作,會自動根據參數選擇生成 SQL 語句。

」靜態更新SQL的問題
Account account = new Account(1,"小明","123",22);
System.out.println(AccountMapper.findByAccount(account));
account.setAge(18); //僅更改了年齡但SQL語句中其他屬性進行了重複賦值
AccountMapper.update(account);
System.out.println(account);

<mapper namespace="com.Long.Mapper.AccountMapper">
<update id="update"  parameterType="com.Long.Entity.Account">
    update t_account set age=#{age},username =#{username},pwd=#{pwd} where id =#{id}
</update>

增加set標籤
<mapper namespace="com.Long.Mapper.AccountMapper">
<update id="update"  parameterType="com.Long.Entity.Account">
update t_account
<set>
    <choose>
    <when test="username!=null">
        and  username =#{username}
    </when>
    <when test="pwd!=null">
        and  pwd=#{pwd}
    </when>
    <when test="age!=null">
        and age =#{age}
    </when>
    </choose>
</set>
where id = #{id}
</update>

foreach 標籤★

foreach 標籤可以迭代生成⼀系列值,這個標籤主要用於 SQL 的 in 語句。

舉例

僅查詢id=1,2,4的帳戶信息

靜態SQL語句
select * from t_account where id in(1,2,4);

動態SQL(字符串拼接)
<select id="findByIds" parameterType="com.Long.Entity.Account" resultType="com.Long.Entity.Account">
select * from t_account
<where>
    <foreach collection="ids" open="id in (" close=")" item="id"
             separator=",">
        #{id}
    </foreach>
</where>
</select>

測試
ArrayList<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(2);
ids.add(4);
Account account = new Account();
account.setIds(ids);
System.out.println(AccountMapper.findByIds(account));

相關焦點

  • Mybatis初始化過程簡單總結
    前面連續多篇文章都是在數據mybatis的初始化過程,目前基本完成,是時候做一個總結了。總覽首先回顧下最上層的測試代碼,實際上目前分析的還在測試代碼中與mybatis相關的第一步,具體如下圖:目前還在構建SqlSessionFactory這行代碼,這行代碼涉及了很多流程,前面也分析了很多,這裡把分析的主要流程總結如下圖:
  • Mybatis 動態sql 學習總結
    mybatis 的動態sql語句是基於OGNL表達式的。可以方便的在 sql 語句中實現某些邏輯.總體說來mybatis 動態SQL 語句主要有以下幾類:  1. if 語句 (簡單的條件判斷)  2. choose (when,otherwize) ,相當於java 語言中的 switch ,與 jstl 中的choose 很類似.
  • Mybatis_day01
    優化總結:我們總結一下上面對JDBC的優化和封裝:(1) 使用資料庫連接池對連接進行管理(2) SQL語句統一存放到配置文件(3) SQL語句變量和傳入參數的映射以及動態SQL(4) 動態SQL語句的處理(5) 對資料庫操作結果的映射和結果緩存(6) SQL語句的重複一.
  • mybatis源碼分析-反射基礎MetaClass
    WHAT我們知道mybatis是一個ORM(Object Relation Mapping)框架,既然是ORM框架,那麼資料庫與java的pojo之間的相互映射必然是其重要工作之一。WHYJDK已經為我們提供了所有反射的方法,那麼mybatis為什麼還要去二次封裝呢?
  • MyBatis-Plus為啥這麼牛?
    本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫前言大家有用過MyBatis-Plus(簡稱MP)的都知道它是一個MyBatis的增強工具,旨在MyBatis的基礎上只做增強不做改變
  • Mybatis【關聯映射】
    這時的連接即可以採用內連接,又可以採用外連接由於我們Mybatis中並沒有像Hibernate這樣全自動化的,因此我們是沒有<set>..DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="courseNamespace">    <resultMap type="cn.itcast.javaee.mybatis.many2many.Course
  • mybatis最全教程之JAVA API
    第一種方法是最常用的,它使用了一個參照了 XML 文檔或上面討論過的更特定的 mybatis-config.xml 文件的 Reader 實例。可選的參數是 environment 和 properties。environment 決定加載哪種環境,包括數據源和事務管理器。
  • Mybatis 中xml和註解映射,原來如此簡單
    DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.tian.mybatis.mapper.UserMapper"> <select id=
  • Mybatis【配置文件】
    UUID        <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">        <selectKey keyProperty="id" order="BEFORE" resultType="string">            select
  • Mybatis 強大的結果映射器ResultMap
    前言resultMap 元素是 MyBatis 中最重要最強大的元素。它可以讓你從 90% 的 JDBC ResultSets 數據提取代碼中解放出來,並在一些情形下允許你進行一些 JDBC 不支持的操作。實際上,在為一些比如連接的複雜語句編寫映射代碼的時候,一份 resultMap 能夠代替實現同等功能的數千行代碼。
  • 寫了10年的代碼,我最怕寫Mybatis這些配置,現在有詳解了
    1.1.3 輸入GroupId和ArtifactIdGroupId 填 com.homejim.mybatisArtifactId 填 mybatis-generator通過以上步驟, 一個普通的Maven項目就創建好了。
  • Mybatis的SqlSession創建過程詳解
    前面mybatis的初始化過程分析完成,接下來是第二步SqlSession的創建。創建過程總覽SqlSession創建過程如下圖:創建過程還是比較簡單的,首先是之前分析的SqlSessionFactory,在mybatis中提供了兩個SqlSessionFactory實現:SqlSessionManager和DefaultSqlSessionFactory
  • 看到Mybatis源碼就感到煩躁,怎麼辦?
    個人建議,以下基礎知識必須會一些:會設計模式:包括單例模式、工廠模式、代理模式、裝飾器模式、責任鏈模式、模板方法模式等。會猜測:大膽的猜測,在看源碼的時候,多站在高層次想想,如果你是Mybatis的設計者,你會怎麼設計?
  • MyBatis JPA Extra,MyBatis JPA 擴展 v2.2 發布
    ;import org.apache.mybatis.jpa.test.domain.Students;import org.apache.mybatis.jpa.util.WebContext;import
  • (四)Mybatis從入門到入土——別名、配置文件以及引入mapper
    mybatis也支持我們通過外部properties文件來配置一些屬性信息。    mybatis配置屬性信息有3種方式。如果3種方式如果我們都寫了,mybatis會怎麼走?    mybatis會先讀取方式1的配置,然後讀取方式2或者方式3的配置,會將1中相同的配置給覆蓋。
  • SpringBoot+Mybatis動態切換數據源
    -- 配置一個連接在池中最小生存的時間,單位是毫秒 -->     <property name="minEvictableIdleTimeMillis" value="${druid.minEvictableIdleTimeMillis}" />      <property name="validationQuery" value="select
  • 使用mybatis框架,完成增刪改查操作
    mybatis框架的繼續學習,安排如下:對昨天學習的內容做個小結,其中補充一個昨天忽視的問題。資料庫無外乎就是增刪改查,所以使用mybatis做一個完整的crud操作。一、mybatis使用步驟回顧主要是涉及到配置文件的編寫,其中又包含核心配置文件和映射文件。創建mybatis-config.xml核心配置文件。
  • Mybatis中mapper的xml解析詳解
    基礎介紹回顧下之前是在分析configuration的初始化過程,已經進行到了最後一步mapperElement(root.evalNode("mappers")),這個方法裡有兩種解析mapper的方法,一種是解析類,一種是解析xml文件,上一篇文章在講解析類中的註解,今天說到的就是解析xml
  • 深入理解 Mybatis 插件開發
    分頁功能mybatis的分頁默認是基於內存分頁的(查出所有,再截取),數據量大的情況下效率較低,不過使用mybatis插件可以改變該行為,只需要攔截StatementHandler類的prepare方法,改變要執行的SQL語句為分頁語句即可;公共欄位統一賦值一般業務系統都會有創建者,創建時間,修改者,修改時間四個欄位
  • mybatis框架之 resultMap 的高級應用
    各位小夥伴今天我們來了解resultMap 的高級應用mybatis 查詢多表資料庫表結構中存在的幾種多表關係:一對一 ,一對多, 多對一 ,多對多第二種方式:用 mybatis 的 resultMap 標籤返回創建一個Dept.Java