国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Mybatis學(xué)習(xí)筆記,包含mybatis基本使用、關(guān)系映射、動(dòng)態(tài)SQL、分頁插件等等

這篇具有很好參考價(jià)值的文章主要介紹了Mybatis學(xué)習(xí)筆記,包含mybatis基本使用、關(guān)系映射、動(dòng)態(tài)SQL、分頁插件等等。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

??????創(chuàng)作不易,各位看官點(diǎn)贊收藏.

MyBatis 學(xué)習(xí)筆記

簡(jiǎn)介:MyBatis 是一款優(yōu)秀的持久層框架,它支持自定義 SQL、存儲(chǔ)過程以及高級(jí)映射。MyBatis 免除了幾乎所有的 JDBC 代碼以及設(shè)置參數(shù)和獲取結(jié)果集的工作。MyBatis 可以通過簡(jiǎn)單的 XML 或注解來配置和映射原始類型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 對(duì)象)為數(shù)據(jù)庫中的記錄。簡(jiǎn)單來說,mybatis就是用來操作數(shù)據(jù)庫的,可以使程序猿更加容易書寫 dao 層。

1、Mybatis Demo 程序

搭建環(huán)境:導(dǎo)入依賴、創(chuàng)建數(shù)據(jù)庫表user(id,name,address)。

<!--    junit-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
</dependency>
<!--    mybatis-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.6</version>
</dependency>
<!--    數(shù)據(jù)庫連接-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.21</version>
</dependency>
<!--      log4j-->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.12</version>
</dependency>

編寫配置文件:mybatis-config.xml,XML 配置文件中包含了對(duì) MyBatis 系統(tǒng)的核心設(shè)置,包括獲取數(shù)據(jù)庫連接實(shí)例的數(shù)據(jù)源(DataSource)以及決定事務(wù)作用域和控制方式的事務(wù)管理器(TransactionManager)。

<?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">
<!--mybatis的主配置文件-->
<configuration>
    <!-- 數(shù)據(jù)庫配置環(huán)境-->
    <!-- default和下面的id名稱要一樣,默認(rèn)使用,可以定義多個(gè)環(huán)境-->
    <environments default="mysql">
        <!-- 配置mysql的環(huán)境-->
        <environment id="mysql">
            <!-- 配置事務(wù)類型為jdbc-->
            <transactionManager type="JDBC"/>
            <!--   配置數(shù)據(jù)池連接源-->
            <!--   type有三種類型
                        1、POOLED是使用數(shù)據(jù)庫連接池的類型
                        2、UNPOOLED是不適用數(shù)據(jù)庫連接池的類型
                        3、JNDI是JNDI類型的數(shù)據(jù)源 JndiDataSource
             -->
            <dataSource type="POOLED">
                <!-- 配置數(shù)據(jù)庫的4個(gè)基本信息-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///mybatis?characterEncoding=utf-8&amp;serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 引入映射文件-->
    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
    </mappers>
</configuration>

編寫 Mapper 接口:

public interface UserMapper {
    // 查詢所有的用戶
    List<User> findAllUser();
}

編寫 mapper.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會(huì)綁定一個(gè)mapper接口,可以理解為實(shí)現(xiàn)這個(gè)接口,必須寫全限定類名-->
<mapper namespace="com.jx.app.mybatis.mapper.UserMapper">
    <!--   id是接口中的方法名稱,resultType是實(shí)體的全限定類名,標(biāo)簽體中寫sql語句-->
    <select id="findAllUser" resultType="com.jx.app.mybatis.entity.User">
        select * from user
    </select>
</mapper>

編寫 Mybatis 工具類:

public class MybatisUtils {
    // 成員變量
    private static SqlSessionFactory sqlSessionFactory;
    // 靜態(tài)代碼初始化
    static {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // 獲取sqlSession
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

測(cè)試查詢結(jié)果:

@Test
public void test(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<User> users = mapper.findAllUser();
    System.out.println(users);
}

2、Mybatis 核心配置文件

environments:配置數(shù)據(jù)庫連接配置環(huán)境。

<!-- default和下面的id名稱要一樣,默認(rèn)使用,可以定義多個(gè)環(huán)境-->
<environments default="mysql">
    <!-- 配置mysql的環(huán)境,id是唯一標(biāo)識(shí)不能重復(fù)-->
    <environment id="mysql">
        <!-- 配置事務(wù)管理方式:JDBC(原生事務(wù))、MANAGED()-->
        <transactionManager type="JDBC"/>
        <!--   配置數(shù)據(jù)池連接源-->
        <!--   type有三種類型
                        1、POOLED是使用數(shù)據(jù)庫連接池的類型
                        2、UNPOOLED是不適用數(shù)據(jù)庫連接池的類型
                        3、JNDI使用上下文的數(shù)據(jù)源
         -->
        <dataSource type="POOLED">
            <!-- 配置數(shù)據(jù)庫的4個(gè)基本信息-->
            <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql:///mybatis?characterEncoding=utf-8&amp;serverTimezone=UTC"/>
            <property name="username" value="root"/>
            <property name="password" value="123456"/>
        </dataSource>
    </environment>
</environments>

propertes:可以引入 properties 文件,然后通過某種方式去訪問文件中的值。

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql:///mybatis?characterEncoding=utf-8&amp;serverTimezone=UTC
username=root
password=123456
<!-- 引入文件,然后可以在下面通過 ${key值} 獲取對(duì)應(yīng)的value-->
<properties resource="jdbc.properties"/>

settings:Mybatis 的全局配置,還有很多配置,可以去官網(wǎng)上查看。

<settings>
    <!-- 字段名與屬性名駝峰命名映射:user_name == userName-->
    <setting name="mapUnderscoreToCamelCase" value="true"/>
    <!-- 指定 mybatis 中的日志輸出-->
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

typeAliases:取別名標(biāo)簽,給實(shí)體類取一個(gè)別名,在映射結(jié)果時(shí)就可以使用別名就不再使用全限定類名。

<typeAliases>
    <!-- 在編寫 mapper 映射文件時(shí)就可以使用 User 來代替這個(gè)全限定類名,不設(shè)置 alias 別名就是類名-->
    <typeAlias type="com.jx.app.mybatis.entity.User" alias="User"/>
    
    <!-- 把指定包下的所有類都起別名,別名都是類名-->
    <package name="com.jx.app.mybatis.entity"/>
</typeAliases>

mappers:引入 mapper 映射文件。

<!-- 引入映射文件-->
<mappers>
    <!-- 需要引入 mapper 文件存放在 resources 目錄下-->
    <mapper resource="mapper/UserMapper.xml"/>

    <!-- 通過包名進(jìn)行引入:1、mapper 文件名需要與接口一樣,2、mapper 存放的目錄結(jié)構(gòu)也必須和接口保持一致-->
    <package name="com.jx.app.mybatis.mapper"/>
</mappers>

3、Mybatis Mapper 傳參映射

? 在 mapper 映射文件獲取接口的參數(shù)有兩種方式,${}#{}。

  • ${}: 本質(zhì)是字符串拼接,將參數(shù)與 SQL 語句進(jìn)行簡(jiǎn)單拼接,這種方式可能存在 SQL 注入問題,使用這種方式需要注意字符串的單引號(hào)拼接。
  • #{}:本質(zhì)是占位符方式來拼接 SQL,自動(dòng)給參數(shù)加上單引號(hào),這種方式防止 SQL 注入問題。

單個(gè)字面量參數(shù):

// 參數(shù) name 是單個(gè)字面量
User getUserByName(String name);
<select id="getUserByName" resultType="com.jx.app.mybatis.entity.User">
    SELECT *
    FROM user u
    WHERE u.user_name = #{name} 
    <!-- name參數(shù)需要和接口參數(shù)名保持一致-->
</select>

多個(gè)字面量參數(shù):

// 存在多個(gè)參數(shù)
User getUser(String id, String name);
<!-- 如果存在多個(gè)參數(shù),那么 mybatis 會(huì)把參數(shù)存儲(chǔ)在一個(gè) map 中,key:[arg0,arg1...,param1,param2...] 
     可以通過對(duì)應(yīng)的鍵獲取參數(shù)值,但是不能通過參數(shù)名去獲取,這兩種 key 可以混用,順序就是指定的下標(biāo)
-->
<select id="getUser" resultType="com.jx.app.mybatis.entity.User">
    SELECT *
    FROM user u
    <!-- WHERE u.id = #{arg0} AND u.user_name = #{arg1}-->
    WHERE u.id = #{param1} AND u.user_name = #{param2}
</select>

map 傳參:

// 參數(shù)是一個(gè)map
User getUserByMap(Map<String,String> map);
<!-- 參數(shù)是一個(gè) map,可以直接根據(jù) key 獲取對(duì)應(yīng)的值-->
<select id="getUserByMap" resultType="com.jx.app.mybatis.entity.User">
    SELECT *
    FROM user u
    WHERE u.id = #{id} AND u.user_name = #{username}
</select>

實(shí)體類傳參:

// 參數(shù)是一個(gè)是實(shí)體類
int insert(User user);
<!-- 參數(shù)是實(shí)體類,可以通過類的屬性名獲取對(duì)應(yīng)的屬性值-->
<insert id="insert">
    INSERT INTO user values(null,#{userName},#{password},#{money})
</insert>

@param 注解:可以命名參數(shù),標(biāo)識(shí)參數(shù)后依然后把參數(shù)放入 map 中,可以通過命名參數(shù)的 key 來獲取參數(shù)值。

// @Param 將參數(shù)進(jìn)行取別名命名
User getUser(@Param("id") String id, @Param("name") String name);
<!-- 使用 @param 注解后可以直接使用對(duì)應(yīng)的命名 key 獲取對(duì)應(yīng)的值-->
<select id="getUser" resultType="com.jx.app.mybatis.entity.User">
    SELECT *
    FROM user u
    WHERE u.id = #{id} AND u.user_name = #{name}
</select>

4、Mybatis 查詢結(jié)果

查詢結(jié)果為實(shí)體對(duì)象:

// 接口返回值為實(shí)體對(duì)象
User getUserByName(String name);
<!-- resultType:屬性需要指定返回值的全限定類名或者是別名-->
<select id="getUserByName" resultType="com.jx.app.mybatis.entity.User">
    SELECT *
    FROM user u
    WHERE u.user_name = #{name}
</select>

注意:返回值是一個(gè)實(shí)體類對(duì)象時(shí),返回結(jié)果只能是一條數(shù)據(jù)或者 null,如果查詢出來是多條數(shù)據(jù)就會(huì)報(bào)錯(cuò)。

查詢結(jié)果為集合:

// 接口返回值為集合類型,并指定對(duì)應(yīng)泛型
List<User> getUserByName(@Param("name") String name);
<!-- resultType:需要指定集合中泛型對(duì)應(yīng)類的全限定類名或者別名-->
<select id="getUserByName" resultType="com.jx.app.mybatis.entity.User">
    SELECT * FROM user u
</select>

注意:如果查詢出來一條或多條結(jié)果就會(huì)封裝到集合中,如果沒有結(jié)果就會(huì)返回空集合但是不會(huì)返回 null。

查詢結(jié)果為 map 集合:

// 接口返回值是map類型
Map<String,Object> getUserToMap();
<!-- 將查詢的接口以字段名為key,然后字段值為 value 的 map-->
<select id="getUserToMap" resultType="java.util.Map">
    SELECT * FROM user u
</select>

注意:查詢結(jié)果為 map 只能查詢一條數(shù)據(jù),查詢出多條就會(huì)報(bào)錯(cuò),而且如果某個(gè)字段是 null,這個(gè)字段不會(huì)封裝到 map 中。

多條結(jié)果封裝成 map:

/**
 * 如果查詢多條數(shù)據(jù)也想封裝成 map,@MapKey 可以指定查詢出來那個(gè)字段可以作為 key,
 * 然后這一條數(shù)據(jù)又會(huì)封裝成一個(gè) map 作為 value 存儲(chǔ)進(jìn)去
*/
@MapKey("id")
Map<String, Map<String,Object>> getUserToMap();

獲取自增主鍵:在插入數(shù)據(jù)時(shí),可以獲取插入數(shù)據(jù)后對(duì)應(yīng)的自動(dòng)遞增的 id。

// 插入元素
int insert(User user);
<!-- 
    useGeneratedKeys:設(shè)置是否能夠獲取到自增主鍵
    keyProperty:獲取到的主鍵的值存儲(chǔ)到參數(shù)實(shí)體的哪個(gè)屬性
-->
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO user values(null,#{userName},#{password},#{money})
</insert>

resultMap 字段關(guān)系映射:查詢出來的結(jié)果與實(shí)體類上的字段名稱不一致,我們就需要通過 resultMap 屬性去自定義映射關(guān)系。

方式一:字段起別名,可以在 SQL 語句中把字段名通過起別名方式與屬性名一一對(duì)應(yīng)。

方式二:使用 resultMap 映射,將查詢出來字段名與對(duì)象屬性名進(jìn)行一個(gè)自定義映射。

<!-- 設(shè)置返回值類型為 resultMap,并且創(chuàng)建一個(gè)映射-->
<select id="getUserList" resultMap="UserListMap">
    SELECT * FROM user u
</select>

<!-- 關(guān)系映射,id屬性:需要和映射返回值相同,type屬性:就是映射的實(shí)體對(duì)象類型-->
<!-- id:數(shù)據(jù)庫主鍵字段,result:普通字段。
       column屬性:查詢數(shù)據(jù)庫對(duì)應(yīng)字段名,property屬性:需要映射的屬性名稱。
 -->
<resultMap id="UserListMap" type="com.jx.app.mybatis.entity.User">
    <id column="id" property="id"/>
    <result column="user_name" property="userName"/>
    <result column="password" property="password"/>
    <result column="money" property="money"/>
</resultMap>

注意:如果查詢出來字段名與屬性名對(duì)應(yīng)不上,不會(huì)報(bào)錯(cuò),只是他們對(duì)應(yīng)屬性值都是對(duì)象默認(rèn)值。

5、Mybatis 關(guān)系映射處理

兩個(gè)實(shí)體:Student 和 Teacher,一個(gè)學(xué)生有一個(gè)老師,一個(gè)老師有多個(gè)學(xué)生。

@Data
public class Student {
    private String id;
    private String studentName;
    private Teacher teacher;
}
@Data
public class Teacher {
    private String id;
    private String teacherName;
    private List<Student> students;
}

5.1、多對(duì)一關(guān)系映射處理

方式一:使用連接查詢查詢對(duì)學(xué)生對(duì)應(yīng)的老師信息,然后使用級(jí)聯(lián)屬性映射。

<!-- 使用連接查詢獲取學(xué)生信息以及老師信息-->
<select id="getStudentById" resultMap="StudentMap">
    SELECT * FROM student s
    LEFT JOIN teacher t ON s.t_id = t.id
    WHERE s.id = #{id}
</select>

<!-- 使用級(jí)聯(lián)方式進(jìn)行屬性映射-->
<resultMap id="StudentMap" type="com.jx.app.mybatis.entity.Student">
    <id column="id" property="id"/>
    <result column="student_name" property="studentName"/>
    <result column="t_id" property="teacher.id"/>
    <result column="teacher_name" property="teacher.teacherName"/>
</resultMap>

方式二:使用連接查詢查詢對(duì)學(xué)生對(duì)應(yīng)的老師信息,然后通過 resultMap 進(jìn)行關(guān)系映射。

<!-- 使用連接查詢獲取學(xué)生信息以及老師信息-->
<select id="getStudentById" resultMap="StudentMap">
    SELECT * FROM student s
    LEFT JOIN teacher t ON s.t_id = t.id
    WHERE s.id = #{id}
</select>

<!-- 使用 association 關(guān)系映射-->
<resultMap id="StudentMap" type="com.jx.app.mybatis.entity.Student">
    <id column="id" property="id"/>
    <result column="student_name" property="studentName"/>
    <!-- property:需要映射的屬性名,javaType:這個(gè)屬性的 java 類型是什么-->
    <association property="teacher" javaType="com.jx.app.mybatis.entity.Teacher">
        <id column="t_id" property="id"/>
        <result column="teacher_name" property="teacherName"/>
    </association>
</resultMap>

方式三:通過子查詢?nèi)ゲ樵兝蠋熜畔?,然后通過 resultMap 進(jìn)行關(guān)系映射。

<!-- 先獲取學(xué)生信息-->
<select id="getStudentById" resultMap="StudentMap">
    SELECT * from student WHERE id = #{id}
</select>

<resultMap id="StudentMap" type="com.jx.app.mybatis.entity.Student">
    <id property="id" column="id"/>
    <result property="studentName" column="student_name"/>
    <!-- select:子查詢的唯一標(biāo)識(shí)(命名空間+id),column:給子查詢的查詢參數(shù)-->
    <association property="teacher" select="com.jx.app.mybatis.mapper.UserMapper.getTeacher" column="t_id"/>
</resultMap>

<!-- 子查詢-->
<select id="getTeacher" resultType="com.jx.app.mybatis.entity.Teacher">
    SELECT * from teacher where id = #{t_id}
</select>

注意:子查詢有一個(gè)好處就是可以設(shè)置關(guān)聯(lián)對(duì)象的延遲加載,只有在使用到延遲對(duì)象時(shí)才會(huì)去執(zhí)行對(duì)應(yīng)的子查詢 SQL 語句然后返回結(jié)果。

  • 需要開啟 mybatis 的全局懶加載設(shè)置,<setting name="lazyLoadingEnabled" value="true"/>
  • association 有一個(gè) fetchType 屬性手動(dòng)控制懶加載,值有 lazy(懶加載)、eager(立即加載),如果不設(shè)置這個(gè)屬性默認(rèn)是懶加載。

5.2、一對(duì)多關(guān)系映射處理

方式一:通過連接查詢出老師對(duì)應(yīng)的所有學(xué)生信息,然后通過 resultMap 進(jìn)行關(guān)系映射。

<!-- 連接查詢-->
<select id="getTeacherById" resultMap="TeacherMap">
    SELECT * FROM teacher t
    LEFT JOIN student s ON t.id = s.t_id
    WHERE t.id = #{id}
</select>

<resultMap id="TeacherMap" type="com.jx.app.mybatis.entity.Teacher">
    <id property="id" column="id"/>
    <result property="teacherName" column="teacher_name"/>
     <!-- 查詢出來學(xué)生信息進(jìn)行集合映射,ofType:集合泛型中的屬性-->
    <collection property="students" ofType="com.jx.app.mybatis.entity.Student">
        <id property="id" column="s_id"/>
        <result property="studentName" column="student_name"/>
    </collection>
</resultMap>

方式二:分步查詢老師信息和學(xué)生信息,然后通過 resultMap 映射關(guān)聯(lián)。

<select id="getTeacherById" resultMap="TeacherMap">
    SELECT * FROM teacher t
    WHERE t.id = #{id}
</select>

<resultMap id="TeacherMap" type="com.jx.app.mybatis.entity.Teacher">
    <id property="id" column="id"/>
    <result property="teacherName" column="teacher_name"/>
    <!-- 查詢出來學(xué)生信息進(jìn)行集合映射,ofType:集合泛型中的屬性-->
    <collection property="students" ofType="com.jx.app.mybatis.entity.Student"
            select="com.jx.app.mybatis.mapper.UserMapper.getStudent"
            column="id">
    </collection>
</resultMap>

<select id="getStudent" resultType="com.jx.app.mybatis.entity.Student">
    select * from student where t_id = #{tid}
</select> 

6、Mybatis 動(dòng)態(tài) SQL

? 根根據(jù)特定的條件動(dòng)態(tài)拼接 SQL 語句的功能,它就是解決在拼接 SQL 時(shí)字符串問題。

if 標(biāo)簽:會(huì)根據(jù)標(biāo)簽的 test 屬性對(duì)應(yīng)表達(dá)式返回 true 或者 false 決定是否拼接到 SQL 語句中。

// 使用 if 進(jìn)行多條件查詢
List<User> DynamicSQL(User user);
<select id="DynamicSQL" resultType="com.jx.app.mybatis.entity.User">
    select * from user 
    where 1=1
    <!-- 如果查詢條件有 username 就會(huì)在 SQL 中進(jìn)行拼接-->
    <if test="userName != null and userName != ''">
        and user_name = #{userName}
    </if>
    <if test="money != null and money != ''">
        and money = #{money}
    </if>
</select>

where 標(biāo)簽:動(dòng)態(tài)生成 where 條件語句,根據(jù)拼接 SQL 在前面添加或去掉 and、or 關(guān)鍵字,如果沒有條件就不會(huì)有 where 關(guān)鍵字。

<select id="DynamicSQL" resultType="com.jx.app.mybatis.entity.User">
    select * from user
    <!-- 會(huì)動(dòng)態(tài)生成 where 關(guān)鍵字,并且去除或添加開頭的 and、or 關(guān)鍵字-->
    <where>
        <!-- 如果查詢條件有 username 就會(huì)在 SQL 中進(jìn)行拼接-->
        <if test="userName != null and userName != ''">
            and user_name = #{userName}
        </if>
        <if test="money != null and money != ''">
            or money = #{money}
        </if>
    </where>
</select>

trim 標(biāo)簽:如果拼接 SQL 字符串有內(nèi)容可以在內(nèi)容前后添加內(nèi)容,如果沒有內(nèi)容也沒有任何效果。

<select id="DynamicSQL" resultType="com.jx.app.mybatis.entity.User">
    select * from user
    <!--
        prefix|suffix:在內(nèi)容的前面|后面添加指定內(nèi)容
        prefixOverrides|suffixOverrides:在內(nèi)容的前面|后面去掉指定內(nèi)容
    -->
    <trim prefix="where" suffix="" prefixOverrides="and|or" suffixOverrides="">
            <if test="userName != null and userName != ''">
                and user_name = #{userName}
            </if>
            <if test="money != null and money != ''">
                or money = #{money}
            </if>
    </trim>
</select>

chose…when…otherwise 標(biāo)簽:相當(dāng)于 if…eles if…else,指定條件選擇一個(gè)進(jìn)行執(zhí)行,其它內(nèi)容不執(zhí)行。

<select id="DynamicSQL" resultType="com.jx.app.mybatis.entity.User">
    select * from user
    <where>
        <!-- 只選擇一個(gè)條件進(jìn)行執(zhí)行,如果 when 都不滿足則執(zhí)行 otherwise 中的內(nèi)容-->
        <choose>
            <when test="userName != null and userName != ''">
                user_name = #{userName}
            </when>
            <when test="money != null and money != ''">
                money = #{money}
            </when>
            <otherwise>
                id = #{id}
            </otherwise>
        </choose>
    </where>
</select>

注意:這個(gè)條件選擇執(zhí)行只會(huì)滿足一個(gè),要么是 when 中的一個(gè)要么就是 otherwise。

foreach 標(biāo)簽:如果參數(shù)是集合類型,可以通過標(biāo)簽遍歷集合中內(nèi)容,例如進(jìn)行批量刪除、增加等操作。

// 批量刪除
int deleteBatch(@Param("ids") List<String> ids);
<delete id="deleteBatch">
    delete from user
    <where>
        id in
        <!-- collection:操作的集合參數(shù),item:遍歷出來的每個(gè)元素,open:指定開始內(nèi)容,
                 close:指定結(jié)束內(nèi)容,index:遍歷到的下標(biāo),separator:指定每個(gè)元素之間的分隔符
            -->
        <foreach collection="ids" item="id" close=")" open="(" separator="," index="i">
            #{id}
        </foreach>
    </where>
</delete>

sql 標(biāo)簽:對(duì)常用的 SQL 語句進(jìn)行一個(gè)抽取,如果在其它地方使用直接引用。

<!-- id:唯一標(biāo)識(shí) sql 標(biāo)簽,在引用時(shí)通過 id 引入-->
<sql id="CommonSQL">
    id,user_name,password,money
</sql>

<!-- 通過 include 標(biāo)簽進(jìn)行引入動(dòng)態(tài)的 sql-->
<select id="selectAll" resultType="com.jx.app.mybatis.entity.User">
    select <include refid="CommonSQL"/> from user
</select>

7、Mybatis 緩存

一級(jí)緩存:這個(gè)級(jí)別緩存是 SqlSession 級(jí)別的緩存,通過同一個(gè) SqlSession 對(duì)象去查詢數(shù)據(jù),那么在第二次查詢就會(huì)去緩存中獲取而不會(huì)去查詢數(shù)據(jù)庫,這種緩存是默認(rèn)開啟的。

@Test
public void test4(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();

    UserMapper userMapper1 = sqlSession.getMapper(UserMapper.class);
    List<User> allUser1 = userMapper1.findAllUser();
    System.out.println(allUser1);

    // 即使是不同 mapper 對(duì)象,但是是同一個(gè) sqlSession,那么第二次就會(huì)去緩存中取數(shù)據(jù)
    UserMapper userMapper2 = sqlSession.getMapper(UserMapper.class);
    List<User> allUser2 = userMapper2.findAllUser();
    System.out.println(allUser2);
}

一級(jí)緩存失效:

  • 使用不同的 SqlSession 進(jìn)行查詢數(shù)據(jù)。
  • 同一個(gè) SqlSession 但是查詢條件不同。
  • 同一個(gè) SqlSession 的兩次查詢之間執(zhí)行了其它的增、刪、改等操作。
  • 同一個(gè) SqlSession 的兩次查詢之間手動(dòng)清空了緩存。
// 手動(dòng)清空緩存
sqlSession.clearCache();

二級(jí)緩存:二級(jí)緩存是 SqlSessionFactory 級(jí)別的緩存,通過同一個(gè) SqlSessionFactory 創(chuàng)建的 SqlSession 去查詢結(jié)果會(huì)被緩存,那么第二次去執(zhí)行相同查詢就會(huì)去緩存中查詢,二級(jí)緩存需要手動(dòng)開啟。

  • 需要在 mybatis 核心配置文件中開啟緩存。
<settings>
    <!-- 開啟全局緩存,默認(rèn)是開啟的-->
    <setting name="cacheEnabled" value="true"/>
</settings>
  • 在 mapper 映射文件中開啟緩存。
<!-- 開啟緩存-->
<cache />
@Test
public void test5(){
    SqlSession sqlSession1 = MybatisUtils.getSqlSession();
    SqlSession sqlSession2 = MybatisUtils.getSqlSession();

    UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
    List<User> users1 = mapper1.selectAll();
    System.out.println(users1);
    sqlSession1.commit();

    // 同一個(gè) SqlSessionFactory 獲取的不同 SqlSession 查詢結(jié)果會(huì)被緩存
    UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
    List<User> users2 = mapper2.selectAll();
    System.out.println(users2);
}

注意事項(xiàng):

  • 必須是同一個(gè) SqlSessionFactory 的 SqlSession 的二級(jí)緩存才會(huì)生效。
  • 只有每一個(gè)將 SqlSession 查詢后提交或者關(guān)閉,數(shù)據(jù)才會(huì)被緩存。
  • 查詢的結(jié)果對(duì)象必須實(shí)現(xiàn)序列化,不然使用緩存會(huì)報(bào)錯(cuò)。
  • 兩次相同查詢之間,執(zhí)行了增、刪、改操作,一級(jí)緩存、二級(jí)緩存都會(huì)失效。

Mybatis學(xué)習(xí)筆記,包含mybatis基本使用、關(guān)系映射、動(dòng)態(tài)SQL、分頁插件等等,mybatis,學(xué)習(xí),筆記

二級(jí)緩存相關(guān)設(shè)置:在 mapper 映射文件中的 cache 標(biāo)簽可以設(shè)置以下屬性。

<!-- 相關(guān)設(shè)置:
           eviction(緩存回收策略)=LRU(最近最少使用,默認(rèn)值) | FIFO(先進(jìn)先出)
           flushInterval:緩存刷新時(shí)間,單位秒,不設(shè)置就是不刷新就只有執(zhí)行增刪改語句才會(huì)刷新
           size:緩存對(duì)象數(shù)目,防止內(nèi)存溢出
           readOnly(是否只讀)=true(緩存返回是同一個(gè)對(duì)象,且這個(gè)對(duì)象不能修改,修改會(huì)報(bào)錯(cuò)) 
                            false(返回的緩存中的一個(gè)拷貝對(duì)象,這個(gè)對(duì)象可以修改,默認(rèn)值)
-->
<cache eviction="LRU" flushInterval="1000" size="10" readOnly="false"/>

Mybatis 緩存查詢順序:

  • 先查詢二級(jí)緩存,二級(jí)緩存的范圍比一級(jí)緩存大一些。
  • 如果二級(jí)緩存沒有命中就回去查詢一級(jí)緩存。
  • 如果一級(jí)緩存也沒有命中,就會(huì)去查詢數(shù)據(jù)庫。
  • SqlSession 關(guān)閉后,會(huì)將一級(jí)緩存的數(shù)據(jù)寫入二級(jí)緩存。

第三方緩存工具 EHCache:

  • 導(dǎo)入依賴:
<!-- ehcache和mybatis整合包-->
<dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.2.1</version>
</dependency>
  • 編寫 ehcache 配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
        updateCheck="false">
    <!--
    diskStore:為緩存路徑,ehcache分為內(nèi)存和磁盤兩級(jí),
    此屬性定義磁盤的緩存位 置。
    參數(shù)解釋如下:
    user.home – 用戶主目錄
    user.dir – 用戶當(dāng)前工作目錄
    java.io.tmpdir – 默認(rèn)臨時(shí)文件路徑
    -->
    <diskStore path="E:\ehcache"/>
    <defaultCache
            eternal="false"
            maxElementsInMemory="10000"
            overflowToDisk="true"
            diskPersistent="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="259200"
            memoryStoreEvictionPolicy="LRU"/>
    <cache
            name="cloud_user"
            eternal="false"
            maxElementsInMemory="5000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="1800"
            memoryStoreEvictionPolicy="LRU"/>
    <!--name:緩存名稱。
    maxElementsInMemory:緩存最大數(shù)目
    maxElementsOnDisk:硬盤最大緩存?zhèn)€數(shù)。
    eternal:對(duì)象是否永久有效,一但設(shè)置了,timeout將不起作用。
    overflowToDisk:是否保存到磁盤,當(dāng)系統(tǒng)當(dāng)機(jī)時(shí)
    timeToIdleSeconds:設(shè)置對(duì)象在失效前的允許閑置時(shí)間(單位:秒)。 僅當(dāng) eternal=false對(duì)象不是永久有效時(shí)使用,可選屬性,默認(rèn)值是0,也就是可閑置時(shí)間無窮大。
    timeToLiveSeconds:設(shè)置對(duì)象在失效前允許存活時(shí)間(單位:秒)。最大時(shí)間介于創(chuàng)建 時(shí)間和失效時(shí)間之間。僅當(dāng)eternal=false對(duì)象不是永久有效時(shí)使用,默認(rèn)是0.,也就是對(duì)象存 活時(shí)間無窮大。
    diskPersistent:是否緩存虛擬機(jī)重啟期數(shù)據(jù) Whether the disk store persists between restarts of the Virtual Machine. The default value is false.diskSpoolBufferSizeMB:這個(gè)參數(shù)設(shè)置DiskStore(磁盤緩存)的緩存區(qū)大小。默 認(rèn)是30MB。每個(gè)Cache都應(yīng)該有自己的一個(gè)緩沖區(qū)。
    diskExpiryThreadIntervalSeconds:磁盤失效線程運(yùn)行時(shí)間間隔,默認(rèn)是120秒。
    memoryStoreEvictionPolicy:當(dāng)達(dá)到maxElementsInMemory限制時(shí),Ehcache將 會(huì)根據(jù)指定的策略去清理內(nèi)存。
    默認(rèn)策略是LRU(最近最少使用)。你可以設(shè)置為FIFO(先進(jìn)先 出)或是LFU(較少使用)。
    clearOnFlush:內(nèi)存數(shù)量最大時(shí)是否清除。 memoryStoreEvictionPolicy:
    可選策略有:
    LRU(最近最少使用,默認(rèn)策略)、
    FIFO(先進(jìn)先出)、
    LFU(最少訪問次數(shù))。
    FIFO,first in first out,這個(gè)是大家最熟的,先進(jìn)先出。
    LFU, Less Frequently Used,就是上面例子中使用的策略,直白一點(diǎn)就是講一直以 來最少被使用的。如上面所講,緩存的元素有一個(gè)hit屬性,hit值最小的將會(huì)被清出緩存。 L'
    RU,Least Recently Used,最近最少使用的,緩存的元素有一個(gè)時(shí)間戳,當(dāng)緩存容 量滿了,而又需要騰出地方來緩存新的元素的時(shí)候,那么現(xiàn)有緩存元素中時(shí)間戳離當(dāng)前時(shí)間最遠(yuǎn)的 元素將被清出緩存。 -->
</ehcache>
  • 使用三方緩存工具:在 mapper 映射文件中修改。
<!-- type:指定緩存類型,不指定就是使用 mybatis 的緩存-->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

8、Mybatis 分頁插件

導(dǎo)入依賴:

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.3.3</version>
</dependency>

設(shè)置 mybatis 插件:

<plugins>
    <!-- 設(shè)置分頁插件攔截器-->
    <plugin interceptor="com.github.pagehelper.PageInterceptor"/>
</plugins>

使用方式:文章來源地址http://www.zghlxwxcb.cn/news/detail-613762.html

@Test
public void test6(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    // 開啟分頁,在下一個(gè)查詢語句會(huì)進(jìn)行分頁攔截,參數(shù)一:頁碼,參數(shù)二:一頁數(shù)量
    PageHelper.startPage(1,5);

    List<User> users2 = mapper.selectAll();
    
    // 參數(shù)是查詢后的 list 結(jié)果
    PageInfo<User> pageInfo = new PageInfo<>(users2);

    System.out.println(pageInfo.getList());
}

到了這里,關(guān)于Mybatis學(xué)習(xí)筆記,包含mybatis基本使用、關(guān)系映射、動(dòng)態(tài)SQL、分頁插件等等的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【MyBatis】自定義resultMap三種映射關(guān)系

    【MyBatis】自定義resultMap三種映射關(guān)系

    目錄 一、一對(duì)一映射(One-to-One) 1.1 表關(guān)系 1.2?resultMap設(shè)置自定義映射? 二、一對(duì)多映射(One-to-Many) 2.1 創(chuàng)建實(shí)體 2.2?級(jí)聯(lián)方式處理映射關(guān)系 2.3 定義SQL 2.4 OrderMapper接口 2.5 編寫業(yè)務(wù)邏輯層 2.6 Junit測(cè)試 三、多對(duì)多映射(Many-to-Many) 3.1 表關(guān)系 3.2 創(chuàng)建實(shí)體 3.3?處理映射關(guān)系、

    2024年02月10日
    瀏覽(20)
  • 認(rèn)識(shí)Mybatis的關(guān)聯(lián)關(guān)系映射,靈活關(guān)聯(lián)表對(duì)象之間的關(guān)系

    認(rèn)識(shí)Mybatis的關(guān)聯(lián)關(guān)系映射,靈活關(guān)聯(lián)表對(duì)象之間的關(guān)系

    目錄 ? ?? 一、概述 ( 1?)? 介紹 ( 2 )??關(guān)聯(lián)關(guān)系映射 ( 3 ) 關(guān)聯(lián)講述 二、一對(duì)一關(guān)聯(lián)映射 2.1 數(shù)據(jù)庫創(chuàng)建 2.2 配置文件? 2.3 代碼生成 2.4 編寫測(cè)試 三、一對(duì)多關(guān)聯(lián)映射 四?、多對(duì)多關(guān)聯(lián)映射 給我們帶來的收獲 關(guān)聯(lián)關(guān)系映射是指在數(shù)據(jù)庫中,通過定義 表之間的關(guān)聯(lián)關(guān)系 ,將多

    2024年02月11日
    瀏覽(19)
  • 如何在MyBatis中處理復(fù)雜結(jié)果集映射關(guān)系

    如何在MyBatis中處理復(fù)雜結(jié)果集映射關(guān)系

    在開發(fā)中,我們不是總是對(duì)單表進(jìn)行操作的場(chǎng)景。按照數(shù)據(jù)庫表的設(shè)計(jì)原則,要符合一定的范式,那么就需要對(duì)某一種場(chǎng)景的表進(jìn)行拆分。 在業(yè)務(wù)上,可能是屬于同一個(gè)業(yè)務(wù)。但是,在數(shù)據(jù)庫中表的存儲(chǔ)這塊,可能就會(huì)涉及到表的拆分。 這里設(shè)計(jì)到表的創(chuàng)建直接創(chuàng)建兩張表

    2024年02月05日
    瀏覽(26)
  • Mybatis的三種映射關(guān)系以及聯(lián)表查詢

    目錄 一、概念 二、一對(duì)一 1、配置generatorConfig.xml 2、Vo包的編寫 3、xml的sql編寫 4、編寫對(duì)應(yīng)接口及實(shí)現(xiàn)類 5、測(cè)試 三、一對(duì)多 1、Vo包類的編寫 2、xml的sql編寫 3、編寫對(duì)應(yīng)接口及實(shí)現(xiàn)類 4、測(cè)試 四、多對(duì)多 1、Vo類 2、xml的sql配置 3、接口及接口實(shí)現(xiàn)類 4、測(cè)試 1、MyBatis中表之間

    2024年02月10日
    瀏覽(25)
  • MyBatis注解開發(fā)---實(shí)現(xiàn)自定義映射關(guān)系和關(guān)聯(lián)查詢

    目錄 相關(guān)導(dǎo)讀 一、使用注解實(shí)現(xiàn)自定義映射關(guān)系 1. 編寫注解方法 2. 編寫測(cè)試方法

    2023年04月09日
    瀏覽(16)
  • MyBatis中至關(guān)重要的關(guān)系映射----全方面介紹

    MyBatis中至關(guān)重要的關(guān)系映射----全方面介紹

    目錄 一 對(duì)于映射的概念 1.1 三種關(guān)系映射 1.2 resultType與resultMap的區(qū)別 resultType: resultMap: 二,一對(duì)一關(guān)聯(lián)查詢 2.1 嵌套結(jié)果集編寫 2.2 案例演示 三,一對(duì)多關(guān)聯(lián)查詢 3.1 嵌套結(jié)果集編寫 ?3.3?案例演示 四,多對(duì)多關(guān)聯(lián)查詢? 4.1?嵌套結(jié)果集編寫 ?4.2?案例演示 ? ? ?在關(guān)系型數(shù)

    2024年02月09日
    瀏覽(24)
  • MyBatis 的關(guān)聯(lián)關(guān)系配置 一對(duì)多,一對(duì)一,多對(duì)多 關(guān)系的映射處理

    MyBatis 的關(guān)聯(lián)關(guān)系配置 一對(duì)多,一對(duì)一,多對(duì)多 關(guān)系的映射處理

    目錄 一.關(guān)聯(lián)關(guān)系配置的好處 ?二.?導(dǎo)入數(shù)據(jù)庫表: ?三.? ? 一對(duì)多關(guān)系:--? ? 一個(gè)訂單對(duì)應(yīng)多個(gè)訂單項(xiàng)? ? ? ? 四.一對(duì)一關(guān)系:---一個(gè)訂單項(xiàng)對(duì)應(yīng)一個(gè)訂單 五.多對(duì)多關(guān)系(兩個(gè)一對(duì)多) ?????????MyBatis是一個(gè)Java持久化框架,可以 通過XML或注解的方式 將對(duì)象與數(shù)據(jù)庫

    2024年02月11日
    瀏覽(26)
  • 【Mybatis】深入學(xué)習(xí)MyBatis:概述、主要特性以及配置與映射

    【Mybatis】深入學(xué)習(xí)MyBatis:概述、主要特性以及配置與映射

    ?? 個(gè)人博客: 個(gè)人主頁 ?? 個(gè)人專欄: ? Mybatis? ? ???? 功不唐捐,玉汝于成 目錄 前言 正文 一、概述 MyBatis簡(jiǎn)介 主要特性 1.?動(dòng)態(tài)SQL 2.結(jié)果映射 3 .插件機(jī)制 二、MyBatis配置文件 1.配置文件結(jié)構(gòu) 數(shù)據(jù)庫連接信息 全局配置 映射器掃描 2.SQL映射文件 SQL語句定義 參數(shù)映射和

    2024年02月04日
    瀏覽(28)
  • MyBatis的使用(XML映射文件)

    MyBatis基于注解開發(fā)簡(jiǎn)單便捷,但是弊端是失去SQL語句的靈活性,不能根據(jù)實(shí)際情況產(chǎn)生不同的SQL語句 MyBatis除了支持注解開發(fā)以外,還支持一種開發(fā)方式:XML映射文件,將SQL語句寫到XML映射文件中,基于更多種的選擇可以讓SQL變得更加靈活 1.開發(fā)方式 1.和基于注解開發(fā)方式一

    2024年02月08日
    瀏覽(26)
  • Mybatis使用collection映射一對(duì)多查詢分頁問題

    Mybatis使用collection映射一對(duì)多查詢分頁問題

    場(chǎng)景:頁面展示列表,需要查詢多的字段,和一的字段。并且還要分頁。 這時(shí)候直接想到的是手寫sql。 原來的sql 。 正常查詢tags有兩條。加上分頁條件,多的一端只有一條數(shù)據(jù)。 修改之后的sq。滿足分頁正常展示多的一端。

    2024年02月15日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包