Mybatis – Introduction (1)

A, the ORM

1. What is ORM

ORM, Object Relational Mapping, Relational database (Object Object, Mapping Mapping, Relation), ORM framework to solve the problem of program objects and Relational database Mapping.

2. ORM frameworks have those

Hibernate

  • advantages
    • Fully automatic
  • disadvantages
    • Use get, save, update methods to manipulate all fields, there is no way to use some fields.
    • Automatic generation of SQL statements, optimization is difficult
    • Dynamic SQL is not supported

Mybatis

MyBatis, a semi-automated ORM framework, solves these problems. “Semi-automation” is relative to Hibernate’s full automation, that is, it is not as high as Hibernate’s encapsulation, does not automatically generate all SQL statements, mainly to solve the PROBLEM of SQL and object mapping. In MyBatis, SQL and code are separated, so the ability to write SQL will basically use MyBatis, without additional learning costs.

Core features

  1. Connection pooling is used to manage connections
  2. SQL and code separation, centralized management
  3. Result set mapping
  4. Parameter mapping and dynamic SQL
  5. Repeated SQL extraction
  6. Cache management
  7. Plug-in mechanism

The subsequent introduction of Mybatis-Plus integrated application will quickly improve the development efficiency, so that developers pay more attention to business development.

Mybatis core object and life cycle

Official documentation: mybatis.org/mybatis-3/z…

SqlSessionFactoryBuilder

This class can be instantiated, used, and discarded, and is no longer needed once the SqlSessionFactory has been created. So the best scope for SqlSessionFactoryBuilder instances is the method scope (that is, local method variables). You can reuse SqlSessionFactoryBuilder to create multiple instances of SqlSessionFactory, but it’s best not to keep it around all the time to ensure that all XML parsing resources can be freed up for more important things.

SqlSessionFactory

Once created, the SqlSessionFactory should persist for the duration of the application, and there is no reason to discard it or recreate another instance. The best practice with SqlSessionFactory is not to create the SqlSessionFactory more than once while the application is running. Rebuilding SqlSessionFactory more than once is considered a code “bad habit.” So the best scope for SqlSessionFactory is the application scope. There are many ways to do this, the easiest is to use singleton or static singleton.

Session

Each thread should have its own INSTANCE of SqlSession. An instance of SqlSession is not thread-safe and therefore cannot be shared, so its best scope is the request or method scope. A reference to an SqlSession instance must never be placed in a static domain of a class, or even an instance variable of a class. A reference to an SqlSession instance should also never be placed in any type of managed scope, such as HttpSession in the Servlet framework. If you are currently using a Web framework, consider putting SqlSession in a scope similar to HTTP requests. In other words, each time an HTTP request is received, an SqlSession can be opened, and when a response is returned, it can be closed. The close operation is important, and to ensure that the close operation is performed every time, you should put the close operation ina finally block. The following example is a standard mode to ensure that SqlSession is closed:

Mapper

Mappers are interfaces that bind mapping statements. The instance of the mapper interface is obtained from SqlSession. Although technically speaking, the maximum scope of any mapper instance is the same as the SqlSession from which they are requested. But the method scope is the most appropriate scope for the mapper instance. That is, mapper instances should be retrieved in the methods that call them and then discarded after use. The mapper instance does not need to be explicitly closed. Although keeping the mapper instance in the entire request scope is fine, you will soon find that managing too many resources like SqlSession in this scope can get you too busy.

Three, Mybatis introduction case

github:[email protected]: stopping5 / orm – guide. Git

1. Introduce mybatis dependencies


      
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>stopping-orm</artifactId>
        <groupId>com.stopping</groupId>
        <version>1.0 the SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>mybatis-base</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.3</version>
        </dependency>
		<! -- Version 8.0.13 requires cJ Driver -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.13</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
        </dependency>
    </dependencies>
</project>
Copy the code

2. Mybatis -config configuration file

Configure the file node structure

  • Configuration
    • Properties
    • Settings
    • typeAliases
    • typeHandlers
    • objectFactory
    • Plugins
    • Environments
      • Environment (environment variable)
        • transactionManager
        • A dataSource
    • DatabaseIdProvider (Database vendor Identity)
    • Mappers (mapper)

Configuration File Description

In this case, only environments and Mappers configuration information is used.

environments

Environments is used to configure transaction management and data sources. We have configured only one data source. If our business systems have different databases and libraries, we need to configure multiple data sources.

mappers

Mappers are mapped to our mapper file to tell Mybatis where to find SQL statements. There are four ways:

<! -- Use a resource reference relative to the classpath -->
<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 locator (URL) -->
<mappers>
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  <mapper url="file:///var/mappers/BlogMapper.xml"/>
  <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
<! Implement the fully qualified class name of the class using the mapper interface
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
<! Register all mapper interface implementations as mapper
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>
Copy the code

Case profile


      
<! DOCTYPEconfiguration
        PUBLIC "- / / mybatis.org//DTD Config / 3.0 / EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <! -- Environment Configuration -->
    <environments default="development">
        <environment id="development">
            <! -- Transaction configuration -->
            <transactionManager type="JDBC"/>
            <! -- Data source -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value='jdbc:mysql://localhost:3306/test? useUnicode=true&amp;useJDBCCompliantTimezoneShift=true&amp;useLegacyDatetimeCode=false&amp;serverTimezone=UTC'/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <! -- mapper -->
    <mappers>
        <mapper resource="mapper/UserMapper.xml"></mapper>
    </mappers>
</configuration>
Copy the code

3. The entity class

Take simple user information as an example

Database table structure User

CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `avatar` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `password` varchar(300) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `username` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL.PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `UK_ob8kqyqqgmefl0aco34akdtpe` (`email`) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC
Copy the code

Corresponding entity class

@Data
@Accessors(chain = true)
public class User implements Serializable {
    /** * id * */
    private Integer id;
    /** ** avatar ** /
    private String avatar;
    /** ** email ** /
    private String email;
    /** * account ** /
    private String name;
    /** * Password ** /
    private String password;
    /** * User name ** /
    private String username;
}
Copy the code

4. mapper

Usermapper. Java needs to be bound to usermapper. XML, which is bound to UserMapper. Java through the namespace in Usermapper. XML.

UserMapper.java

@Mapper
public interface UserMapper {
    /** * query user information ** /
    List<User> selectUser(a);

    /** * New user ** /
    void insertUser(@Param("user")User user);
}
Copy the code

UserMapper.xml

In usermapper.xml, SQL is written in place. In addition to curd tags such as SELECT and INSERT, there are dynamic SQL tags such as if, Choose, trim, and foreach, which will be described in more detail later.


      
<! DOCTYPEmapper
        PUBLIC "- / / mybatis.org//DTD Mapper / 3.0 / EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.stopping.mapper.UserMapper">
    <insert id="insertUser" parameterType="com.stopping.model.User">
        insert into user(name,email,username,password) value(
            #{user.name},
            #{user.email},
            #{user.username},
            #{user.password});
    </insert>
    <select id="selectUser" resultType="com.stopping.model.User">
        select * from user order by id;
    </select>
</mapper>
Copy the code

So far, we have data sources, transaction management, Mapper mapping, entity classes.

5. Test

class UserMapperTest {

    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        // By calling the sqlSession encapsulated method
        User user = new User();
        			user.setName("tom").setUsername("tom").setEmail("[email protected]").setPassword("123456");
        userMapper.insertUser(user);
        List<User> users = userMapper.selectUser();
        for (User u : users) {
            System.out.println("Get name :"+u.getName()); }}}Copy the code

Output structure

Stopping to obtain the name: Tom To obtain the name :jobCopy the code