Mybatis - the first mybatis program

Keywords: Database MySQL Mybatis

MyBatis

If there is a problem, switch the version:

  • jdk:1.8
  • mysql:5.1.47
  • maven 3.6.1
  • IDEA

brief introduction

What is MyBatis

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.

How to get mybatis

maven warehouse: https://mvnrepository.com/artifact/org.mybatis/mybatis/3.5.7

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.7</version>
</dependency>

GitHub address: https://github.com/mybatis/mybatis-3/releases

Chinese documents: https://mybatis.org/mybatis-3/zh/index.html

Persistence

Data persistence

  • Persistence is the process of transforming program data in persistent state and transient state
    • Persistence: database (jdbc), io file persistence
    • Instantaneous: memory: power loss

Persistent layer

  • Code block that completes the persistence work
  • The layer boundary is very obvious

Why do you need MyBatis?

  • Help programmers store data into the database

  • Traditional jdbc code is too complex - > simplified - > framework

  • advantage:

    • Easy to learn
    • flexible
    • Separation of sql and code to improve maintainability
    • Provide mapping labels to support the mapping of orm fields between objects and databases
    • Provide object relationship mapping labels to support object relationship construction and maintenance
    • Provide xml tags to support writing dynamic sql
  • Many people use it!

The first MyBatis program

Idea: build environment - > Import mybatis - > write code - > test

1. Build database

#mybatis
CREATE DATABASE mybatis;

USE mybatis;

CREATE TABLE USER(
    sid INT(20) NOT NULL PRIMARY KEY,
    sname VARCHAR(30) DEFAULT NULL,
    pwd VARCHAR(30) DEFAULT NULL
)ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO USER(sid,sname,pwd) VALUES
(1,"feliks","123456"),
(2,"zhangsan","123456"),
(3,"lisi","123456")

2. New project

Create a normal maven project

Delete src directory as parent project

Import maven dependencies

<!--Parent project-->
    <groupId>net.cqwu</groupId>
    <artifactId>Mybatis-Study</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--Import dependency-->
    <dependencies>
    <!--mysql drive-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

3. 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 Core profile-->
<configuration>
    <!--environment-->
    <environments default="development">
        <environment id="development">
            <!--Things Management-->
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                                                                                    <!--xml in & No, No &amp; replace-->
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
<!--every last Mapper.xml All need to be in Mybatis Register in core profile-->
    <mappers>
        <mapper resource="net/cqwu/dao/UserMapper.xml"/>
    </mappers>
</configuration>
  • Write mybatis tool class
package net.cqwu.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

//Sqlsessionfactory -- > build sqlSession
public class MybatisUtils {

    //Promote scope
    private static SqlSessionFactory sqlSessionFactory;

    static {

        try {
            //Step 1 of using Mybatis: get sqlSessionFactory object
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    //Now that we have SqlSessionFactory, as the name suggests, we can get an instance of SqlSession from it.
    // SqlSession provides all the methods required to execute SQL commands in the database
    public static SqlSession getSqlSession(){
//        SqlSession sqlSession = sqlSessionFactory.openSession();
//        return sqlSession;
        return sqlSessionFactory.openSession();
    }
}

4. Write code

  • Entity class
public class User {
    private int sid;
    private String sname;
    private String pwd;

    public User() {
    }

    public User(int sid, String sname, String pwd) {
        this.sid = sid;
        this.sname = sname;
        this.pwd = pwd;
    }
    //Omit getter setter toString
  • Dao interface
public interface UserDao {
    List<User> getUserList();
}
  • Interface implementation class

    From the original UserDaoImpl to a Mapper configuration file

<?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">
<!--Namespace namespace = Bind a corresponding Dao/Mapper Interface-->
<mapper namespace="net.cqwu.dao.UserDao">
          <!--Method name-->           <!--Returns the fully qualified name-->
    <select id="getUserList" resultType="net.cqwu.pojo.User">
        select * from mybatis.user
    </select>

</mapper>

4. Test

  • junit
public class UserDaoTest {
    @Test
    public void test(){

        //Step 1: get SqlSession
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //Step 2: execute SQL -- > method 1: getMapper
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> userList = mapper.getUserList();
        
        //Method 2: old, not recommended
//        List<User> userList = sqlSession.selectList("net.cqwu.dao.UserDao.getUserList");

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

        //Close SqlSession
        sqlSession.close();
    }
}

You may encounter problems:

  1. The profile is not registered
  2. Binding interface error
  3. Wrong method name
  4. Wrong return type
  5. Maven export resources

Summary:

Seven steps:

Three core interfaces of Mybatis

SqlSessionFactoryBuilder

This class can be instantiated, used, and discarded once created SqlSessionFactory,
You don't need it anymore. therefore SqlSessionFactoryBuilder Instance
 The best scope is the method scope (that is, the local method variable). You can reuse SqlSessionFactoryBuilder 
To create multiple SqlSessionFactory Instance, but it's best not to keep it all the time,
To ensure that all XML Parsing resources can be released to more important things.

SqlSessionFactory

SqlSessionFactory Once created, it should always exist during the operation of the application,
There is no reason to discard it or recreate another instance. 
use SqlSessionFactory The best practice is not to create multiple times during application operation,
Multiple reconstruction SqlSessionFactory It is regarded as a code "bad habit".
therefore SqlSessionFactory The best scope for is the application scope. 
There are many ways to do this. The simplest is to use singleton mode or static singleton mode.

SqlSession

Each thread should have its own SqlSession example.
SqlSession The instance of is not thread safe, so it cannot be shared,
So its best scope is the request or method scope. 
Absolutely not SqlSession The instance reference is placed in the static field of a class,
Not even instance variables of a class. And never SqlSession The reference of the instance is placed in any type
 In the managed scope of, such as Servlet In frame HttpSession. 
 If you're using one now Web Framework, considering SqlSession Put it in one
 and HTTP The request is in a similar scope. In other words, every time you receive HTTP Request,
 You can open one SqlSession,When a response is returned, close it. 
 This closing operation is very important. In order to ensure that the closing operation can be performed every time,
 You should put this close operation in finally Block in

Standard mode to ensure that SqlSession is turned off:

try (SqlSession session = sqlSessionFactory.openSession()) {
  // Your application logic code
}

Errors encountered:

Test error

java.lang.ExceptionInInitializerError
	at net.cqwu.dao.UserDaoTest.test(UserDaoTest.java:15)

solve:

  • Method 1: copy a copy of UserMapper.xml to the same path in target \ test classes
  • Method 2: add the following configuration in pom.xml
  • If an error is still reported, change true in true to false

maven may encounter the problem that the written configuration file cannot be exported or effective because the contract is greater than the configuration. Solution:

<!--stay build Medium configuration resourse,To prevent the failure of resource export-->
<build>
    <resources>
        <resource>
            <directory>src/main/resource</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

Error in IDEA linked database

java.lang.RuntimeException: com.mysql.cj.exceptions.InvalidConnectionAttribute

Reason: serverTimezone is not specified

resolvent:

Fill in the following fields in the URL:

jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC


thanks for kuang😄

Posted by watts on Sat, 20 Nov 2021 13:06:01 -0800