主頁 > 後端開發 > Mybatis

Mybatis

2020-09-24 05:35:27 後端開發

1.什么是 MyBatis?

  • MyBatis 是一款優秀的持久層框架(持久層,可以理解成資料 保存在 資料庫或者 硬碟一類可以保存很長時間的設備里面).
  • 它支持自定義 SQL、存盤程序以及高級映射,
  • MyBatis 免除了幾乎所有的 JDBC 代碼以及設定引數和獲取結果集的作業,MyBatis 可以通過簡單的 XML 或注解來配置和映射原始型別、介面和 Java POJO(Plain Old Java Objects,普通老式 Java 物件)為資料庫中的記錄,

1.2 持久化

記憶體:斷電即失

所以持久化 能把資料保存在磁盤上面

1.3 持久層

完成持久化作業的代碼塊

1.4 為什么要用Mybatis

JDBC代碼太復雜,框架更簡單

  • 簡單易學:
  • 靈活:
  • 解除sql與程式代碼的耦合:通過提供DAO層,將業務邏輯和資料訪問邏輯分離,使系統的設計更清晰,更易維護,更易單元測驗,sql和代碼的分離,提高了可維護性,
  • 提供映射標簽,支持物件與資料庫的orm欄位關系映射
  • 提供物件關系映射標簽,支持物件關系組建維護
  • 提供xml標簽,支持撰寫動態sql,

2.第一個Mybatis程式

思想

2.1搭建資料庫

use mybatis;
CREATE TABLE user(

	id INT PRIMARY KEY,
	name VARCHAR(20),
	pwd VARCHAR(20)
	
)ENGINE=INNODB DEFAULT charset=utf8;

INSERT INTO `user`(NAME,pwd) VALUES
("chen1","123456"),
("chen2","123456"),
("chen3","123456")

2.2 配置mybatis

1.mybatis組態檔 mybatis-config.xml

作用: SqlSessionFactoryBuilder 則可以從 XML 組態檔或一個預先配置的 Configuration 實體來構建出 SqlSessionFactory 實體,

<?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="https://www.cnblogs.com/firsthelloworld/p/${driver}"/>
        <property name="url" value="https://www.cnblogs.com/firsthelloworld/p/${url}"/>
        <property name="username" value="https://www.cnblogs.com/firsthelloworld/p/${username}"/>
        <property name="password" value="https://www.cnblogs.com/firsthelloworld/p/${password}"/>
      </dataSource>
    </environment>
  </environments>
    -----------注冊-------------
  <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>

2.構建sqlSessionFactory物件

作用:獲取SqlSession物件(SqlSession 提供了在資料庫執行 SQL 命令所需的所有方法,你可以通過 SqlSession 實體來直接執行已映射的 SQL 陳述句)

public class SqlSeeionUtils {

    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
   public static SqlSessionFactory getSqlSessionFactory(){
        return sqlSessionFactory;
    }
}

public class UserDaoTest {

    @Test
   public void test1(){
        SqlSessionFactory sqlSessionFactory = SqlSeeionUtils.getSqlSessionFactory();
       //獲得sqlSession物件
        SqlSession sqlSession = sqlSessionFactory.openSession();
       //sqlSession物件 獲得數操作SQL陳述句操作物件 Mapper
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> allUsers = mapper.getAllUsers();
        for (User allUser : allUsers) {
            System.out.println(allUser);
        }
    }

}

4.SqlSession物件

  • 增刪改 必須需要事務,默認自動提交事務關閉的,需要在sqlSessionFactory.openSession(true);開啟

    ? sqlSession.commit();

5.映射器.xml檔案和 dao介面

通過 id = dao介面方法名 和 namespace 連接起來

<mapper namespace="com.cb.dao.UserDao">
    <select id="getAllUsers" resultType="com.cb.pojo.User">
    select * from user
  </select>
</mapper>

3.xml組態檔

  • configuration(配置)
    • properties(屬性)
    • ? settings(設定)
    • ? typeAliases(型別別名)
    • ? typeHandlers(型別處理器)
    • ? objectFactory(物件工廠)
    • ? plugins(插件)
    • ? environments(環境配置)
      • ? environment(環境變數)
      • ? transactionManager(事務管理器)
      • ? dataSource(資料源)
    • ? databaseIdProvider(資料庫廠商標識)
    • ? mappers(映射器)

environments(環境配置)

<environments default="development">
  <environment id="development">
    <transactionManager type="JDBC">
      <property name="..." value="https://www.cnblogs.com/firsthelloworld/p/..."/>
    </transactionManager>
    <dataSource type="POOLED">
      <property name="driver" value="https://www.cnblogs.com/firsthelloworld/p/${driver}"/>
      <property name="url" value="https://www.cnblogs.com/firsthelloworld/p/${url}"/>
      <property name="username" value="https://www.cnblogs.com/firsthelloworld/p/${username}"/>
      <property name="password" value="https://www.cnblogs.com/firsthelloworld/p/${password}"/>
    </dataSource>
  </environment>
</environments>

MyBatis 可以配置成適應多種環境,不過要記住:盡管可以配置多個環境,但每個 SqlSessionFactory 實體只能選擇一種環境,

如果忽略了環境引數,那么將會加載默認環境.

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment);

事務管理器(transactionManager)

在 MyBatis 中有兩種型別的事務管理器(也就是 type="[JDBC|MANAGED]"):

  • JDBC – 這個配置直接使用了 JDBC 的提交和回滾設施,它依賴從資料源獲得的連接來管理事務作用域,
<transactionManager type="MANAGED">
  <property name="closeConnection" value="https://www.cnblogs.com/firsthelloworld/p/false"/>
</transactionManager>

如果你正在使用 Spring + MyBatis,則沒有必要配置事務管理器,因為 Spring 模塊會使用自帶的管理器來覆寫前面的配置,

資料源(dataSource)

dataSource 元素使用標準的 JDBC 資料源介面來配置 JDBC 連接物件的資源,

有三種內建的資料源型別(也就是 type="[UNPOOLED|POOLED|JNDI]"):

添加其他資料源

<dataSource type="org.myproject.C3P0DataSourceFactory">
  <property name="driver" value="https://www.cnblogs.com/firsthelloworld/p/org.postgresql.Driver"/>
  <property name="url" value="https://www.cnblogs.com/firsthelloworld/p/jdbc:postgresql:mydb"/>
  <property name="username" value="https://www.cnblogs.com/firsthelloworld/p/postgres"/>
  <property name="password" value="https://www.cnblogs.com/firsthelloworld/p/root"/>
</dataSource>

屬性(properties)

<properties resource="db.properties">

</properties>
后面的就可以使用 ${driver}去參考
優先使用resource="db.properties"匯入的 

型別別名(typeAliases)

型別別名可為 Java 型別設定一個縮寫名字, 它僅用于 XML 配置,意在降低冗余的全限定類名書寫,例如:

單個
<typeAliases>
  <typeAlias alias="Author" type="domain.blog.Author"/>
</typeAliases>

使用包
<typeAliases>
  <package name="domain.blog"/>
</typeAliases>

使用注解
@Alias("author")
public class Author {
    ...
}

設定(settings)

這是 MyBatis 中極為重要的調整設定,它們會改變 MyBatis 的運行時行為, 下表描述了設定中各項設定的含義、默認值等,

設定名 描述 有效值 默認值
cacheEnabled 全域性地開啟或關閉所有映射器組態檔中已配置的任何快取, true | false true
lazyLoadingEnabled 延遲加載的全域開關,當開啟時,所有關聯物件都會延遲加載, 特定關聯關系中可通過設定 fetchType 屬性來覆寫該項的開關狀態, true | false false
logImpl 指定 MyBatis 所用日志的具體實作,未指定時將自動查找, SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING 未設定
mapUnderscoreToCamelCase 是否開啟駝峰命名自動映射,即從經典資料庫列名 A_COLUMN 映射到經典 Java 屬性名 aColumn, true | false False

映射器(mappers)注冊

<!-- 使用相對于類路徑的資源參考 -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
  <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>

//需要在同一個包下面,且介面和.xml檔案同名
<!-- 使用映射器介面實作類的完全限定類名 -->
<mappers>
  <mapper />
  <mapper />
  <mapper />
</mappers>
<!-- 將包內的映射器介面實作全部注冊為映射器 -->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>

4.xml映射器

引數

parameterType 將會傳入這條陳述句的引數的類全限定名或別名,這個屬性是可選的,因為 MyBatis 可以通過型別處理器(TypeHandler)推斷出具體傳入陳述句的引數,默認值為未設定(unset),
#{},${} #{}防止SQL注入,
@Param("") 定義別名,給傳引數用,

引數是map

 SqlSessionFactory sqlSessionFactory = SqlSeeionUtils.getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
//        List<User> allUsers = mapper.getAllUsers();
//        for (User allUser : allUsers) {
//            System.out.println(allUser);
//        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("userName","aaa");
        map.put("password","21321");
        mapper.addUser(map);
        sqlSession.commit();
        sqlSession.close();


 <insert id="addUser" parameterType="map">
        insert into mybatis.user(name,pwd) values (#{userName},#{password})
 </insert>

結果映射resultMap

解決 資料庫欄位 和 屬性 不一致的問題 ,可以把資料庫查詢出來的資料進行封裝成pojo,

resultType只是 簡單的資料回傳

1.解決欄位名和屬性名不一致

-----------取別名-----

<select id="getAllUsers" resultType="com.cb.pojo.User">
select id,name,pwd as password from user
</select>

-----------結果集映射-----
 <resultMap id="Users" type="com.cb.pojo.User">
        <result column="pwd" property="password"/>
  </resultMap>


2.一對多和多對一

回傳映射是一個物件用 association

回傳映射是一個集合用 collection

多對一:多個學生對應一個老師,即

public class Student {
    private int id;
    private String name;
    private Teacher teacher;
}
<resultMap id="stu" type="com.cb.pojo.Student">
    <id property="id" column="id"/>
    <result property="name" column="name"/>
    <association property="teacher" javaType="com.cb.pojo.Teacher">
        <id property="id" column="tid"/>
        <result property="name" column="tName"/>
    </association>
</resultMap>
<select id="getAllStus" resultMap="stu">
    select t.id as tid ,t.name as tName ,s.id,s.name from  teacher t   left join  student s on s.tid = t.id;
</select>

一對多:一個老師對應多個學生,即

@Data
public class Teacher {
    private int id;
    private String name;

    private List<Student> stus;
}
  <resultMap id="tea" type="com.cb.pojo.Teacher">
        <id column="tid" property="id"/>
        <result property="name" column="tname"/>

        <collection property="stus" ofType="com.cb.pojo.Student">
            <id column="sid" property="id"/>
            <result property="name" column="sname"/>
        </collection>
    </resultMap>

    <select id="getAllTea" resultMap="tea">
        select t.id tid ,t.name tname ,s.id sid ,s.name sname ,s.tid stid
from teacher t left join student s
on s.tid = t.id;
    </select>

5.日志

用來記錄 SQL操作

mybatis 默認提供

logImpl 指定 MyBatis 所用日志的具體實作,未指定時將自動查找, SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING 未設定
  • SLF4J (掌握)

  • LOG4J

  • LOG4J2

  • JDK_LOGGING

  • COMMONS_LOGGING

  • STDOUT_LOGGING 標準輸出

    <settings>
        <setting name="logImpl" value="https://www.cnblogs.com/firsthelloworld/p/STDOUT_LOGGING"/>
    </settings>
    
    控制臺 顯示
    Created connection 1166151249.
    Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@45820e51]
    ==>  Preparing: select * from user 
    ==> Parameters: 
    <==    Columns: id, name, pwd
    <==        Row: 1, chen1, 123456
    <==        Row: 2, chen2, 123456
    <==        Row: 3, chen3, 123456
    <==        Row: 5, aaa, 21321
    <==      Total: 4
    
    
  • NO_LOGGING

LOG4J

  • 控制日志資訊輸送的目的地是控制臺、檔案、GUI組件,甚至是套介面服務器、NT的事件記錄器、UNIX Syslog守護行程等;

  • 控制每一條日志的輸出格式;

  • 通過定義每一條日志資訊的級別,我們能夠更加細致地控制日志的生成程序

  • 通過一個組態檔來靈活地進行配置

匯入log4j的包

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

組態檔log4j.properties

#將等級為DEBUG的日志資訊輸出到console和file這兩個目的地,console和file的定義在下面的代碼
log4j.rootLogger=DEBUG,console,file

#控制臺輸出的相關設定
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=【%c】-%m%n

#檔案輸出的相關設定
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/kuang.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=【%p】【%d{yy-MM-dd}】【%c】%m%n

#日志輸出級別
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

使用log4j

Logger logger = Logger.getLogger(UserDaoTest.class);
logger.info("info------------");
logger.error("info------------");
logger.debug("info------------");

-------------顯示 檔案和控制臺----------
[INFO][20-07-29][com.cb.dao.UserDaoTest]info------------
[ERROR][20-07-29][com.cb.dao.UserDaoTest]info------------
[DEBUG][20-07-29][com.cb.dao.UserDaoTest]info------------

6.分頁

1.使用limit進行分頁

<select id="getUserBylimit" resultType="com.cb.pojo.User" parameterType="map">
    select * from user limit #{indexStart} , #{pageSize}
</select>

2.pageHelper插件

1. 使用 Maven

在 pom.xml 中添加如下依賴:

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>最新版本</version>
</dependency>

最新版本號可以從首頁查看,

2. 配置攔截器插件

特別注意,新版攔截器是 com.github.pagehelper.PageInterceptorcom.github.pagehelper.PageHelper 現在是一個特殊的 dialect 實作類,是分頁插件的默認實作類,提供了和以前相同的用法,

1. 在 MyBatis 配置 xml 中配置攔截器插件

<!--
    plugins在組態檔中的位置必須符合要求,否則會報錯,順序如下:
    properties?, settings?,
    typeAliases?, typeHandlers?,
    objectFactory?,objectWrapperFactory?,
    plugins?,
    environments?, databaseIdProvider?, mappers?
-->
<plugins>
    <!-- com.github.pagehelper為PageHelper類所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- 使用下面的方式配置引數,后面會有所有的引數介紹 -->
        <property name="param1" value="https://www.cnblogs.com/firsthelloworld/p/value1"/>
	</plugin>
</plugins>

3. 分頁插件引數介紹

3.代碼中使用

//第三種,Mapper介面方式的呼叫,推薦這種使用方式,
PageHelper.offsetPage(1, 10);
List<Country> list = countryMapper.selectIf(1);

7.注解開發

面向介面開發

代碼實作

package org.mybatis.example;
public interface BlogMapper {
  @Select("SELECT * FROM blog WHERE id = #{id}")
  Blog selectBlog(int id);
}

8.Lombok

Lombok專案是一個Java庫,它會自動插入編輯器和構建工具中,Lombok提供了一組有用的注釋,用來消除Java類中的大量樣板代碼,僅五個字符(@Data)就可以替換數百行代碼從而產生干凈,簡潔且易于維護的Java類,

常用注解:

@常用注解:
@Setter :注解在類或欄位,注解在類時為所有欄位生成setter方法,注解在欄位上時只為該欄位生成setter方法,
@Getter :使用方法同上,區別在于生成的是getter方法,
@ToString :注解在類,添加toString方法,
@EqualsAndHashCode: 注解在類,生成hashCode和equals方法,
@NoArgsConstructor: 注解在類,生成無參的構造方法,
@RequiredArgsConstructor: 注解在類,為類中需要特殊處理的欄位生成構造方法,比如final和被@NonNull注解的欄位,
@AllArgsConstructor: 注解在類,生成包含類中所有欄位的構造方法,
@Data: 注解在類,生成setter/getter、equals、canEqual、hashCode、toString方法,如為final屬性,則不會為該屬性生成setter方法,
@Slf4j: 注解在類,生成log變數,嚴格意義來說是常量,

9.動態SQL

能夠根據不同的條件 構建出 不同的SQL陳述句

if

判斷條件是否滿足 ,滿足就使用,

<select id="getIf" resultType="com.cb.pojo.Blog" parameterType="map" >
    select * from blog where 1=1
    <if test="title != null">
        and title = #{title}
    </if>

    <if test="title != null">
        and author= #{author}
    </if>
</select>

判斷不為null 且 不為空字串

<if test="keyword != null and keyword != ''">
        AND  user_id = #{keyword} 
</if>

choose (when, otherwise)

從幾個條件選擇 一個條件出來:

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

trim (where, set)

where 標簽where 元素只會在子元素回傳任何內容的情況下才插入 “WHERE” 子句,而且,若子句的開頭為 “AND” 或 “OR”,where 元素也會將它們去除,

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG
  <where>
    <if test="state != null">
         state = #{state}
    </if>
    <if test="title != null">
        AND title like #{title}
    </if>
    <if test="author != null and author.name != null">
        AND author_name like #{author.name}
    </if>
  </where>
</select>

set 跟 update一起用

<update id="updateAuthorIfNecessary">
  update Author
    <set>
      <if test="username != null">username=#{username},</if>
      <if test="password != null">password=#{password},</if>
      <if test="email != null">email=#{email},</if>
      <if test="bio != null">bio=#{bio}</if>
    </set>
  where id=#{id}
</update>

trim標簽:用來重新定義set 和 where標簽

<trim prefix="SET" suffixOverrides=",">
  ...
</trim>

foreach

動態 SQL 的另一個常見使用場景是對集合進行遍歷(尤其是在構建 IN 條件陳述句的時候),比如:

<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  WHERE ID in
  <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
        #{item}
  </foreach>
</select>

你可以將任何可迭代物件(如 List、Set 等)、Map 物件或者陣列物件作為集合引數傳遞給 foreach,當使用可迭代物件或者陣列時,index 是當前迭代的序號,item 的值是本次迭代獲取到的元素,當使用 Map 物件(或者 Map.Entry 物件的集合)時,index 是鍵,item 是值,

bind

bind 元素允許你在 OGNL 運算式以外創建一個變數,并將其系結到當前的背景關系,比如:

<select id="selectBlogsLike" resultType="Blog">
  <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" /> 
  SELECT * FROM BLOG
  WHERE title LIKE #{pattern}
</select>

 _parameter代表那個引數(傳遞過來的引數)   '%' + #{name} + '%'  _parameter.getName()

案例:

<select id="getUserByName" resultType="com.cb.pojo.User" parameterType="string" >
    <bind name="name1" value="'%'+_parameter+'%'"/>
    select * from user
    where name like #{name1}

</select>

傳遞多個引數

//模糊查詢
    List<User> likeByNameOrIponeCode(@Param("name") String name,@Param("ipone") String iponeCode);



 <select id="likeByNameOrIponeCode" parameterType="string" resultType="com.cb.pojo.User">
        <bind name="_name" value="https://www.cnblogs.com/firsthelloworld/p/'%'+ name +'%'"/>
        <bind name="_ipone" value="https://www.cnblogs.com/firsthelloworld/p/'%' + ipone  +'%'"/>
        SELECT * from t_user
        <where>
            <if test=" name != null and name!=''">
                username like  #{_name}
            </if>
            <if test="ipone != null and ipone!='' ">
                or phoneCode like #{_ipone}
            </if>
        </where>

    </select>

10.快取

作用:

  • 把查詢出來的資料 快取到記憶體里面

  • 再次使用時,就可以不用從關系資料庫里面查詢,提高查詢效率,

  • 一般快取不經常改變的資料

  • 所有快取都放在以及快取,當SqlSession關閉時,才會轉移到二級快取

mybatis快取

  • 默認開啟一級快取

一級快取

  Mybatis對快取提供支持,但是在沒有配置的默認情況下,它只開啟一級快取,一級快取只是相對于同一個SqlSession而言,所以在引數和SQL完全一樣的情況下,我們使用同一個SqlSession物件呼叫一個Mapper方法,往往只執行一次SQL,因為使用SelSession第一次查詢后,MyBatis會將其放在快取中,以后再查詢的時候,如果沒有宣告需要重繪,并且快取沒有超時的情況下,SqlSession都會取出當前快取的資料,而不會再次發送SQL到資料庫,

            

  為什么要使用一級快取,不用多說也知道個大概,但是還有幾個問題我們要注意一下,

  1、一級快取的生命周期有多長?

每一個請求都都會 開啟一個一個新的SqlSession物件

  a、MyBatis在開啟一個資料庫會話時,會 創建一個新的SqlSession物件,SqlSession物件中會有一個新的Executor物件,Executor物件中持有一個新的PerpetualCache物件;當會話結束時,SqlSession物件及其內部的Executor物件還有PerpetualCache物件也一并釋放掉,

  b、如果SqlSession呼叫了close()方法,會釋放掉一級快取PerpetualCache物件,一級快取將不可用,

  c、如果SqlSession呼叫了clearCache(),會清空PerpetualCache物件中的資料,但是該物件仍可使用,

  d、SqlSession中執行了任何一個update操作(update()、delete()、insert()) ,都會清空PerpetualCache物件的資料,但是該物件可以繼續使用

二級快取:

  MyBatis的二級快取是namespece級別的快取,它可以提高對資料庫查詢的效率,以提高應用的性能,

? 意思是 新來的請求也可以拿到快取,如果在同一個Mapper下

MyBatis的快取機制整體設計以及二級快取的作業模式

  SqlSessionFactory層面上的二級快取默認是不開啟的,二級快取的開席需要進行配置,實作二級快取的時候,MyBatis要求回傳的POJO必須是可序列化的, 也就是要求實作Serializable介面,配置方法很簡單,只需要在映射XML檔案配置就可以開啟快取了,如果我們配置了二級快取就意味著:

  • 映射陳述句檔案中的所有select陳述句將會被快取,
  • 映射陳述句檔案中的所欲insert、update和delete陳述句會重繪快取,
  • 快取會使用默認的Least Recently Used(LRU,最近最少使用的)演算法來識訓,
  • 根據時間表,比如No Flush Interval,(CNFI沒有重繪間隔),快取不會以任何時間順序來重繪,
  • 快取會存盤串列集合或物件(無論查詢方法回傳什么)的1024個參考
  • 快取會被視為是read/write(可讀/可寫)的快取,意味著物件檢索不是共享的,而且可以安全的被呼叫者修改,不干擾其他呼叫者或執行緒所做的潛在修改,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/116787.html

標籤:Java

上一篇:static關鍵字設計原理

下一篇:Reactor反應器模式

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more