[mybatis] a direct conclusion

Mybatis

brief introduction

MyBatis is an excellent persistence layer framework, which supports custom SQL, stored procedures and advanced mapping. MyBatis eliminates almost all JDBC code and the work of setting parameters and obtaining result sets. MyBatis can configure and map primitive types, interfaces and Java POJO s (Plain Old Java Objects) to records in the database through simple XML or annotations.

Summary:

  1. Mybatis is a persistence layer framework that works with databases
  2. Simplifies JDBC operations
  3. Separation of SQL and code

The database table name of idea does not prompt the solution:

effect

The first Mybatis program

1. Build environment

Create database

CREATE DATABASE `mybatis`;
USE `mybatis`;
CREATE TABLE `user`(
	`id` INT(20) NOT NULL ,
	`name` VARCHAR(30) DEFAULT NULL,
	`pwd` VARCHAR(30) DEFAULT NULL,
	PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=UTF8

INSERT INTO `user`(`id`,`name`,`pwd`) 
VALUES(1,'La La La','123456'),
(2,'Zhang San','123456'),
(3,'Mad God','123456');

New project

  1. Create a normal maven project

  2. Delete src directory

  3. Import pom dependencies

    <dependencies>
            <!--    mysql drive-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.47</version>
            </dependency>
            <!--    mybatis-->
            <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.5</version>
            </dependency>
            <!--    junit-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>
        </dependencies>
    

2. Create a module

  • Write Mybatis core configuration file

    <?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 Is the core configuration file-->
    <configuration>
        <!--Environment configuration default Property to set the database environment to be used by default-->
        <environments default="development">
            
            <!--Unique identification of environment name id-->
            <environment id="development">
                <!--The default is jdbc Transaction manager-->
                <transactionManager type="JDBC"/>
                <!--Use connection pool by default-->
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
                </dataSource>
            </environment>
        </environments>
    
    </configuration>
    
  • Write Mybatis tool class

    public class MybatisUtils {
        private static SqlSessionFactory sqlSessionFactory;
        static{
            String resource = "mybatis-config.xml";
            try {
                //Get sqlsessionfactory object using Mybatis
                InputStream inputStream = Resources.getResourceAsStream(resource);
                sqlSessionFactory  = new SqlSessionFactoryBuilder().build(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        //sqlsession is an object that can execute sql
        public static SqlSession getSqlsession(){
            return sqlSessionFactory.openSession();
        }
    }
    

3. Write code

Entity class member variables must be consistent with database fields!!!

  • Create entity class

    package com.hou.pojo;
    
    public class User {
        private int id;
        private String name;
        private String pwd;
    
        public User() {
        }
    
        public User(int id, String name, String pwd) {
            this.id = id;
            this.name = name;
            this.pwd = pwd;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getPwd() {
            return pwd;
        }
    
        public void setPwd(String pwd) {
            this.pwd = pwd;
        }
    }
    
    
  • Dao interface

    public interface UserDao {
        List<User> getUserList();
    }
    
  • The interface implementation class is changed from the original UserDaoImpl to usermapper XML file

  • Namespace is used to bind interfaces

  • resultType automatically encapsulates the result set, so you only need to write the real type of the return value

    <?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">
    <!--select Query statement-->
    <mapper namespace="com.hou.dao.UserDao">  <!--The fully qualified name writes the interface you want to bind-->
        <select id="getUserList" resultType="com.hou.pojo.User">   <!--id:Method name in interface   resultType:return type-->
            select * from user
        </select>
    </mapper>
    

4. Testing

  • Register mappers in the core configuration file (Only registered mappers will take effect, so don't forget after writing!!)

        <mappers>
            <!--Note that the file path here is/Delimited directory-->
            <mapper resource="com/hou/dao/UserMapper.xml"/> 
        </mappers>
    
  • Use Junit to test. Note: sqlsession is not thread safe and must be closed after use

        @Test
        public void test(){
    
            //Get sqlsession object
            SqlSession sqlsession = MybatisUtils.getSqlsession();
            //Execute sql
            UserMapper userMapper = sqlsession.getMapper(UserMapper.class);
    
            List<User> userList = userMapper.getUserList();
            for (User user : userList) {
                System.out.println(user);
            }
            sqlsession.close();
        }
    

Addition, deletion, modification and query of Mybatis (CRUD)

1. Namespace (namespace) must be fully qualified. For example: com xxx. xxx. XXX (fully qualified class name of the corresponding interface)

2. Add, delete and modify transactions that need to be submitted. Transactions are automatically enabled by default!!!!!!!

3,select

Select query statement;

  • id: is the method name of the corresponding namespace;
  • resultType: return value type of Sql statement execution
  • parameterType: parameter type

#The difference between {} and ${}

1) #{} is a parameter placeholder?, sql precompiling

2) ${} is replaced by string, that is, sql splicing

  1. Write mapper interface
  2. In mapper Writing sql in XML
  3. test
    <select id="getUserList" resultType="com.hou.pojo.User">
        select * from user
    </select>

    <select id="getUserByID" resultType="com.hou.pojo.User" parameterType="int">
        select * from user where id = #{id}
    </select>

4,insert

    <insert id="addUser" parameterType="com.hou.pojo.User">
        insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
    </insert>

5,updata

    <update id="updataUser" parameterType="com.hou.pojo.User">
        update user set name=#{name},pwd=#{pwd}  where id = #{id};
    </update>

6,delete

ditto

About some mistakes

  • There is a problem of Chinese garbled code in the output XML file!
  • maven resource cannot be exported. Problem!
  • NullPointerException, no registered resource!

Universal Map

Assuming that there are too many entity classes and tables, fields and parameters in the database, we should consider using map

Throw any parameter you need into the map

@Test
public void addUser(){
        SqlSession sqlsession = MybatisUtils.getSqlsession();
        UserMapper mapper = sqlsession.getMapper(UserMapper.class);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id",5);
        map.put("name","La La La");
        map.put("pwd","222222");
        mapper.addUser2(map);
        sqlsession.commit();
    }
    <insert id="addUser2" parameterType="map">
        insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
    </insert>

You only need to write the key in sql directly to pass the parameters of map! [ parameterType=“map”]

Transfer parameters to the object and directly take out the object attributes in sql!

Only when only one parameter is a basic type can it be retrieved directly from sql

Two ways of fuzzy query

[the external chain image transfer fails. The source station may have anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-3qgdyyjn-1619259358443) (C: \ users \ Hou \ appdata \ roaming \ typora user images \ image-20200910144237480. PNG)]

! Configuration resolution

Core profile

  • mybatis-config.xml

  • Mybatis's configuration file contains settings and attribute information that will deeply affect mybatis's behavior

    configuration(Configuration)
    properties(Properties)
    settings(Settings)
    typeAliases(Type alias)
    typeHandlers(Type (processor)
    objectFactory(Object factory)
    plugins(Plug in)
    environments(Environment configuration)
    environment(Environment variables)
    transactionManager(Transaction manager)
    dataSource((data source)
    databaseIdProvider(Database (manufacturer identification)
    mappers(Mapper)
    

    (environments) environment configuration

    • MyBatis can be configured to adapt to a variety of environments. This mechanism helps to apply SQL mapping to a variety of databases

    • Although multiple environments can be configured, only one environment can be selected for each SqlSessionFactory instance.

    • The default transaction manager of Mybatis is JDBC, and the default connection pool is pooled

properties

  • These properties can be configured externally and can be replaced dynamically. You can configure these properties either in a typical Java properties file or in a child element of the properties element.
<!--Import external files, and then mybatis-config.xml The attributes in the referenced file can be referenced in the configuration file, and this label can be self closed-->
<properties resource="db.properties">
<!--You can write some parameters here-->
</properties>
-----------------------------------------------------------------------------------------------------------------------------------------
or
<properties resource="db.properties">
   <property name="username" value="root"/>
   <property name="password" value="123456"/>
</properties>
_________________________________________________________________________________________________________________________________________

<!--Use of reference properties ${}To quote, xml Represents a replacement splice string in-->
 <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
</dataSource>
  • You can import external files directly, as shown above
  • Some properties can be added in the configuration
  • If the internal attribute and the external attribute have the same field, the external configuration file is preferred, because the attribute configuration in XML is read first, and then the external file will be read, so the external attribute will overwrite the internal attribute value

Type aliases

Type alias sets an abbreviated name for a Java type. It is only used for XML configuration and is intended to reduce redundant fully qualified class name writing

At present, there are two setting methods to choose from. Method 1 is recommended when there are few entity classes and method 2 is recommended when there are many entity classes!

Method 1: customize the alias for a single entity class

<typeAliases>
  <typeAlias alias="Author" type="domain.blog.Author"/>
  <typeAlias alias="Blog" type="domain.blog.Blog"/>
  <typeAlias alias="Comment" type="domain.blog.Comment"/>
  <typeAlias alias="Post" type="domain.blog.Post"/>
  <typeAlias alias="Section" type="domain.blog.Section"/>
  <typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>

When configured in this way, blog can be used in any domain blog. Blog place.

Method 2: batch setting alias

Scan all classes under the package and alias them all. If there is no annotation, the initial lowercase unqualified class name of the Bean will be used as its alias. For example, domain blog. The alias of author is author.

<typeAliases>
  <package name="domain.blog"/>
</typeAliases>

If annotation is used, its alias is annotation value:

@Alias("author")
public class Author {
    ...
}

settings

These are extremely important tuning settings in MyBatis, which will change the runtime behavior of MyBatis.

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-lutko6ji-1619259358444) (C: \ users \ Hou \ appdata \ roaming \ typora user images \ image-20200910164401282. PNG)]

[the external chain image transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-etfpm13t-1619259358444) (C: \ users \ Hou \ appdata \ roaming \ typora \ typora user images \ image-20200910164438903. PNG)]

mappers

We need to tell MyBatis where to find these statements. Java does not provide a good solution for automatically finding resources, so the best way is to directly tell MyBatis where to find the mapping file. You can use resource references relative to the classpath, or fully qualified resource locators or class and package names, that is, tell MyBatis where to find the mapping file

<!-- Use resource references relative to Classpaths -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
  <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- Use fully qualified resource locators( URL) -->
<mappers>
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  <mapper url="file:///var/mappers/BlogMapper.xml"/>
  <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
<!-- Use the mapper interface to implement the fully qualified class name of the class -->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
<!-- Register all the mapper interface implementations in the package as mappers -->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>

Note: in addition to the first method, other methods need to be noted:

  • Interface and its Mapper configuration file must have the same name!
  • Interface and its Mapper configuration file must be in the same package!
  • If you want to separate xml from the interface, you need to create the same directory as the package where the interface is located in the resources directory, and put the mapper corresponding to the interface into it

Lifecycle and scope

Mybatis process:

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-tl5gm77y-1619259358445) (C: \ users \ Hou \ appdata \ roaming \ typora user images \ image-20200910170901085. PNG)]

SqlSessionFactoryBuilder:

This class can be instantiated, used and discarded. Once SqlSessionFactory is created, it is no longer needed.

SqlSessionFactory:

Once SqlSessionFactory is created, it should always exist during the operation of the application. There is no reason to discard it or recreate another instance. The best practice of using SqlSessionFactory is not to create multiple times during application operation. The best scope of SqlSessionFactory is application scope. It is recommended to use singleton mode or static singleton mode.

SqlSession:

Each thread should have its own SqlSession instance. The instance of SqlSession is not thread safe, so it cannot be shared, so its best scope is the request or method scope.

Never put the reference of SqlSession instance in the static field of a class, or even the instance variable of a class. You must never place a reference to a SqlSession instance in any type of managed scope

Consider putting SqlSession in a scope similar to HTTP requests. In other words, every time you receive an HTTP request, you can open a SqlSession and close it after returning a response.

Click: https://mybatis.org/mybatis-3/zh/getting-started.html

If SqlSessionFactory is equivalent to a database Connection pool, SqlSession is equivalent to a database Connection (Connection object),
You can execute multiple SQL statements in a transaction, and then commit or roll back the transaction through its commit, rollback and other methods. So it should survive in a business request,
After processing a complete request, you should close the connection and return it to SqlSessionFactory, otherwise the database resources will be consumed quickly and the system will be paralyzed. Therefore, use the try... catch... Properly statement to ensure that it is closed correctly.

The name of the property and the name of the field are inconsistent

Solution:

Scheme 1: alias in sql statement example: user_id as id;

Scheme 2: modify the mapping name by using resultMap of result set mapping

column: corresponds to the field in the database

Property: the property of the corresponding entity class

[the external chain image transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-4zhhgs6ti-1619259358446) (C: \ users \ Hou \ appdata \ roaming \ typora user images \ image-20200910180720968. PNG)]

journal

1. Log factory

If an exception occurs in a database operation and we need to troubleshoot it, we need to use the log

journal:

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-ftmpxbxd-1619259358447) (C: \ users \ Hou \ appdata \ roaming \ typora user images \ image-20200912153705622. PNG)]

  • SLF4J
  • LOG4J [Master]
  • LOG4J2
  • JDK_LOGGING
  • COMMONS_LOGGING
  • STDOUT_LOGGING [mastering]
  • NO_LOGGING

The specific log implementation used in Mybatis is set in the settings!

STDOUT_LOGGING: standard log output

Configuration method: directly configure key value pairs in settings in the configuration file (available in the official document)

<settings>
       <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

Log4j: Log4j is Apache An open source project

By using Log4j, we can control the destination of log information delivery Console , documents GUI Components, even socket servers NT Event recorder UNIX SyslogDaemon Etc;

We can also control the output format of each log

Configuration method:

  1. Import the dependency of log4j

    <!-- https://mvnrepository.com/artifact/log4j/log4j -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    
    
  2. Write configuration file

    #Output the log information with the level of DEBUG to the two destinations of console and file. The definitions of console and file are in the following code
    log4j.rootLogger=DEBUG,console,file
    
    #Relevant settings of console output
    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
    
    #Relevant settings for file output
    log4j.appender.file = org.apache.log4j.RollingFileAppender
    log4j.appender.file.File=./log/hou.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
    
    #Log output level
    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
    
  3. Configure settings in the configuration file

        <settings>
            <setting name="logImpl" value="LOG4J"/>
        </settings>
    
  4. Simple use of log4j. Use log4j to output logs in the program

    //Be careful not to lead the package wrong: org apache. log4j. The logger method parameter is the class of the current class
    static Logger logger = Logger.getLogger(MyTest.class);
    
    @Test
    public void selectUser() {
       logger.info("info: get into selectUser method");
       logger.debug("debug: get into selectUser method");
       logger.error("error: get into selectUser method");
       SqlSession session = MybatisUtils.getSession();
       UserMapper mapper = session.getMapper(UserMapper.class);
       List<User> users = mapper.selectUser();
       for (User user: users){
           System.out.println(user);
      }
       session.close();
    }
    

paging

Why pagination?

Paging at the back end is to reduce the amount of data processing, because if you do not page, it is a great burden for the program to find out all the data at once

--paging sql: 
select * from user limit Start bit

Steps:

1. Write mapper xml

<select id="selectUser" parameterType="map" resultType="user">
  select * from user limit #{startIndex},#{pageSize}
</select>

2. Mapper corresponds to the interface, and the parameter is map

//Select all users to implement paging
List<User> selectUser(Map<String,Integer> map)

3. Pass in the parameter test in the test class

  • Infer: start position = (current page - 1) * page size
//Paging query, two parameters: StartIndex and PageSize
@Test
public void testSelectUser() {
   SqlSession session = MybatisUtils.getSession();
   UserMapper mapper = session.getMapper(UserMapper.class);

   int currentPage = 1;  //Page number
   int pageSize = 2;  //How many are displayed per page
   Map<String,Integer> map = new HashMap<String,Integer>();
   map.put("startIndex",(currentPage-1)*pageSize);
   map.put("pageSize",pageSize);

   List<User> users = mapper.selectUser(map);

   for (User user: users){
       System.out.println(user);
  }

   session.close();
}

Using annotation development

Using annotation development

  • The initial configuration information of MyBatis is based on XML, and the mapping statement (SQL) is also defined in XML. MyBatis 3 provides a new annotation based configuration. Unfortunately, the expressiveness and flexibility of Java annotations are very limited. The most powerful MyBatis mapping cannot be built with annotations

  • sql types are mainly divided into:

    • @select ()
    • @update ()
    • @Insert ()
    • @delete ()

**Note: * * mapper is not required for annotation development XML Mapping file

1. We add annotations to our interface

//Query all users
@Select("select id,name,pwd password from user")
public List<User> getAllUser();

2. Inject in the core configuration file of mybatis

<!--use class Binding interface-->
<mappers>
   <mapper class="com.kuang.mapper.UserMapper"/>
</mappers>

3. Let's go and test

@Test
public void testGetAllUser() {
   SqlSession session = MybatisUtils.getSession();
   //In essence, it makes use of the dynamic proxy mechanism of jvm
   UserMapper mapper = session.getMapper(UserMapper.class);

   List<User> users = mapper.getAllUser();
   for (User user : users){
       System.out.println(user);
  }

   session.close();
}

4. Use Debug to see the essence

5. In essence, it makes use of the dynamic proxy mechanism of jvm

6. Detailed execution process of Mybatis

Addition, deletion and modification of notes

Transform the getSession() method of MybatisUtils tool class and overload the implementation.

  //Get SqlSession connection
  public static SqlSession getSession(){
      return getSession(true); //Transaction auto commit
  }
 
  public static SqlSession getSession(boolean flag){
      return sqlSessionFactory.openSession(flag);
  }

[note] ensure that the entity class corresponds to the database field

Query:

1. Write interface method annotation

//Query user by id
@Select("select * from user where id = #{id}")
User selectUserById(@Param("id") int id);

2. Testing

@Test
public void testSelectUserById() {
   SqlSession session = MybatisUtils.getSession();
   UserMapper mapper = session.getMapper(UserMapper.class);

   User user = mapper.selectUserById(1);
   System.out.println(user);

   session.close();
}

newly added:

1. Write interface method annotation

//Add a user
@Insert("insert into user (id,name,pwd) values (#{id},#{name},#{pwd})")
int addUser(User user);

2. Testing

@Test
public void testAddUser() {
   SqlSession session = MybatisUtils.getSession();
   UserMapper mapper = session.getMapper(UserMapper.class);

   User user = new User(6, "Qin Jiang", "123456");
   mapper.addUser(user);

   session.close();
}

Modification:

1. Write interface method annotation

//Modify a user
@Update("update user set name=#{name},pwd=#{pwd} where id = #{id}")
int updateUser(User user);

2. Testing

@Test
public void testUpdateUser() {
   SqlSession session = MybatisUtils.getSession();
   UserMapper mapper = session.getMapper(UserMapper.class);

   User user = new User(6, "Qin Jiang", "zxcvbn");
   mapper.updateUser(user);

   session.close();
}

Delete:

1. Write interface method annotation

//Delete by id
@Delete("delete from user where id = #{id}")
int deleteUser(@Param("id")int id);

2. Testing

@Test
public void testDeleteUser() {
   SqlSession session = MybatisUtils.getSession();
   UserMapper mapper = session.getMapper(UserMapper.class);

   mapper.deleteUser(6);
   
   session.close();
}

[Note: remember to deal with the transaction when adding, deleting or modifying]

About @ Param

@The Param annotation is used to give a name to a method parameter. The following are the principles for the use of the summary:

  • When the method accepts only one parameter, @ Param may not be used.
  • When the method accepts multiple parameters, it is recommended to use the @ Param annotation to name the parameters.
  • If the parameter is a JavaBean, @ Param cannot be used.
  • When @ Param annotation is not used, there can only be one parameter and it is a java bean.

#Difference from $

  • #The function of {} is mainly to replace the placeholder in the preparestatement? [recommended, with the feature of preventing sql injection]

    INSERT INTO user (name) VALUES (#{name});
    INSERT INTO user (name) VALUES (?);
    
  • The function of ${} is to replace the string directly

    INSERT INTO user (name) VALUES ('${name}');
    INSERT INTO user (name) VALUES ('kuangshen');
    

Using annotations and configuration files for collaborative development is the best practice of MyBatis!

Use of lombook plug-in

Laziness is the ladder of scientific and technological progress

Use steps:

  1. Install Lombok plug-in in IDEA!

  2. Import the jar package of lombok in the project

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
    </dependency>
    
  3. Just annotate the entity class!

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    
    
@Getter and @Setter
@FieldNameConstants
@ToString
@EqualsAndHashCode
@AllArgsConstructor, @RequiredArgsConstructor and @NoArgsConstructor
@Log, @Log4j, @Log4j2, @Slf4j, @XSlf4j, @CommonsLog, @JBossLog, @Flogger
@Data
@Builder
@Singular
@Delegate
@Value
@Accessors
@Wither
@SneakyThrows

explain:

@Data: Generation: parameterless construction, get,set,tostring,hashcode,equals
@AllArgsConstructor: Generation: the structure with parameters, but the corresponding structure without parameters is gone
@NoArgsConstructor: Generation: parameterless construction, which can cooperate with the above one AllArgsConstructor Use, so that there is no parameter and there are both parameters
@EqualsAndHashCode
@ToString
@Getter

Be careful when using. Sometimes there are some inexplicable bug s when using

Many to one processing

Many to one:

  • Multiple students correspond to one teacher
  • For students, it is related to... Multiple students and one teacher [many to one]
  • For teachers, a collection, a teacher, has many students [one to many]

Requirements: find all students and find the corresponding teacher according to the foreign key tid in the student table

SQL:

CREATE TABLE `teacher` (
  `id` INT(10) NOT NULL,
  `name` VARCHAR(30) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO teacher(`id`, `name`) VALUES (1, 'Miss Qin'); 

CREATE TABLE `student` (
  `id` INT(10) NOT NULL,
  `name` VARCHAR(30) DEFAULT NULL,
  `tid` INT(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fktid` (`tid`),
  CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8


INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', 'Xiao Ming', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', 'Xiao Hong', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', 'Xiao Zhang', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', 'petty thief', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', 'Xiao Wang', '1');

nested queries

Idea:

  1. Query all student information
  2. According to the student's tid, check the corresponding teacher
<mapper namespace="com.hou.dao.StudentMapper">

    <select id="getStudent" resultMap="StudentTeacher">
        select * from mybatis.student
    </select>
    <resultMap id="StudentTeacher" type="com.hou.pojo.Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <!--
			Complex attributes need to be handled separately
			If it is an object: association
			If it is a set: collection
		-->
        <association property="teacher" column="tid"  javaType="com.hou.pojo.Teacher" select="getTeacher"/>
    </resultMap>
    
    <select id="getTeacher" resultType="com.hou.pojo.Teacher">
        select * from mybatis.teacher where id = #{tid}
    </select>
</mapper>

understand:

  1. First, query all the student table information, including the field tid

  2. Then nest the query and use (Association) to associate the query. select a query

  3. In the sub query, follow the tid found to find the corresponding teacher!

  4. Here, the parameter passed in the getTeacher query statement is the tid in the queried student information, because there is only one parameter, which will be automatically matched and obtained

Result query (recommended)

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-kfhiy2ik-1619259358449) (C: \ users \ Hou \ appdata \ roaming \ typora user images \ image-20200915182233355. PNG)]

One to many processing

Demand: find out the teacher and the student information under the teacher's name!

A teacher with multiple students is a one to many relationship for teachers!

A single object uses: javaType to specify the type of the attribute

The collection specifies the generic type of the collection with the confliction: oftepe attribute

But they are all used for complex environment queries

Method 1. Result query

public class Teacher {

    private int id;
    private String name;
    //Students under the teacher's name
    private List<Student> students;
}
    //Get the information of all students and teachers under the designated teacher
    Teacher getTeacher(@Param("tid") int id);
  <select id="getTeacher" resultMap="TeacherStudent">
        select s.id sid,s.name sname,t.id tid,t.name tname from mybatis.student s,mybatis.teacher t
        where s.tid=t.id and t.id = #{tid}
    </select>
    <!---->
    <resultMap id="TeacherStudent" type="com.hou.pojo.Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        <collection property="students" ofType="com.hou.pojo.Student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>

Test:

    @Test
    public void test(){
        SqlSession sqlsession = MybatisUtils.getSqlsession();
        TeacherMapper mapper = sqlsession.getMapper(TeacherMapper.class);
        Teacher teacher = mapper.getTeacher(3);
        System.out.println(teacher);
        sqlsession.commit();
        sqlsession.close();
    }

//test result
Teacher(id=3, name=Miss Zhang, students=[Student(id=3, name=Xiao Zhang, tid=3), Student(id=5, name=Xiao Wang, tid=3)])

2. Query nesting

Nested processing by query

1. TeacherMapper interface writing method

public Teacher getTeacher2(int id);

2. Write Mapper configuration file corresponding to the interface

<select id="getTeacher2" resultMap="TeacherStudent2">
select * from teacher where id = #{id}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
   <!--column Is a one to many foreign key , Write the column name of a primary key-->
   <collection property="students" javaType="ArrayList" ofType="Student"column="id" select="getStudentByTeacherId"/>
</resultMap> 
<select id="getStudentByTeacherId" resultType="Student">
  select * from student where tid = #{id}
</select>

3. Register Mapper file in mybatis config file

4. Testing

@Test
public void testGetTeacher2(){
   SqlSession session = MybatisUtils.getSession();
   TeacherMapper mapper = session.getMapper(TeacherMapper.class);
   Teacher teacher = mapper.getTeacher2(1);
   System.out.println(teacher.getName());
   System.out.println(teacher.getStudents());
}

Summary

1. association Association

2. collection -

3. Therefore, association is used for one-to-one and many to one relationships, while collection is used for one to many relationships

4. Both JavaType and ofType are used to specify the object type

  • JavaType is used to specify the type of property in pojo
  • ofType specifies the type mapped to pojo in the list collection attribute and the type of constraint in the generic type.

Note:

1. Ensure the readability of SQL and make it easy to understand as much as possible

2. According to the actual requirements, try to write SQL statements with higher performance

3. Pay attention to the inconsistency between attribute name and field

4. Pay attention to the correspondence between fields and attributes in one to many and many to one

5. Try to use Log4j and check your errors through the log

Dynamic Sql

What is dynamic SQL: dynamic SQL refers to generating different SQL statements according to different conditions

introduce

What is dynamic SQL: dynamic SQL refers to generating different SQL statements according to different query conditions

Official website description:
MyBatis One of its powerful features is its dynamics SQL. If you use JDBC Or other similar framework experience, you can experience splicing according to different conditions SQL The pain of the sentence. For example, when splicing, make sure you don't forget to add the necessary spaces, and pay attention to removing the comma of the last column name in the list. Utilization dynamics SQL This characteristic can completely get rid of this pain.
Although dynamic was used before SQL It's not easy, but it is MyBatis Provided can be used in any SQL Powerful dynamic mapping in statements SQL Language can improve this situation.
dynamic SQL Element and JSTL Or based on similar XML Similar to our text processor. stay MyBatis In previous versions, there were many elements that took time to understand. MyBatis 3 The element types have been greatly simplified. Now you only need to learn half of the original elements. MyBatis Adopt powerful based OGNL To eliminate most of the other elements.

  -------------------------------
  - if
  - choose (when, otherwise)
  - trim (where, set)
  - foreach
  -------------------------------

The SQL statements we wrote before are relatively simple. If there are complex businesses, we need to write complex SQL statements, which often need to be spliced. If we don't pay attention to splicing SQL, errors may be caused due to the lack of quotation marks, spaces and so on.

So how to solve this problem? This requires the use of mybatis dynamic SQL. Through tags such as if, choose, when, otherwise, trim, where, set and foreach, it can be combined into very flexible SQL statements, which not only improves the accuracy of SQL statements, but also greatly improves the efficiency of developers.

1. Build environment

Create a new database table: blog

Fields: id, title, author, create_time,views

CREATE TABLE `blog` (
`id` varchar(50) NOT NULL COMMENT 'Blog id',
`title` varchar(100) NOT NULL COMMENT 'Blog title',
`author` varchar(30) NOT NULL COMMENT 'Blogger',
`create_time` datetime NOT NULL COMMENT 'Creation time',
`views` int(30) NOT NULL COMMENT 'Views'
) ENGINE=InnoDB DEFAULT CHARSET=utf8

1. Create Mybatis foundation project

2. IDutil utility class

public class IDUtil {

   public static String genId(){
       return UUID.randomUUID().toString().replaceAll("-","");
  }

}

3. Entity class preparation [pay attention to the function of set method]

import java.util.Date;

public class Blog {

   private String id;
   private String title;
   private String author;
   private Date createTime;
   private int views;
   //set,get....
}

4. Write Mapper interface and xml file

public interface BlogMapper {
}
<?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.kuang.mapper.BlogMapper">

</mapper>

5. mybatis core configuration file, underline Hump Automatic Conversion

<settings>
   <setting name="mapUnderscoreToCamelCase" value="true"/>
   <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--register Mapper.xml-->
<mappers>
 <mapper resource="mapper/BlogMapper.xml"/>
</mappers>

6. Insert initial data

Write interface

//Add a new blog
int addBlog(Blog blog);

sql configuration file

<insert id="addBlog" parameterType="blog">
  insert into blog (id, title, author, create_time, views)
  values (#{id},#{title},#{author},#{createTime},#{views});
</insert>

Initialize blog method

@Test
public void addInitBlog(){
   SqlSession session = MybatisUtils.getSession();
   BlogMapper mapper = session.getMapper(BlogMapper.class);

   Blog blog = new Blog();
   blog.setId(IDUtil.genId());
   blog.setTitle("Mybatis So simple");
   blog.setAuthor("Madness theory");
   blog.setCreateTime(new Date());
   blog.setViews(9999);

   mapper.addBlog(blog);

   blog.setId(IDUtil.genId());
   blog.setTitle("Java So simple");
   mapper.addBlog(blog);

   blog.setId(IDUtil.genId());
   blog.setTitle("Spring So simple");
   mapper.addBlog(blog);

   blog.setId(IDUtil.genId());
   blog.setTitle("Microservices are so simple");
   mapper.addBlog(blog);

   session.close();
}

Initialization data completed!

2. if statement

Demand: according to the author's name and blog name to query the blog! If the author's name is empty, query only according to the blog name; otherwise, query according to the author's name

1. Writing interface classes

//Demand 1
List<Blog> queryBlogIf(Map map);

2. Writing SQL statements

<!--Requirement 1:
According to the author's name and blog name to query the blog!
If the author's name is empty, query only according to the blog name; otherwise, query according to the author's name,If none, query all
select * from blog where title = #{title} and author = #{author}
-->
<select id="queryBlogIf" parameterType="map" resultType="blog">
  select * from blog where 1=1
   <if test="title != null">
      and title = #{title}
   </if>
   <if test="author != null">
      and author = #{author}
   </if>
</select>

3. Testing

@Test
public void testQueryBlogIf(){
   SqlSession session = MybatisUtils.getSession();
   BlogMapper mapper = session.getMapper(BlogMapper.class);

   HashMap<String, String> map = new HashMap<String, String>();
   map.put("title","Mybatis So simple");
   map.put("author","Madness theory");
   List<Blog> blogs = mapper.queryBlogIf(map);

   System.out.println(blogs);

   session.close();
}

In this way, we can see that if the identity 1 = 1 is not written, if the author is equal to null, the query statement is select * from user where title=#{title}, but what if the title is empty? Then the query statement is select * from user where and author=#{author}. This is a wrong SQL statement. How to solve it? Please see the following where statement!

Where

Modify the above SQL statement;

<select id="queryBlogIf" parameterType="map" resultType="blog">
  select * from blog
   <where>
       <if test="title != null">
          title = #{title}
       </if>
       <if test="author != null">
          and author = #{author}
       </if>
   </where>
</select>

The "where" tag will know that if it contains a return value in the tag, it will insert a "where". In addition, if the content returned by the tag starts with AND OR, it will be eliminated.

3. set statement

Similarly, the above query SQL statement contains the where keyword. If the update operation contains the set keyword, how can we deal with it?

1. Write interface method

int updateBlog(Map map);

2. sql configuration file

<!--be careful set Are separated by commas-->
<update id="updateBlog" parameterType="map">
  update blog
     <set>
         <if test="title != null">
            title = #{title},
         </if>
         <if test="author != null">
            author = #{author}
         </if>
     </set>
  where id = #{id};
</update>

3. Testing

@Test
public void testUpdateBlog(){
   SqlSession session = MybatisUtils.getSession();
   BlogMapper mapper = session.getMapper(BlogMapper.class);

   HashMap<String, String> map = new HashMap<String, String>();
   map.put("title","dynamic SQL");
   map.put("author","Qin Jiang");
   map.put("id","9d6a763f5e1347cebda43e2a32687a77");

   mapper.updateBlog(map);


   session.close();
}

4. choose statement

Sometimes, we don't want to use all the query conditions. We just want to select one of them. If one of the query conditions is satisfied, we can use the choose tag to solve such problems, which is similar to the switch statement in Java

1. Write interface method

List<Blog> queryBlogChoose(Map map);

2. sql configuration file

<select id="queryBlogChoose" parameterType="map" resultType="blog">
  select * from blog
   <where>
       <choose>
           <when test="title != null">
                title = #{title}
           </when>
           <when test="author != null">
              and author = #{author}
           </when>
           <otherwise>
              and views = #{views}
           </otherwise>
       </choose>
   </where>
</select>

3. Test class

@Test
public void testQueryBlogChoose(){
   SqlSession session = MybatisUtils.getSession();
   BlogMapper mapper = session.getMapper(BlogMapper.class);

   HashMap<String, Object> map = new HashMap<String, Object>();
   map.put("title","Java So simple");
   map.put("author","Madness theory");
   map.put("views",9999);
   List<Blog> blogs = mapper.queryBlogChoose(map);

   System.out.println(blogs);

   session.close();
}

5. SQL fragment

Sometimes we may use a certain sql statement too much. In order to increase the reusability of the code and simplify the code, we need to extract these codes and call them directly when using them.

Extract SQL fragment:

<sql id="if-title-author">
   <if test="title != null">
      title = #{title}
   </if>
   <if test="author != null">
      and author = #{author}
   </if>
</sql>

Reference SQL fragment:

<select id="queryBlogIf" parameterType="map" resultType="blog">
  select * from blog
   <where>
       <!-- quote sql Clip, if refid If the specified is not in this document, it needs to be preceded by namespace -->
       <include refid="if-title-author"></include>
       <!-- Other can be quoted here sql fragment -->
   </where>
</select>

be careful:

① . it is better to define sql fragments based on a single table to improve the reusability of fragments

② . do not include where in the sql fragment

6,Foreach

Modify the id of the first three data in the database to 1,2,3;

Requirement: we need to query the blog information with id 1, 2 and 3 in the blog table

1. Write interface

List<Blog> queryBlogForeach(Map map);

2. Writing SQL statements

<select id="queryBlogForeach" parameterType="map" resultType="blog">
  select * from blog
   <where>
       <!--
       collection:Specifies the collection properties in the input object
       item:The generated object is traversed each time
       open:Splice string at the beginning of traversal
       close:String spliced at the end
       separator:Traverse the strings that need to be spliced between objects
       select * from blog where 1=1 and (id=1 or id=2 or id=3)
     -->
       <foreach collection="ids"  item="id" open="and (" close=")" separator="or">
          id=#{id}
       </foreach>
   </where>
</select>

3. Testing

@Test
public void testQueryBlogForeach(){
   SqlSession session = MybatisUtils.getSession();
   BlogMapper mapper = session.getMapper(BlogMapper.class);

   HashMap map = new HashMap();
   List<Integer> ids = new ArrayList<Integer>();
   ids.add(1);
   ids.add(2);
   ids.add(3);
   map.put("ids",ids);

   List<Blog> blogs = mapper.queryBlogForeach(map);

   System.out.println(blogs);

   session.close();
}

Summary: in fact, the compilation of dynamic sql statements is often a problem of splicing. In order to ensure the accuracy of splicing, we'd better first write the original sql statements, and then change them through the dynamic sql of mybatis to prevent errors. It is the skill to master it by using it in practice.

  1. In mybatis, if there are multiple parameters, the @ param annotation should be added to name the parameters. Then, if there are parameters that are reference objects and want to use its attributes in xml, the @ param annotation should be used

    Parameter name The attribute name is as follows:

    public int modifyUser(@Param("user")User user,@Param("id")int id);
    
    <update id="modifyUser">
            update smbms.smbms_user
            <set>
                <if test="user.userName !=null and user.userName != ''">userName = #{user.userName},</if>
                <if test="user.userRole != null and user.userRole !=''">userRole = #{user.userRole},</if>
                <if test="user.gender != null and user.gender != ''">gender = #{user.gender},</if>
                <if test="user.birthday != null">birthday = #{user.birthday},</if>
                <if test="user.phone != null and user.phone != ''">phone = #{user.phone},</if>
                <if test="user.address != null and user.address != ''">address = #{user.address},</if>
                <if test="user.modifyBy != null and user.modifyBy !=''">modifyBy = #{user.modifyBy},</if>
                <if test="user.modifyDate != null">modifyDate = #{user.modifyDate}</if>
            </set>
            where id = #{id}
        </update>
    

Dynamic SQL is widely used in development. You must master it skillfully!

cache

brief introduction

  1. What is a Cache?
    • Temporary data in memory
    • Put the data frequently queried by users in the cache, and when users query the data, they do not need to query from the disk (relational database data file), but from the cache, so as to improve the query efficiency and solve the performance problem of high concurrency system.
  2. Why cache
    • Reduce the number of interactions with the database, reduce system overhead and improve system efficiency
  3. What kind of data can be cached
    • Data that is frequently queried and not frequently changed.

1. mybatis cache

  • Mybatis contains a very powerful query caching feature, which can easily customize and configure the cache. Caching can greatly improve query efficiency.
  • Mybatis provides two levels of default cache: the first level cache and the second level cache
    • By default, only L1 cache is on. (sqlSession level cache, also known as local cache)
    • L2 cache needs to be started and configured manually. It is based on namespace level cache.
    • In order to improve scalability, MyBatis defines the Cache interface Cache. We can customize the L2 Cache by implementing the Cache interface

Cache:

  1. The results of all select statements in the mapping statement file will be cached.

  2. All insert, update, and delete statements in the mapping statement file flush the cache. (because the original data may be changed, the whole cache will be refreshed ~)

  3. The cache will use the least recently used (LRU) algorithm to clear the unnecessary cache.

  4. The cache is not refreshed regularly (that is, there is no refresh interval).

  5. The cache holds 1024 references to a list or object, regardless of what the query method returns.

  6. The cache is treated as a read / write cache, which means that the acquired object is not shared and can be safely modified by the caller without interfering with potential modifications made by other callers or threads.

2. L1 cache

Whenever we use MyBatis to open a session with the database, MyBatis will create a SqlSession object to represent a database session.

In a conversation with the database, we may repeatedly execute the same query statements. If we do not take some measures, each query will query the database. If we do the same query in a very short time, their results are likely to be identical. Because it is very expensive to query the database once, This may cause a great waste of resources.

In order to solve this problem and reduce the waste of resources, MyBatis will establish a simple cache in the SqlSession object representing the session to cache the results of each query. When the next query, if it is judged that there is an identical query before, it will directly take the results out of the cache and return them to the user, There is no need to query the database again.

As shown in the following figure, MyBatis will create a local cache in a SqlSession object, the representation of a session. For each query, it will try to find out whether it is in the cache according to the query conditions. If it is in the cache, it will be directly taken out of the cache and returned to the user; Otherwise, read the data from the database, store the query results in the cache and return them to the user.

For Session level data cache, we call it level-1 data cache, which is called level-1 cache for short

The L1 cache is turned on by default and is only valid in one sqlSession, that is, get the connection to close this interval.

The L1 cache can be cleaned up manually: sqlsession clearCache();

3. L2 cache

  • L2 cache is a global cache. Because the scope of L1 cache is too low, L2 cache was born

  • Cache based on namespace level. A namespace corresponds to a L2 cache

  • Working mechanism:

    • When a session queries a statement, the data will be placed in the first level cache of the current session;
    • If the current session is closed, the L1 cache corresponding to this session is gone; But what we want is that when the session is closed, the data in the L1 cache will be saved to the L2 cache; That is, after the L1 cache fails, the cache content will be delivered from the L1 cache to the L2 cache.
    • The new session query information can get the content from the L2 cache;
    • The data found by different mapper s will be placed in their corresponding cache (map);

    Steps:

    1. Turn on global cache

      		<!--Display enable L2 global cache-->
              <setting name="cacheEnabled" value="true"/>
      
    2. In mapper Using L2 cache in XML

      <!--Use L2 cache-->
      <cache/>
      

      These attributes of the cache can be modified through the attributes of the cache element. For example:

      <cache
        eviction="FIFO"
        flushInterval="60000"
        size="512"
        readOnly="true"/>
      

      This more advanced configuration creates a FIFO cache, which is refreshed every 60 seconds. It can store up to 512 references of the result object or list, and the returned objects are considered read-only. Therefore, modifying them may conflict with callers in different threads.

      Available purge strategies are:

      • LRU – least recently used: removes objects that have not been used for the longest time.
      • FIFO – first in first out: remove objects in the order they enter the cache.
      • SOFT – SOFT reference: removes objects based on garbage collector status and SOFT reference rules.
      • WEAK – WEAK references: remove objects more actively based on garbage collector status and WEAK reference rules.

      The default purge policy is LRU.

      The flush interval property can be set to any positive integer. The set value should be a reasonable amount of time in milliseconds. The default is not set, that is, there is no refresh interval. The cache will only be refreshed when the statement is called.

      The size (number of references) attribute can be set to any positive integer. Pay attention to the size of the object to be cached and the memory resources available in the running environment. The default value is 1024.

      The readOnly property can be set to true or false. A read-only cache returns the same instance of the cache object to all callers. Therefore, these objects cannot be modified. This provides a significant performance improvement. The read-write cache returns a copy of the cached object (through serialization). It will be slower, but safer, so the default value is false.

      Indicates that the L2 cache is transactional. This means that when SqlSession completes and commits, or completes and rolls back, but the insert/delete/update statement with flushCache=true is not executed, the cache will be updated.

    3. Summary:

      • As long as the L2 cache is enabled, it is effective under the same Mapper

The secondary cache of MyBatis is the Application level cache, which can improve the efficiency of database query and improve the performance of Application.

Check out the blog: https://louluan.blog.csdn.net/article/details/41408341

ps://img-blog.csdn.net/20141121213425390)

For Session level data cache, we call it level-1 data cache, which is called level-1 cache for short

The L1 cache is turned on by default and is only valid in one sqlSession, that is, get the connection to close this interval.

The L1 cache can be cleaned up manually: sqlsession clearCache();

3. L2 cache

  • L2 cache is a global cache. Because the scope of L1 cache is too low, L2 cache was born

  • Cache based on namespace level. A namespace corresponds to a L2 cache

  • Working mechanism:

    • When a session queries a statement, the data will be placed in the first level cache of the current session;
    • If the current session is closed, the L1 cache corresponding to this session is gone; But what we want is that when the session is closed, the data in the L1 cache will be saved to the L2 cache; That is, after the L1 cache fails, the cache content will be delivered from the L1 cache to the L2 cache.
    • The new session query information can get the content from the L2 cache;
    • The data found by different mapper s will be placed in their corresponding cache (map);

    Steps:

    1. Turn on global cache

      		<!--Display enable L2 global cache-->
              <setting name="cacheEnabled" value="true"/>
      
    2. In mapper Using L2 cache in XML

      <!--Use L2 cache-->
      <cache/>
      

      These attributes of the cache can be modified through the attributes of the cache element. For example:

      <cache
        eviction="FIFO"
        flushInterval="60000"
        size="512"
        readOnly="true"/>
      

      This more advanced configuration creates a FIFO cache, which is refreshed every 60 seconds. It can store up to 512 references of the result object or list, and the returned objects are considered read-only. Therefore, modifying them may conflict with callers in different threads.

      Available purge strategies are:

      • LRU – least recently used: removes objects that have not been used for the longest time.
      • FIFO – first in first out: remove objects in the order they enter the cache.
      • SOFT – SOFT reference: removes objects based on garbage collector status and SOFT reference rules.
      • WEAK – WEAK references: remove objects more actively based on garbage collector status and WEAK reference rules.

      The default purge policy is LRU.

      The flush interval property can be set to any positive integer. The set value should be a reasonable amount of time in milliseconds. The default is not set, that is, there is no refresh interval. The cache will only be refreshed when the statement is called.

      The size (number of references) attribute can be set to any positive integer. Pay attention to the size of the object to be cached and the memory resources available in the running environment. The default value is 1024.

      The readOnly property can be set to true or false. A read-only cache returns the same instance of the cache object to all callers. Therefore, these objects cannot be modified. This provides a significant performance improvement. The read-write cache returns a copy of the cached object (through serialization). It will be slower, but safer, so the default value is false.

      Indicates that the L2 cache is transactional. This means that when SqlSession completes and commits, or completes and rolls back, but the insert/delete/update statement with flushCache=true is not executed, the cache will be updated.

    3. Summary:

      • As long as the L2 cache is enabled, it is effective under the same Mapper

The secondary cache of MyBatis is the Application level cache, which can improve the efficiency of database query and improve the performance of Application.

Check out the blog: https://louluan.blog.csdn.net/article/details/41408341

This article is partly quoted from madness, and there are some other blog things, which may be a little messy

Keywords: Java Mybatis

Added by Griff1324 on Sat, 19 Feb 2022 13:48:02 +0200