Supplement two knowledge maps
Two recent articles Maven's first acquaintance and The first MyBatis program The knowledge structure diagram is missing in this paper, which is supplemented here.


This section is about the advanced part of MyBatis. The focus of the previous section is to take you to build a java project using MyBatis framework from scratch, and you can use MyBatis framework to add, delete, modify and query tables in the database; It doesn't sound difficult to understand, but it still needs more practice for novices to practice again. It is recommended that you operate by creating a new Module.
This section will be based on the previous section, including project engineering and database, including but not limited to:
- Other configurations in MyBatis core configuration file
- How to make SQL statements dynamic
- MyBatis annotation development model
- MyBatis caching mechanism
- Paging function
tips: the source code and data table of demo are available in official account recommendation java reply to myBatisDemo.
Coming to the point, please keep quiet
Profile label
Log management
A log file is a record file or collection of files used to record system operation events.
In actual development, log is very important and can play two great roles. One is to help developers troubleshoot. The other is to manage who operates what content through records. These two points, especially when associated with the library, can play a very key role. I believe you have heard of the saying of deleting the library and running the road!
The log framework can master two common:
- STDOUT_LOGGING
- LOG4J
It is easy to use. In the main configuration file mybatis config Add the following code to XML:
<settings> <!-- Configuration log --> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>
For STDOUT_LOGGING can be used by adding the above configuration; For LOG4J, the library itself supports various customizations. You can add attribute configuration files separately, modify the configuration according to your own needs, and achieve customization. There are many tutorials on how to cooperate and what attributes are available on the Internet, which are not explained here (there have been loopholes in the library recently, and everyone is filling the hole).
It should be noted that the tags configured under the configuration tag in the MyBatis core configuration file are in order, as follows:
- properties (property configuration, which will be configured later in this article, needs to be mastered)
- settings
- typeAliases (type aliases, need to be mastered, can understand and use)
- typeHandlers (type processor, just understand)
- objectFactory (object factory, just understand)
- plugins (plug-ins, which need to be mastered. Configuration is required when relying on some plug-ins)
- environments (environment configuration, proficiency)
- Environment (environment variable)
- Transaction manager
- dataSource
- Environment (environment variable)
- databaseIdProvider (database vendor ID)
- mappers (mapper, proficient)
properties tag
In the previous section, we configured hump naming mapping in the settings tab:
<!-- Enable hump naming mapping --> <setting name="mapUnderscoreToCamelCase" value="true"/>
These are the two configurations in the settings tab we have contacted so far. Let's look at the properties tab. This is our first contact. Take a simple example and you will know its function. Remember the following code?
<!-- development environment --> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <!-- mysql drive--> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <!-- Specify the open port of the database, the name of the database to be connected, and the encoding method--> <property name="url" value="jdbc:mysql://localhost:3306/mybatis_demo?useUnicode=true&characterEncoding=utf8"/> <!-- mysql user name--> <property name="username" value="root"/> <!-- mysql Login password--> <property name="password" value="root"/> </dataSource> </environment>
The value corresponding to the value here is not friendly and recommended to be written directly. In actual development, there is a special property file to manage these values, which requires the properties tag.
Create a new file dB. In the resources directory Properties, edit the following:
driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/mybatis_demo?useUnicode=true&characterEncoding=utf8 username=root password=root
It's that simple. Taoist friends with experience in other programming languages should be familiar with it. This is a simple way to store values in k-v form. Next, configure the following code under the configuration tab in our core configuration file:
<properties resource="db.properties"/>
Remember the order problem we mentioned earlier! Don't misplace it (it doesn't matter if you misplace it. IDEA is too smart. It will give you a hint).
Careful, you may notice that we have a small change: & amp; - >& So why & can't this symbol be written directly in xml?
We all know that there are labels in xml. If we want to write a less than sign <, when parsing xml, you will think that this is the beginning of a label, and the label is not completely written, so there are some corresponding escape symbols. The commonly used ones are:
- < : <
- > : >
- & : &
- ' : '
- " : "
typeAliases label
The function of this tag is to give a short name to many long and numerous JavaBeans, so as to facilitate use and reduce error probability. In the previous section, we have such a query:
<!-- Query all records --> <select id="selectTVSeriesAll" resultType="com.javafirst.bean.TVSeriesBean"> select * from tv_series </select>
Here's com javafirst. bean. Tvseriesbean is the part we want to replace with an alias. Think about it. If the project is a little more complex and has experienced several developers, it is Nice to use an alias The following is the configuration of alias labels:
<!-- Set alias --> <typeAliases> <!-- Mode 1 is convenient mapper Medium resultType Use the alias directly --> <typeAlias type="com.javafirst.bean.TVSeriesBean" alias="bean_series"/> <!-- Method 2 specifies the full path alias of the package name. The default is the initial lowercase class name(If the class is annotated, the alias takes precedence over the annotation name) The advantage is that you can specify more than one at a time, but the disadvantage is that you can't customize it --> <!-- <package name="com.javafirst.domain"/>--> </typeAliases>
After this setting, we set it in the corresponding mapper XML can be used in this way:
<!-- Query all records --> <select id="selectTVSeriesAll" resultType="bean_series"> select * from tv_series </select>
Careful students have noticed that there are two ways, but we recommend you to use the example here. As for the annotation method, we will talk about it later in this article.
Dynamic SQL
Dynamic SQL refers to the technology of dynamically organizing SQL according to parameters. Simply put, you can execute SQL by dynamically changing conditions in java projects to get the required results. In fact, it's not difficult or profound. Let's learn one by one:
- Dynamic SQL if
- Dynamic SQL where (optimization of if)
- Dynamic SQL choose (when, otherwise)
- Dynamic SQL foreach
- Dynamic SQL fragment
Dynamic SQL fragment
Precautions for use:
- Try to implement it based on a single table
- Do not nest where tags
Let's first define an SQL fragment:
<!-- SQL fragment --> <sql id="select_front"> select * from tv_series </sql>
The syntax is very simple. The SQL tag is used, which is a basic SQL statement. You can add, delete, modify and query one of them. You can define multiple, as long as the id is unique. The use method is also very simple. See the following example:
<!-- Query all records --> <select id="selectTVSeriesAll" resultType="bean_series"> <include refid="select_front"/> </select>
Of course, you can also nest in statements, such as:
<!-- Query all records --> <select id="selectTVSeriesAll" resultType="bean_series"> <include refid="select_front"/> where tv_id = #{tvId} </select>
It is flexible to use, especially when our SQL is long. Extracting some independent content is of great significance for us to understand the program.
Dynamic SQL if
I believe you should have guessed. Yes, it's interesting to learn the if tag and apply it to SQL statement writing as conditional judgment. Before you start, insert several pieces of data as the next step. The complete SQL is as follows, which can be executed directly:
INSERT INTO tv_series (tv_title,tv_sub_title,tv_type) VALUES ("<The eight dragons","This novel takes the era of song zhezong as the background, examines and describes life and society from the height of philosophy through the Wulin gratitude and resentment and national contradictions among the kingdoms of song, Liao, Dali, Xixia and Tubo, and shows a magnificent picture of life.",2), ("<Xiake Xing","Xiake Island, which is isolated overseas, sends two envoys to the Central Plains every ten years to reward the good and punish the evil, and forcibly invites the leaders of all major schools in the Wulin to the island for Laba porridge. All sects that did not accept the invitation were killed by the two envoys, and the leaders who went to Xiake island had no news.",1), ("<Xiaoao Jianghu","The play tells the story of Linghu Chong, the eldest disciple of Huashan sect, who is open-minded and uninhibited by nature. I came across Feng Qingyang, an expert of the sword sect, who gave Dugu Jiujian, and accidentally got the essence of the sword techniques of all schools in the five mountains, which led to the suspicion of master Yue buqun and expelled from the school on the pretext of suspicion.",2), ("<In the name of the people","At night, in Jingzhou City, Handong Province, the seemingly calm officialdom was suddenly cloudy. Zhao Dehan, director of the project Department of national ministries and commissions, was suspected of taking bribes and was subjected to a surprise investigation by Hou Liangping (Lu Yi), director of the investigation department of the anti corruption General Administration of the Supreme People's Procuratorate.",6) ;
Now let's take a very simple example:
Query data by title or type and return a List collection
It is not difficult to realize this function. The key is that we should do it through dynamic SQL technology, but the three steps we are familiar with will not change. Step 1: define the interface list < tvseriesbean > selectbydynamicsql in TVSeriesDao_ if(Map<String, Object> params) ;
The second step is in TVseries mapper Write SQL in XML:
<!-- dynamic SQL-if --> <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 > 0 and type < 7"> or tv_type = #{type} </if> </select>
The third step is the test method. The code is as follows:
/** * Dynamic SQL if test */ @Test public void testDynamicSQL_if() { 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(); }
After completing the above three steps, the final step is to see the results. Here are several groups of test parameters:
// first group params.put("title", "<In the name of the people"); //params.put("type", 2); // Group 2 params.put("title", "<In the name of the people"); params.put("type", 2); // Group 3 //params.put("title", "the name of the people"); params.put("type", 2); // Group 4 params.put("title", ""); params.put("type", 12);
After the test, you will find that the third and fourth groups of parameters will make mistakes, which is the problem caused by using only the IF tag. At this time, the SQL corresponding to these two groups of parameters becomes as follows:
select * from tv_series where or tv_type=2 select * from tv_series where
Obviously, these two SQL grammars are wrong and cannot be executed, resulting in exceptions in our program. So what is the solution? This is the next step to learn how to use dynamic SQL where tags with if.
Dynamic SQL where (if)
On the basis of the above, we only need to modify the mapper The test results can be obtained by the code in XML:
<!-- dynamic SQL-where-if --> <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 > 0 and type < 7"> or tv_type = #{type} </if> </where> </select>
The verification results are tested by yourself. There is no demonstration here. It should be noted that MyBatis will automatically cancel or and immediately after the where tag. It is precisely because of this that our SQL will be automatically assembled into executable statements.
Dynamic SQL choose (when, otherwise)
The procedure is the same. Here you can directly add the code to define the interface tvseriesbean selectbydynamicsql_ choose(Map<String, Object> params); Then mapper The code in XML is as follows:
<!-- dynamic 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>
Here we will explain the function of the code. The choose when otherwise structure has the same function as the switch case structure we learned in the basic part of java, but the writing syntax is different. It is not difficult to understand.
In short, as long as the judgment conditions of one of the when tags are met, the later logic will not be followed; If the when condition is not satisfied, the logic after otherwise will be followed, which is so simple.
Finally, our test code is as follows:
/** * Dynamic SQL choose when otherwise */ @Test public void testSelectByDynamicSQL_choose() { 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 the conditions are not met, the default value is taken params.put("id", 2); TVSeriesBean bean = tvSeriesDao.selectByDynamicSQL_choose(params); System.out.println(bean); sqlSession.close(); }
Results we tried by ourselves to practice the results by changing parameters and understand them more thoroughly.
Dynamic SQL foreach
A common usage scenario is to traverse the collection (especially when building IN conditional statements). Here we will explain that the generic types of the collection are Integer and Object types. They are just a little different. Let's first look at the collection traversal of the wrapper type.
Define interface list < tvseriesbean > selectbydynamicsql_ foreach(List<Integer> ids); Then mapper Code in XML:
<!-- dynamic SQL-foreach collection:Indicates that the traversal is an array(array)Or a collection(list); open:Character at the beginning of the loop; close:Character at the end of the loop; item:Collection member,Custom variable; separator: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>
The meaning of each attribute is explained here. In fact, it completely corresponds to the structure of the set we have learned before, so it is not difficult to understand, because xml is always parsed according to nodes.
The test code is as follows:
/** * Dynamic SQL foreach traversal generic types are collections of wrapper classes */ @Test public void testSelectByDynamicSQL_foreach() { 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(); }
You can test by yourself and the results meet our needs: find the records in the id set we specify from the table.
We all know that the generic type of the set can be the wrapper class corresponding to the basic data type or the user-defined object type. Now let's learn the collection of variable object types.
First, define the interface list < tvseriesbean > selectbydynamicsql_ foreachObj(List<TVSeriesBean> seriesBeans); Then came our mapper Code in XML file:
<!-- foreach Parameter generic types are object types--> <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>
The only change is the item here. If it is a collection of object types, then the object is defined here, and the corresponding value is the object name Attribute value; If it is a wrapper class collection of basic types, what is defined here is the data type itself, and the corresponding value is its element itself.
Finally, the test code:
/** * Dynamic SQL foreach traversal generic types are collections of object classes */ @Test public void testSelectByDynamicSQL_foreachObj() { 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(); }
Similarly, the results are verified by ourselves, as long as we understand what we are doing? So the result is expected. Haha ~ here, you'll finish learning dynamic SQL and, of course, dynamically updating the set tag. In fact, it's not difficult. You can check the example on the official website.
Caching mechanism
L1 cache
The L1 cache is enabled by default and cannot be closed. The cache range is SqlSession session.
Cache invalidation:
- Query different conditions
- The update, insert and delete statements update the cache
In fact, we can learn about caching here. redis is used for caching later
L2 cache
The L2 cache needs to be opened manually. The range is Mapper namespace
- useCache=false means no cache is used
- flushCache=true means to force the cache to be emptied
Enable cache:
<cache eviction="LRU" flushInterval="600000" size="512" readOnly="true"/>
The value of eviction can be:
- LRU indicates that the longest unused objects will be cleared.
- FIFO is first in first out, which is clear according to the order in which objects enter the cache.
- SOFT reference: removes objects based on garbage collector status and SOFT reference rules.
- WEAK references: remove objects based on garbage collector status and WEAK reference rules more actively.
Flush interval: represents the interval between automatically clearing the cache, in milliseconds.
size the number of objects stored in the cache. A collection counts as an object.
L2 cache trigger timing
Only when the reply is submitted or closed, it will be submitted to the L2 cache and will be added to the L1 cache by default.
PageHelper plug-in
Official website address: https://pagehelper.github.io/
Of course, you can also go to the mav Search Library: https://search.maven.org/search
Use process:
1. Add maven dependency
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.3.0</version> </dependency>
2. Configuring plugins
<plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"/> </plugins>
The declaration position of this tag is mentioned in the configuration file tag at the beginning of this article. Just pay attention to the position.
2. Use example
// Parameter: page number; Number per page PageHelper.startPage(2, 3);
The paging function depends on the requirements. Sometimes you may be asked to write it yourself, which is the limit we learned before.
Annotation development
This development method can be used for simple business. If it is more complex, it will be difficult to implement the annotation development method, and it will appear very messy, unclear structure and poor readability.
The plug-in lombok provides N annotations. The most commonly used annotation instead of getXXX()/setXXX() and toString()/hashCode() methods is @ Data
Other common notes:
- @AllArgsConstructor: construction method of all parameters
- @NoArgsConstructor: construction method without parameters
- @Alias(""): alias annotation, which is mentioned earlier in this article. If an annotation alias is added, the annotation alias will take precedence in mapper
For the download of plug-ins, there is no demonstration here, but there is a warm reminder:
If IntelliJ IDEA can't open plugins - > marketplace to connect the network cable, you will disconnect the network and link the mobile hotspot. Swish and you will succeed!
Simple example: query all data in the table
/** * Annotation method * There is no need to write the corresponding < Select > tag in the mapper file * @return */ @Select("select * from tv_series") List<TVSeriesBean> selectAllTVSeries();
It also provides a lot of comments. Those who are interested can try it by themselves. I won't explain it too much here.
summary
- The content of this article involves a lot of knowledge points, which needs to be strengthened. In particular, configuration file tags and dynamic SQL are the top priorities
- Technology is constantly evolving. We still need to understand the annotation development mode and know what we are doing, because some developers are already using this mode
- Learning technology is a slow process. Don't be eager for success. Slow down and you can be fast