Fill in two knowledge maps first

The knowledge structure diagram is missing from two recent articles, “Maven For The First Time” and “The First MyBatis Program”.

This section is about the advanced part of MyBatis, the content of the last section is to take you to build a Java project using MyBatis framework from scratch, and can use MyBatis framework to complete the operation of adding, deleting, changing and checking tables in the database; This sounds easy to understand, but for beginners to actual combat, still need more practice, recommend everyone to operate through the way of new Module.

This section will be based on the previous section, including project engineering and database, including but not limited to:

  • Other configurations in the MyBatis core profile
  • How do SQL statements become dynamic
  • MyBatis annotation development mode
  • MyBatis caching mechanism
  • paging

Tips: This article demo source and data tables, in the public number recommended learning Java reply myBatisDemo can be obtained.

We’re about to get down to business. Please be quiet

Profile label

Log management

A log file is a record file or collection of files used to record system operation events.

Log is very important in the actual development, can have the effect of two large, one: to help developers debug, secondly, what who can pass the records management operation, these two points are particularly associated with library, can play a key role, delete library run that believe everyone has heard of!

The logging framework can master two common ones:

  • STDOUT_LOGGING
  • LOG4J

Add the following code to the main configuration file mybatis-config. XML:

<settings>
    <! -- Configure log -->
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
Copy the code

Add the above configuration for STDOUT_LOGGING to use; For LOG4J, the library itself supports a variety of customization, you can add a separate property configuration file, according to their own needs to modify the configuration, do the customization, about how to match and which properties, there are many tutorials on the web, not explained here (recently the library has a bug, everyone is filling in the hole).

It should be noted that the configuration tags in the MyBatis core configuration file are in sequence:

  • Properties (The configuration will be done later in this article, which needs to be mastered)
  • Settings (Need to know)
  • TypeAliases (typeAliases)
  • TypeHandlers (typeHandlers, understand)
  • ObjectFactory (objectFactory)
  • Plugins (need to be learned, require configuration when relying on some plugins)
  • Environments
    • Environment (environment variable)
      • transactionManager
      • A dataSource
  • DatabaseIdProvider (Database vendor Identity)
  • Mappers (mapper, Proficiency)

The properties TAB

In the previous section we configured the hump naming mapping in the Settings tag:

<! -- Enable hump naming mapping -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
Copy the code

These are the two configurations in the Settings TAB that we’ve seen so far, and then the Properties TAB, that’s the first time we’ve seen it. A simple example of how this works, remember this code?

<! -- Development environment -->
<environment id="development">
    <transactionManager type="JDBC"/>
    <dataSource type="POOLED">
        <! -- Mysql driver -->
        <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
        <! -- Specify the port on which the database is open, the name of the database to connect to, and the encoding mode -->
        <property name="url"
                  value="jdbc:mysql://localhost:3306/mybatis_demo? useUnicode=true&amp;characterEncoding=utf8"/>
        <! Mysql > select * from 'mysql';
        <property name="username" value="root"/>
        <! Mysql > select * from 'mysql';
        <property name="password" value="root"/>
    </dataSource>
</environment>
Copy the code

It is not recommended or friendly to write the corresponding value to death. In practice, there are special properties files to manage these values, using the properties tag.

Create a new file db.properties in the Resources directory and edit the following:

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis_demo? useUnicode=true&characterEncoding=utf8
username=root
password=root
Copy the code

This is how we store values in simple K-V format. Next, we configure the following code under the Configuration TAB in our core configuration file:

<properties resource="db.properties"/>
Copy the code

Remember the order we mentioned earlier! Don’t put it in the wrong place (it doesn’t matter, IDEA is so smart, it will give you hints).

You may have noticed that we have a slight change: & -> & So why can’t the & be written directly in XML?

We all know that XML is full of tags. If we write a less than sign <, the XML parsing will assume that this is the beginning of a tag, and the tag is not complete, so there are some corresponding escape symbols.

  • <&lt;
  • >&gt;
  • &&amp;
  • '&apos;
  • "&quot;

TypeAliases label

The purpose of this tag is to give long and numerous Javabeans a short name, which is easy to use and reduces the probability of error. In the previous section we had a query like this:

<! Select * from user where user >
<select id="selectTVSeriesAll" resultType="com.javafirst.bean.TVSeriesBean">
    select * from tv_series
</select>
Copy the code

Com here. Javafirst. Beans. TVSeriesBean is what we want to use an alias to replace part of, think about it, if the project is a little more complicated, and has experienced several developers, then use the alias is very Nice. Here is the configuration of the alias tag:

<! -- Set alias -->
<typeAliases>
    <! The resultType in mapper can be used as a resultType in mapper.
    <typeAlias type="com.javafirst.bean.TVSeriesBean" alias="bean_series"/>

    <! The default is lowercase class name (if the class is annotated, the alias takes precedence over the annotation name).
<! -- <package name="com.javafirst.domain"/>-->
</typeAliases>
Copy the code

After setting this, we can use it in the corresponding mapper.xml:

<! Select * from user where user >
<select id="selectTVSeriesAll" resultType="bean_series">
    select * from tv_series
</select>
Copy the code

If you are careful, you will notice that there are two ways, but I recommend you to use the example here. As for the annotation method, I will explain it later in this article.

Dynamic SQL

Dynamic SQL refers to the technique of organizing SQL dynamically based on parameters. Simply put, you can execute SQL to get the desired results by dynamically changing conditions, etc., in a Java project. In fact, it is not difficult, nor sophisticated, the following one to understand:

  • Dynamic SQL – the if
  • Dynamic SQL-WHERE (optimization for IF)
  • Dynamic SQL – choose the when, otherwise)
  • Dynamic SQL – foreach
  • Dynamic SQL- fragment

Dynamic SQL- fragment

Precautions for use:

  • Try to implement based on a single table
  • Do not nest where tags

Let’s start by defining an SQL fragment:

<!-- SQL fragment -->
<sql id="select_front">
    select * from tv_series
</sql>
Copy the code

Syntax is very simple, using SQL tags, which is the basic SQL statement, you can add, delete, change, check one of the, you can define multiple, only id can be unique, the way to use is also very simple, see the following example:

<! Select * from user where user >
<select id="selectTVSeriesAll" resultType="bean_series">
    <include refid="select_front"/>
</select>
Copy the code

Of course, you can also nest them in statements like this:

<! Select * from user where user >
<select id="selectTVSeriesAll" resultType="bean_series">
    <include refid="select_front"/> where tv_id = #{tvId}
</select>
Copy the code

It is flexible to use, especially when our SQL is long, and it makes a lot of sense to extract some individual content to understand the program.

Dynamic SQL – the if

As you’ve probably guessed, it’s fun to learn the if tag and use it as a conditional in SQL writing. Insert some data before we begin, for use in the following study, complete SQL as follows, can be directly executed:

INSERT INTO tv_series (tv_title,tv_sub_title,tv_type)
VALUES(" Tian Long Ba Bu "," Set in the era of Emperor Zhezong of the Song Dynasty, this novel examines and describes life and society from a philosophical height through the martial enmends and ethnic conflicts between song, Liao, Dali, Xixia, Tubo and other kingdoms, presenting a magnificent picture of life." .2The Journey of a Swordsman Solitary overseas swordsman Island every ten years sends two ambassadors to the Central Plains to reward the good and punish the evil and forcibly invites the heads of the martial arts schools to the island to drink laba porridge. Those who did not accept the invitation were killed by the two generals, and those who went to The Island were still silent." .1The Swordsman the Swordsman the swordsman tells the story of linghu Chong, a disciple of huashan school who is naturally open-minded and uninhibited. Encounter jian zong gao Feng Qingyang to grant "Dugu nine swords", and accident to the essence of the wuyue school jianfa, resulting in teacher Yue Buqun suspicion, excuses out of the teacher. .2In the Name of The People Night falls on Jingzhou City in Handong Province the seemingly calm atmosphere of government suddenly becomes overcast. Hou Liangping (Lu Yi), head of the Anti-graft bureau of the Supreme People's Procuratorate, has launched a surprise investigation into Zhao Dehan on suspicion of taking bribes. .6);Copy the code

Now let’s look at a very simple example:

Query data by title or type and return a List.

It’s not that hard to do, the key is to do it with dynamic SQL technology, but the familiar three steps won’t change. First, define the interface List

selectByDynamicSQL_if(Map

params) in TVSeriesDao;
,>

Step 2: write SQL in tvSeriesmapper. XML:

<! SQL > alter table SQL > alter table SQL > alter table SQL >
<select id="selectByDynamicSQL_if" parameterType="map" resultType="bean_series">
    <include refid="select_front"/>
    where
    <if test="title! =null and ''! =title">
        tv_title=#{title}
    </if>

    <if test="type &gt; 0 and type &lt; 7">
        or tv_type = #{type}
    </if>
</select>
Copy the code

The third step, is the test method, the code is as follows:

/** * dynamic SQL-if test */
@Test
public void testDynamicSQL_if(a) {
  SqlSession sqlSession = MyBatisUtil.openSqlSession();
  TVSeriesDao tvSeriesDao = sqlSession.getMapper(TVSeriesDao.class);

  // Find data by title or type
  Map<String, Object> params = new HashMap<>();
  params.put("title"."In the Name of the People");
  //params.put("type", 2);

  List<TVSeriesBean> beanList = tvSeriesDao.selectByDynamicSQL_if(params);

  for (TVSeriesBean seriesBean : beanList) {
      System.out.println(seriesBean);
  }

  sqlSession.close();
}
Copy the code

After completing the above three steps, the final result is to see. Here are some test parameters for you:

/ / the first group
params.put("title"."In the Name of the People");
//params.put("type", 2);

/ / the second group
params.put("title"."In the Name of the People");
params.put("type".2);

/ / the third group
//params.put("title", "in the name of the people ");
params.put("type".2);

/ / the fourth group
params.put("title"."");
params.put("type".12);
Copy the code

IF you use only the IF tag, you will find that the third and fourth groups of parameters can be wrong. This is the problem with using only the IF tag.

select * from tv_series where or tv_type=2

select * from tv_series where
Copy the code

It is clear that both SQL syntax are incorrect and cannot be executed, causing an exception in our program. So what’s the solution? This is the dynamic SQL-WHERE tag used in conjunction with if.

Dynamic SQL – where (if)

To test the results, we just need to modify the code in mapper.xml:

<! SQL > alter table SQL > alter table SQL > alter table SQL
<select id="selectByDynamicSQL_where_if" parameterType="map" resultType="bean_series">
    <include refid="select_front"/>
    <where>
        <if test="title! =null and ''! =title">
            tv_title=#{title}
        </if>

        <if test="type &gt; 0 and type &lt; 7">
            or tv_type = #{type}
        </if>
    </where>
</select>
Copy the code

MyBatis will automatically cancel the OR and AND tags immediately following where tags. Because of this, our SQL will be automatically assembled into executable statements.

Dynamic SQL – choose the when, otherwise)

Define interface TVSeriesBean selectByDynamicSQL_choose(Map

params); This is followed by the following code in mapper.xml:
,>

<! -- SQL -- choose -- when -- otherwise -->
<select id="selectByDynamicSQL_choose" parameterType="map" resultType="bean_series">
    <include refid="select_front"/>
    <where>
        <choose>
            <when test="type == 6">
                tv_type = #{type}
            </when>

            <when test="title == null or title == ''">Tv_title = 'in the Name of the People'</when>

            <otherwise>
                tv_id = #{id}
            </otherwise>
        </choose>
    </where>
</select>
Copy the code

To illustrate the functionality of the code, the choose-if-otherwise structure is the same as the switch-case structure we learned about in the Java basics section, but the syntax is different and it is not difficult to understand.

In short, as long as one of the criteria of the WHEN tag is satisfied, the latter logic is not followed; If the when conditions are not met, otherwise follows the logic, simple as that.

Finally, our test code is as follows:

/** * dynamic SQL- choose-before-otherwise */
@Test
public void testSelectByDynamicSQL_choose(a) {
  SqlSession sqlSession = MyBatisUtil.openSqlSession();
  TVSeriesDao tvSeriesDao = sqlSession.getMapper(TVSeriesDao.class);

  Map<String, Object> params = new HashMap<>();
  params.put("title"."xxx");
  params.put("type".12);
  // If none of the conditions are met, use the default value
  params.put("id".2);

  TVSeriesBean bean = tvSeriesDao.selectByDynamicSQL_choose(params);

  System.out.println(bean);

  sqlSession.close();
}
Copy the code

Results We try by ourselves, through the transformation of parameters to practice the results, understand more thoroughly.

Dynamic SQL – foreach

A common use scenario is to iterate over collections (especially when building IN conditional statements). I’ll show you that the generics for collections are the types Integer and Object, but they’re only slightly different. Let’s look at the collection traversal of the wrapper type.

Define interface List

selectByDynamicSQL_foreach(List

IDS); Then there is the code in mapper.xml:

<! SQL-foreach collection: array or list traversal; Open: character at the beginning of the loop; Close: the character at the end of the loop; Item: set member, custom variable; Separator: THE separator between elements; -->
<select id="selectByDynamicSQL_foreach" resultType="bean_series">
    <include refid="select_front"/>
    <if test="list ! = null and list.size > 0">
        where tv_id in
        <foreach collection="list" open="(" close=")" item="cus_id" separator=",">
            #{cus_id}
        </foreach>
    </if>
</select>
Copy the code

The meaning of each attribute is explained here, and it actually corresponds exactly to the structure of the collection we learned earlier, so it’s not hard to understand because XML is always parsed in terms of nodes.

The test code is as follows:

/** * Dynamic SQL-foreach traversal generic types are collections of wrapped classes */
@Test
public void testSelectByDynamicSQL_foreach(a) {
  SqlSession sqlSession = MyBatisUtil.openSqlSession();
  TVSeriesDao tvSeriesDao = sqlSession.getMapper(TVSeriesDao.class);

  List<Integer> ids = new ArrayList<>();
  ids.add(1);
  ids.add(2);
  ids.add(3);
  //ids.add(5);

  List<TVSeriesBean> beanList = tvSeriesDao.selectByDynamicSQL_foreach(ids);

  for (TVSeriesBean seriesBean : beanList) {
      System.out.println(seriesBean);
  }

  sqlSession.close();
}
Copy the code

Test for ourselves, and the results meet our requirement: find the records in the set of ids we specify from the table.

We all know that collections of generics can be either wrapper classes corresponding to primitive data types or custom object types, so now let’s look at collections of variable object types.

List

selectByDynamicSQL_foreachObj(List

seriesBeans); Here is the code in our mapper.xml file:

<! -- Foreach parameter generic type is object type -->
<select id="selectByDynamicSQL_foreachObj" resultType="bean_series">
    <include refid="select_front"/>

    <if test="list ! = null and list.size > 0">
        where tv_id in
        <foreach collection="list" open="(" close=")" separator="," item="series">
            #{series.tvId}
        </foreach>
    </if>
</select>
Copy the code

The only change is the item here, if it’s a collection of object types, then this is the object defined here, and the corresponding value is the name of the object. The attribute value; If it is a collection of wrapper classes of a primitive type, then the data type itself is defined, and the corresponding value is the element itself.

Finally, the test code:

/** * Dynamic SQL-foreach traversal generic types are collections of object classes */
@Test
public void testSelectByDynamicSQL_foreachObj(a) {
  SqlSession sqlSession = MyBatisUtil.openSqlSession();
  TVSeriesDao tvSeriesDao = sqlSession.getMapper(TVSeriesDao.class);

  List<TVSeriesBean> seriesBeans = new ArrayList<>();

  TVSeriesBean seriesBean1 = new TVSeriesBean();
  seriesBean1.setTvId(1);
  seriesBean1.setTvType(1);
  seriesBeans.add(seriesBean1);

  TVSeriesBean seriesBean3 = new TVSeriesBean();
  seriesBean3.setTvId(6);
  seriesBean3.setTvType(1);
  seriesBeans.add(seriesBean3);

  List<TVSeriesBean> beanList = tvSeriesDao.selectByDynamicSQL_foreachObj(seriesBeans);

  for (TVSeriesBean bean : beanList) {
      System.out.println(bean);
  }

  sqlSession.close();
}
Copy the code

Again, the results are self-verifying, as long as we understand what we’re doing, right? The set tag is also used to dynamically update the set tag.

Caching mechanisms

Level 1 cache

Level-1 cache is enabled by default and cannot be disabled. The cache scope is SqlSession session.

Cache invalidation:

  • Query different conditions
  • update,insert,deleteThe statement updates the cache

In fact, we know that caching can be done here, and we use Redis to do caching.

The second level cache

Level-2 cache must be manually enabled. The cache scope is Mapper namespace.

  • useCache=falseIndicates that caching is not used
  • flushCache=trueIndicates forcibly clearing the cache

Enable cache:

<cache eviction="LRU" flushInterval="600000" size="512" readOnly="true"/>
Copy the code

Eviction, iction, iction

  • LRUThe object that has not been used for the longest time is cleared.
  • FIFOFirst in, first out, in the order objects are entered into the cache.
  • SOFTSoft references: Remove objects based on garbage collector state and soft reference rules.
  • WEAKWeak references: More aggressively remove objects based on garbage collector state and weak reference rules.

FlushInterval: specifies the interval at which the cache is automatically cleared, in milliseconds.

Size Number of objects stored in the cache. A set counts as an object.

Level 2 cache trigger time

Only when a reply is committed or closed is committed to level 2 cache, which is added to level 1 cache by default.

PageHelper plug-in

Website address: https://pagehelper.github.io/

, of course, also can take mav search library to look for: https://search.maven.org/search

Use process:

1. Add maven dependencies

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.3.0</version>
</dependency>
Copy the code

2. Configure plugins

<plugins>
    <plugin interceptor="com.github.pagehelper.PageInterceptor"/>
</plugins>
Copy the code

The declared location of this tag is mentioned in the order of the configuration file tag at the beginning of this article, just note the location.

2. Use examples

// Parameter: page number; Number each page
PageHelper.startPage(2.3);
Copy the code

Paging depends on the requirements, and sometimes you have to write your own, which is the limit that we learned about earlier.

Annotations to develop

While this approach can be used for simple businesses, annotation development is more difficult to implement if it is more complex, and can be messy, poorly structured, and poorly readable.

Lombok provides dozens of annotations, most commonly used to replace methods like getXXX()/setXXX() and toString()/hashCode() : @data.

Other common notes:

  • AllArgsConstructor: Constructor for all arguments
  • NoArgsConstructor: constructor with no arguments
  • @alias (“”): Alias annotation, which was mentioned earlier in this article. If an annotation Alias is added, mapper will use the annotation Alias preferentially

There is no demo of how to download the plugin, but here is a reminder:

If IntelliJ IDEA doesn’t connect to plugins -> Marketplace, then you disconnect from the network, connect to your mobile hotspot, and whoosh!

Simple example: Query all data in a table

/** * Annotations * do not need to write the corresponding <select> tag * in mapper files@return* /
@Select("select * from tv_series")
List<TVSeriesBean> selectAllTVSeries(a);
Copy the code

There are also plenty of annotations, so if you’re interested, try them out on your own. I won’t explain too much here.

conclusion

  • The content of this article involves a lot of knowledge points, need to strengthen practice, especiallyProfile labelandDynamic SQLTop priority
  • Is the technology constantly evolving, annotating the development approach or is it about understanding, knowing what you’re doing, because part of the development is already using that model
  • Learning technology is a slow process, do not rush for success, slow down, can be fast
  • This will be the last one for 2021Recommended to learn JavaA series of original articles, 2022 continue to output, everyone come on!

The source code and data tables involved in this article can be obtained in the public number recommended learning Java reply myBatisDemo. Xiaobian specially created a public account: recommend learning Java, share original Java content, welcome everyone wechat search attention (attention is to send high-quality video tutorial), learn Java together, see ~ 2022