Summary of learning Mybatis framework

Posted by benjam on Fri, 18 Feb 2022 17:05:10 +0100

Learning Mybatis framework (persistence layer framework) - Introduction

1.1.1 what is a framework

Framework is the redesign of the whole or part of the system, which is expressed as a method of interaction between a group of abstract component instances; Another definition holds that a framework is an application skeleton that can be customized by application developers. The former is defined from the aspect of application, and the latter is defined from the aspect of purpose. (Application of semi-finished products)

Three tier architecture - presentation layer, business layer and persistence layer

Presentation layer: the layer used to display data
Business layer: it deals with business requirements
Persistence layer: it can interact with the database

Solution of persistence layer technology:

JDBC Technology:
1,Connection
2,PreparedStatement
3,ResultSet
Spring's JdbcTemplate:
1. Simple encapsulation of jdbc in Spring
Apache's DBUtils:
1. It is very similar to Spring's JdbcTemplate and is also a simple encapsulation of Jdbc.
However:
They are not frameworks, JDBC is a specification, and JdbcTemplate and Apache's DBUtils are just tool classes.

1.1.2 problems solved by the framework

1. The framework encapsulates many details, so that developers can use a minimalist way to realize functions, which greatly improves the development efficiency.
2,

1.1.3 overview of mybatis framework

mybatis is an excellent persistence layer framework based on java. It encapsulates jdbc internally, so that developers only need to pay attention to the sql Statement itself, and do not need to spend energy dealing with the complicated operations of driving, creating connections and creating statements.


mybatis configures various executed statements through xml or annotation. The dynamic data parameters of sql in the java object and statement are mapped to generate the final executed sql statement. Finally, the MySQL framework executes sql and maps the results back to java objects


MyBatis framework adopts the idea of ORM (Object Relation Mapping), solves the problem of entity and database mapping, encapsulates JDBC and shields the underlying access details of JDBC api, so that we can realize the persistence operation of database without communicating with JDBC api.

1.1.4 simple implementation of mybatis

Detailed explanation of configuration file

Dependencies: define dependencies in this project
Parent: coordinates of the parent project
artifactId: component identifier
groupId: globally unique identifier
Version: version

To create a file

Environment construction of mybatis

  1. Create Maven project and import location
  2. Creating interfaces and dao classes
  3. Create and configure the main configuration file in resource - sqlmapcognig xml
<?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>
	<!-- Configure environment configuration mysql Environment -->
	<!-- Configure environment configuration mysql Environment based mysql8.0 The following driver configurations-->
	<environments default="mysql">
		<environment id="mysql">
			<!-- Configure transaction type -->
			<transactionManager type="JDBC"></transactionManager>
			<!-- Configure data pool -->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url"
					value="jdbc:mysql://localhost:3306/textmybatis" />
				<property name="username" value="root" />
				<property name="password" value="123456" />
			</dataSource>
		</environment>

	</environments>
<!-- The location of the configuration mapping profile, which refers to each dao Stand alone profile -->
</configuration>
	<!--to configure mysql8.0 Operation of-->
    <environments default="mysql">
        <!--to configure mysql Environment-->
        <environment id="mysql">
            <!--Transaction type-->
            <transactionManager type="JDBC"></transactionManager>
            <!--Connection pool-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <!--If used here is'&' Then the system will prompt you to change to ';',If this is changed to; If you still report an error, you can use the following declaration-->
                <property name="url" value="jdbc:mysql://localhost:3306/textmybatis?useUnicode=ture&amp;characterEncoding=utf-8&amp;serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>

            </dataSource>
        </environment>
    </environments>
  1. Create mapping profile
<?xml version="1.0" encoding="UTF-8"?>
<!-- to configure mybatis Mapping file for -->
<!DOCTYPE mapper
 
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.fantasy.Dao.UserDao">
	<!-- Configure query all of them id Don't Scribble, correspond UserDao Interface method correspondence in -->
	<select id="findAll">
		select * from userinfo;
	</select>


</mapper>
  1. matters needing attention:
    1) The mapping configuration file created is not necessarily called userdao XML and other files may also be called Mapper
    2) The result of package creation and directory creation is different: com Bag is a secondary directory, and in the created directory, it belongs to the primary directory. The name of the folder is called com bag
    3) The mapping configuration file location of mybatis must be the same as the package name structure of Dao interface
    4) The value of the mapper tag namespace attribute of the mapping configuration file must be the fully qualified class name of the dao interface
    5) For the operation configuration of the mapping configuration file, the value of id attribute must be the method name of dao interface

Database CRUD operation based on mybatis

How to use log4j:

Go to another article

< mappers > path to DAO configuration file

Interface file corresponding to DAO independent configuration file

/**
     * Query all contents in the table
     * @return
     */
    List<User> findAll();
    /**
     * Using insert to store data
     *
     */
    public void saveUser(User user);
    /**
     * Use updata to update data
     * According to its own id
     */
    public void updateUser(User user);

    /**
     * Use delete to delete users
     * Test the deleted instance according to the id
     */
    public void deleteUser(Integer id);

    /**
     * Use select where to query a single user
     */
    public User findUser(String username);
    /**
     * Fuzzy search by name
     * Use like Tags
     */
    public List<User> findLikeUser(String userString);

The code of the corresponding DAO configuration file

<!--Some duplicate codes here are configuration information, which can be ignored when viewing-->
<?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.text.study.dao.IUserDao">
    <!--Configure all-->
    <select id="findAll" resultType="com.text.study.User">
        SELECT * FROM userinfo;
    </select>

    <insert id="saveUser" parameterType="com.text.study.User">
        insert into userinfo(username,userpassword)values(#{username},#{userpassword});
    </insert>
    <update id="updateUser"  parameterType="com.text.study.User">
        update userinfo set username = #{username} , userpassword = #{userpassword} where id = #{id};
    </update>

    <delete id="deleteUser" parameterType="Integer">
        delete from userinfo where id = #{id}
    </delete>

    <select id="findUser" resultType="com.text.study.User" parameterType="String">
        select * from userinfo where username = #{username};
    </select>
    <select id="findLikeUser" resultType="com.text.study.User" parameterType="String">
        select * from userinfo where username like #{nameString}
    </select>
</mapper>

Code of test class:

    private InputStream in;
    private SqlSessionFactoryBuilder builder;
    private SqlSession session;
    private SqlSessionFactory factory;
    private IUserDao userDao;

    @Before
    public void init() throws Exception{
        //Read configuration file
        in = Resources.getResourceAsStream("sqlMapConfig.xml");
        //Create an sqlSessionFactory factory
        builder = new SqlSessionFactoryBuilder();
        factory = builder.build(in);
        //Use factory production SqlSession object
        session = factory.openSession();
        //Create Dao interface proxy object with SqlSession
        userDao = session.getMapper(IUserDao.class);
    }
    @After
    public void destroy() throws Exception{
        session.commit();
        session.close();
        in.close();
    }

    @Test
    public void findAll(){

        System.out.println("---------------------------");
        //Executing methods using proxy objects
        List<User> users = userDao.findAll();
        for (User user:users){
            System.out.println(user);
        }

    }

    /**
     * Save data (using insert) test class
     * @throws Exception
     */
    @Test
    public void saveUser() throws Exception{
        User user = new User();
        user.setUsername("**");
        user.setUserpassword("159753");

        System.out.println("---------------------------");
        //Executing methods using proxy objects
        userDao.saveUser(user);

    }
    /**
     * Update data (using update) test class
     * @throws Exception
     */
    @Test
    public void updateUser() throws Exception{
        User user = new User();
        user.setUsername("**");
        user.setUserpassword("123753");
        user.setId(3);
        System.out.println("---------------------------");
        //Executing methods using proxy objects
        userDao.updateUser(user);

    }

    /**
     * Delete data (using delete) test class
     * @throws Exception
     */
    @Test
    public void deleteUser() throws Exception{
        System.out.println("---------------------------");
        //Executing methods using proxy objects
        userDao.deleteUser(5);

    }

    /**
     * Query a user's information
     * @throws Exception
     */
    @Test
    public void findUser() throws Exception{
        System.out.println("---------------------------");
        //Executing methods using proxy objects
        User user = userDao.findUser("**");
        System.out.println(user);
    }

    /**
     * Use fuzzy query to query personal information (use select) test class
     * @throws Exception
     */
    @Test
    public void findLikeUser() throws Exception{
        System.out.println("---------------------------");
        //Executing methods using proxy objects
        List<User> users =  userDao.findLikeUser("%*%");
        for (User user:users){
            System.out.println(user);
        }

    }

Here we mainly introduce the usage of parameterType and resultType

  1. parameterType: used to correspond to the passed parameters in the interface method. Generally, the passed parameters are basic types or corresponding entity classes. If you want to transfer multiple different data, you can use the following methods: The code refers to the blogger

    1) No need to write parameterType parameter:
    Because it is multi parameter, we can't use me directly, but index. For example: #{index}
    2) Annotation based approach:

    public List<XXXBean> getXXXBeanList(@Param("id")String id, @Param("code")String code);  
    
    <select id="getXXXBeanList" resultType="XXBean">
    
      select t.* from tableName where id = #{id} and name = #{code}  
    
    </select> 
    

    Since it is multi parameter, parameterType cannot be used. Here @ Param is used to specify which one.
    3)Map encapsulation:

    public List<XXXBean> getXXXBeanList(HashMap map);  
    
    <select id="getXXXBeanList" parameterType="hashmap" resultType="XXBean">
    
      select field... from XXX where id=#{xxId} code = #{xxCode}  
    
    </select>  
    

    hashmap is configured by mybatis and can be used directly. The name of the key in the map is that, so we are #{} using that.
    4) List encapsulation

    public List<XXXBean> getXXXBeanList(List<String> list);  
    
    
    <select id="getXXXBeanList" resultType="XXBean">
      select field... from XXX where id in
      <foreach item="item" index="index" collection="list" open="(" separator="," close=")">  
        #{item}  
      </foreach>  
    </select> 
    

    List and Map operations consume a lot of resources, but sometimes it is necessary to traverse a group of data.

  2. resultType: used to define the type of returned data. It is generally the fully qualified class name of the storage class. And the return value type of the method. Generally basic types, entity classes, map s and list s.

Connection pool

In Mybatis, three different built-in data source types can be supported

typeexplain
POOLEDThe interface of DataSource is implemented and the idea of pool is used.
UNPOOLEDIt also implements the DataSource interface, but does not use the idea of pool
JDNIThe JDNI technology provided by the server is adopted, and the connection pool obtained between different servers is different

If the project is not a web or Maven war project, it cannot be used. For example, the connection pool of DBCP server is Tomcat.

affair

Generally refers to what to do or do. In computer terminology, a program execution unit that accesses and may update various data items in a database
Transactions generally have the following characteristics (ACID): atomicity, consistency, isolation and persistence

synchronize

When multiple users access the same database resources, a mechanism for permission management of access order. Used to ensure the correct reading and writing of data.

Dynamic SQL statements in Mybatis

Dynamic SQL statements commonly used in mybatis include the following categories: if, choose (when, otherwise) is equivalent to Switch, trim, where, set and foreach. Here we mainly talk about if and foreach.

<select id="selectforif" resultType="user" parameterType="User">

    select * from user where

        <if test="username != null">

           username=#{username}
        </if>
        <if test="username != null">
           and sex=#{sex}
        </if>
</select>

<select id="selectUserByListId" parameterType="com.ys.vo.UserVo" resultType="com.ys.po.User">

    select * from user

    <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 user 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>

Multi table query in Mybatis

It is necessary to establish a relationship between the information in the entity class and the relationship in the database. The resultMap is used here.

In combination with the tag attribute resultMap – the name here is the id in the resultMap attribute:

The multi table query here is one to many and many to many. The sub tags used are < Collection >

If it is only a simple one-to-one query, the sub tag < Association > is used. What this tag can do is to encapsulate an entity class, and the above collection is the way of list encapsulation.

Moreover, this multi table query also needs to be declared in the entity class at the same time, as shown in the figure:

Delayed loading of Mybatis

Delayed loading: delayed loading means that not all data requests will be requested when the database is idle during database access. When the user's data is loaded, not all data is currently necessary. At this time, it needs to be loaded on demand. The data that is not needed temporarily is loaded when needed (lazy loading).
Advantages: it speeds up the access speed of the server to the database, reduces the table level of database access, and improves the operation efficiency of the database.

Load immediately: that is, load all the data at the beginning of the method call.

Operating environment:

Delayed loading: one to many, many to many
Load now: one to one, many to one

Usage:
1) Set loading method:

By adding sub tag attributes:
One to one delayed loading:
The select here is the id of the connected SQL statement, and the javaType is the return value type

<resultMap id="findAllAccountLazy" type="com.changwu.pojo.Account">
    <id property="id" column="id"/>
    <result property="uid" column="uid"/>
    <result property="money" column="money"/>
    <!-- select Specified content, The unique method id of a single user can be queried -->
    <!-- there column attribute,Specified is select Specified in fingById Required id value-->
    <association property="user" column="uid" javaType="com.changwu.pojo.User" select="com.changwu.dao.IUserDao.findById">

    </association>
</resultMap>

One to many delayed query

<!-- todo One to many configuration delay loading -->
<resultMap id="findAllUserAndUserAccount" type="com.changwu.pojo.User">
    <id property="id" column="id"/>
    <result property="userName" column="userName"/>
    <result property="birthday" column="birthday"/>
    <result property="sex" column="sex"/>
    <result property="address" column="address"/>
    <!--One to many configuration-->
    <!--ofType Is the type of element in the collection maintained by one party-->
    <collection property="accounts" ofType="com.changwu.pojo.Account"
                 column="id" select="com.changwu.dao.IAccountDao.findAccountByUid">
    </collection>
</resultMap>

<select id="findAllUserAndUserAccount" resultMap="findAllUserAndUserAccount">
    select * from user
</select>

L1 cache and L2 cache

cache

Caching refers to the long time from receiving the request to returning the data, and the heavy burden on the database. It is not conducive to a large number of data requests, and the cache is to use the computer's own memory space for short-term storage of data. When the user initiates the request again, he can directly access the memory without accessing the database. It greatly reduces the burden of the database and reduces the time for users to wait for data.

Data suitable for caching: it is often queried and not frequently modified, and there are no strict requirements on the consistency of such data. On the contrary, data with extremely strict requirements on the consistency of data in bank exchange rate and commodity inventory are not suitable for using the caching mechanism

L1 cache

The first level cache is the cache enabled by Mybatis by default. It exists in the SQLSession object. It is created with the creation of the object, and disappears when the object dies. When the data is not modified or changed, the temporary data is generally stored in the current cache. When the data is modified or overflowed, it will be emptied. This feature also exists in the L2 cache.

L2 cache

L2 cache refers to the cache of SqlSessionFactory objects in MyBatis. Sqlsessions created by the same SqlSessionFactory object will share this L2 cache, that is, the space of a L2 cache will be shared by sqlsessions of multiple L1 caches.

Annotation development

one-on-one

@Select("select * from account") //The select here also includes Insert, Updata and Delete.
@Results(id = "account",value = {
    //First describe your own information, and then describe one-to-one information
    @Result(id = true, property = "id",column = "id"),
    @Result(property = "uid",column = "uid"),
    @Result(property = "money",column = "money"),
    @Result(property = "user",column = "uid",
            one=@One(select = "com.changwu.dao.IUserDao.findById",fetchType = FetchType.EAGER))
})
List<Account> findAll();

One to many

@Select("select * from user")
@Results(id="UserAccount",value = {
        @Result(id = true ,property = "id",column = "id"),
        @Result(property = "accounts",column = "id",
                many = @Many(select = "com.changwu.dao.IAccountDao.findAccountByUid",fetchType = FetchType.LAZY))
})
List<User> findAll();

The above referenced articles:
https://www.cnblogs.com/ZhuChangwu/p/11734347.html

Topics: Java