MyBatis-Systematic review enhancement (continuously updated from April 11, 2020)

MyBatis-Systematic review enhancement (continuously updated from April 11, 2020)

1 Introduction

The content is arranged according to the class of Qin Jiang's teacher at Station B

1.1 What is MyBatis

  • Is a first class persistence layer framework
  • Support custom SQL, stored procedure, advanced mapping
  • It avoids almost all JDBC code, manually setting parameters, getting result sets, etc.
  • Can use simple XML, annotations to configure and map native types, interfaces, POJO (Plain Old Java Objects)

1.2 Persistence layer

Endurance

The process of transforming program data from transient state to persistent state

In the past, I also used IO to write data directly in the disk file, but it was a waste of IO resources.

Why persist?

  • Important objects cannot be lost after power off (memory characteristics)
  • And the cost of memory is higher

Persistence layer

The code blocks that complete the persistence work, decomposed in 'layers'

1.3 Why use MyBatis

  • Traditional JDBC is too complicated
  • Help programmers store data in the database
  • Easy to learn
  • SQL in XML, avoid coupling with code
  • Provide object-relational mapping tags to support the mapping of objects and data
  • Support dynamic SQL
  • High market share

1.4 How to get MyBatis

  • Maven repository

    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.4</version>
    </dependency>
    
  • GItHub, the source code has been hosted so far

  • MyBatis-3 official website

2 The first MyBatis program

The general path to learn new things: build environment-> import dependencies-> write code-> test

2.1 Setting up the environment

Create a database

CREATE DATABASE mybatis;

USE mybatis;

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

INSERT INTO USER(id, NAME, pwd) VALUES
(1, '狂神', '123456'),
(2, '张三', '123456'),
(3, '李四', '1234454');

New Project

  1. New ordinary Maven project

  2. Delete the src directory (make the project a parent project)

  3. Import dependencies

    <?xml version="1.0" encoding="UTF-8"?>
    <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">
        <modelVersion>4.0.0</modelVersion>
    
        <!--父工程-->
        <groupId>com.zhangcl</groupId>
        <artifactId>mybatis-study</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <dependencies>
    
            <!--mybatis-->
            <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.4</version>
            </dependency>
    
            <!--mysql驱动-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.47</version>
            </dependency>
            <!--junit-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>
        </dependencies>
    </project>
    

2.2 Create Module

In this way, the child project does not need to import the package every time, you can use the parent project directly

1. Write the core configuration file

Write the core configuration file of Mybatis, mybatis-config.xml, in the location shown (resources directory)

! [image-20200408091254615] (D: \ Weiyun Sync Assistant \ 364291826 \ Sync Folder \ Knowledge Base \ 10-md Library Qin Jiang Teacher \ Framework \ Mybatis.assets \ image-20200408091254615.png)

Content copied from official website

<?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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:192.168.159.128:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf8"/>
                <property name="username" value="root"/>
                <property name="password" value="910613"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

** 2. Write MyBatis tool class **

package com.zhangcl.util;

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 --> sqlSession
public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = null;
            inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

3. Write code

Entity class

package com.zhangcl.pojo;

public class User {
    private int id;
    private String name;
    private String pwd;

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", pwd='" + pwd + '\'' +
                '}';
    }

    public User() {
    }

    public User(int id, String name, String pwd) {
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
}
  • Dao interface

    package com.zhangcl.dao;
    import com.zhngcl.pojo.User;
    import java.util.List;
    public interface UserDao {
        List<User> getUserList();
    }
    
  • Dao implementation

    No longer write UserDaoImpl, use a Mapper configuration file instead

    UserMapper.xml in dao package

    <?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 绑定一个对应的Dao\Mapper接口-->
    <mapper namespace="com.zhngcl.dao.UserDao">
    
        <!--select 查询语句-->
        <select id="getUserList" resultType="com.zhngcl.pojo.User">
            select * from user;
        </select>
    
    
    
    </mapper>
    

2.3 Running the test

package com.zhangcl.dao;

import com.zhangcl.pojo.User;
import com.zhangcl.util.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class UserDaoTest {

    @Test
    public void test(){
        /*获得SqlSession对象*/
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        /*执行SQL
        *   方式一
        * */
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        List<User> userList = userDao.getUserList();
        for (User user : userList) {
            System.out.println(user);
        }

        sqlSession.close();
    }
}
/*
D:\Software\jdk1.8.0_71\bin\java.exe -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2019.2\lib\idea_rt.jar=57912:D:\Program Files\JetBrains\IntelliJ IDEA 2019.2\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files\JetBrains\IntelliJ IDEA 2019.2\lib\idea_rt.jar;D:\Program Files\JetBrains\IntelliJ IDEA 2019.2\plugins\junit\lib\junit5-rt.jar;D:\Program Files\JetBrains\IntelliJ IDEA 2019.2\plugins\junit\lib\junit-rt.jar;D:\Software\jdk1.8.0_71\jre\lib\charsets.jar;D:\Software\jdk1.8.0_71\jre\lib\deploy.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\access-bridge-64.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\cldrdata.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\dnsns.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\jaccess.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\jfxrt.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\localedata.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\nashorn.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\sunec.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\sunjce_provider.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\sunmscapi.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\sunpkcs11.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\zipfs.jar;D:\Software\jdk1.8.0_71\jre\lib\javaws.jar;D:\Software\jdk1.8.0_71\jre\lib\jce.jar;D:\Software\jdk1.8.0_71\jre\lib\jfr.jar;D:\Software\jdk1.8.0_71\jre\lib\jfxswt.jar;D:\Software\jdk1.8.0_71\jre\lib\jsse.jar;D:\Software\jdk1.8.0_71\jre\lib\management-agent.jar;D:\Software\jdk1.8.0_71\jre\lib\plugin.jar;D:\Software\jdk1.8.0_71\jre\lib\resources.jar;D:\Software\jdk1.8.0_71\jre\lib\rt.jar;D:\Software-idea\Project-QinJiang\com.zhangcl\mybatis-01\target\test-classes;D:\Software-idea\Project-QinJiang\com.zhangcl\mybatis-01\target\classes;D:\Software-idea\MavenRepository\repo-3.6.1\org\mybatis\mybatis\3.5.4\mybatis-3.5.4.jar;D:\Software-idea\MavenRepository\repo-3.6.1\mysql\mysql-connector-java\5.1.47\mysql-connector-java-5.1.47.jar;D:\Software-idea\MavenRepository\repo-3.6.1\junit\junit\4.12\junit-4.12.jar;D:\Software-idea\MavenRepository\repo-3.6.1\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.zhangcl.dao.UserDaoTest
打桩1mybatis-config.xml
打桩2java.io.BufferedInputStream@28ba21f3
打桩3org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@61f8bee4
Wed Apr 08 15:37:09 CST 2020 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
User{id=1, name='狂神', pwd='123456'}
User{id=2, name='张三', pwd='123456'}
User{id=3, name='李四', pwd='1234454'}
*/

2.4 Common BUG

MapperRegistry issues

org.apache.ibatis.binding.BindingException: Type interface com.zhngcl.dao.UserDao is not known to the MapperRegistry.

solve:

Make sure there is the registered configuration of Mapper in the core configuration file

in mybatis-config.xml

    <!--每个*Mapper.xml都需要在这里注册-->
    <mappers>
         <mapper resource="com/zhngcl/dao/UserMapper.xml"></mapper>
    </mappers>

★ Could not find resource .............UserMapper.xml

Maven resource failed to export to target

D:\Software\jdk1.8.0_71\bin\java.exe -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2019.2\lib\idea_rt.jar=62645:D:\Program Files\JetBrains\IntelliJ IDEA 2019.2\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files\JetBrains\IntelliJ IDEA 2019.2\lib\idea_rt.jar;D:\Program Files\JetBrains\IntelliJ IDEA 2019.2\plugins\junit\lib\junit5-rt.jar;D:\Program Files\JetBrains\IntelliJ IDEA 2019.2\plugins\junit\lib\junit-rt.jar;D:\Software\jdk1.8.0_71\jre\lib\charsets.jar;D:\Software\jdk1.8.0_71\jre\lib\deploy.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\access-bridge-64.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\cldrdata.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\dnsns.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\jaccess.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\jfxrt.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\localedata.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\nashorn.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\sunec.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\sunjce_provider.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\sunmscapi.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\sunpkcs11.jar;D:\Software\jdk1.8.0_71\jre\lib\ext\zipfs.jar;D:\Software\jdk1.8.0_71\jre\lib\javaws.jar;D:\Software\jdk1.8.0_71\jre\lib\jce.jar;D:\Software\jdk1.8.0_71\jre\lib\jfr.jar;D:\Software\jdk1.8.0_71\jre\lib\jfxswt.jar;D:\Software\jdk1.8.0_71\jre\lib\jsse.jar;D:\Software\jdk1.8.0_71\jre\lib\management-agent.jar;D:\Software\jdk1.8.0_71\jre\lib\plugin.jar;D:\Software\jdk1.8.0_71\jre\lib\resources.jar;D:\Software\jdk1.8.0_71\jre\lib\rt.jar;D:\Software-idea\Project-QinJiang\com.zhangcl\mybatis-01\target\test-classes;D:\Software-idea\Project-QinJiang\com.zhangcl\mybatis-01\target\classes;D:\Software-idea\MavenRepository\repo-3.6.1\org\mybatis\mybatis\3.5.4\mybatis-3.5.4.jar;D:\Software-idea\MavenRepository\repo-3.6.1\mysql\mysql-connector-java\5.1.47\mysql-connector-java-5.1.47.jar;D:\Software-idea\MavenRepository\repo-3.6.1\junit\junit\4.12\junit-4.12.jar;D:\Software-idea\MavenRepository\repo-3.6.1\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.zhangcl.dao.UserDaoTest,test

java.lang.ExceptionInInitializerError
	at com.zhangcl.dao.UserDaoTest.test(UserDaoTest.java:16)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Caused by: org.apache.ibatis.exceptions.PersistenceException: 
### Error building SqlSession.
### The error may exist in com/zhngcl/dao/UserMapper.xml
### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com/zhngcl/dao/UserMapper.xml
	at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
	at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:80)
	at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:64)
	at com.zhngcl.util.MybatisUtils.<clinit>(MybatisUtils.java:20)
	... 23 more
Caused by: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com/zhngcl/dao/UserMapper.xml
	at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:121)
	at org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(XMLConfigBuilder.java:98)
	at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:78)
	... 25 more
Caused by: java.io.IOException: Could not find resource com/zhngcl/dao/UserMapper.xml
	at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:114)
	at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:100)
	at org.apache.ibatis.builder.xml.XMLConfigBuilder.mapperElement(XMLConfigBuilder.java:372)
	at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:119)
	... 27 more


Process finished with exit code -1

solve:

Need pom.xmlto introduce import and export allocation of resources, in order to ensure the success of our project pom.xml in the parent's and the module are added

    <!--在build中配置resources, 防止资源导入导出失败问题-->
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</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 creating document instance.

java.lang.ExceptionInInitializerError
	at com.zhangcl.dao.UserDaoTest.test(UserDaoTest.java:16)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Caused by: org.apache.ibatis.exceptions.PersistenceException: 
### Error building SqlSession.
### Cause: org.apache.ibatis.builder.BuilderException: Error creating document instance.  Cause: com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: 1 字节的 UTF-8 序列的字节 1 无效。
	at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
	at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:80)
	at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:64)
	at com.zhngcl.util.MybatisUtils.<clinit>(MybatisUtils.java:21)
	... 23 more
Caused by: org.apache.ibatis.builder.BuilderException: Error creating document instance.  Cause: com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: 1 字节的 UTF-8 序列的字节 1 无效。
	at org.apache.ibatis.parsing.XPathParser.createDocument(XPathParser.java:263)
	at org.apache.ibatis.parsing.XPathParser.<init>(XPathParser.java:127)
	at org.apache.ibatis.builder.xml.XMLConfigBuilder.<init>(XMLConfigBuilder.java:81)
	at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:77)
	... 25 more
Caused by: com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: 1 字节的 UTF-8 序列的字节 1 无效。
	at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.invalidByte(UTF8Reader.java:701)
	at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.read(UTF8Reader.java:567)
	at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(XMLEntityScanner.java:1793)
	at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.scanData(XMLEntityScanner.java:1292)
	at com.sun.org.apache.xerces.internal.impl.XMLScanner.scanComment(XMLScanner.java:778)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanComment(XMLDocumentFragmentScannerImpl.java:1039)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:904)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
	at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:243)
	at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339)
	at org.apache.ibatis.parsing.XPathParser.createDocument(XPathParser.java:261)
	... 28 more

Solution: Modify the entire Idea character set, and then create a new xml file, the content can be transferred into

May also fail to connect

  1. There may be a linux firewall pot, firewalld
  2. You may also need to temporarily remove useSSL in the URL, which has been resolved!

3 CRUD

3.1 Supplementary knowledge

Record a few places that are easy to go wrong:

  • Add, delete, modify, commit transactions
  • The resource path of the mapers tag should be separated by slashes, not the point of the package path
  • IDEA error message read from back to front

3.2 Universal Map

Use Map to save data

You can customize any field name when saving data:

  1. Write Mapper interface: UserDao.java (can also be changed to UserMapper)

        /*增2: Map保存User信息*/
        int addUserInMap(Map<String, Object> map);
    
  2. Write * Mapper.xml: UserMapper.xml

        <!--增2 User in a Map-->
        <insert id="addUserInMap" parameterType="map">
            insert into user(id, name, pwd) values(#{userId}, #{userName}, #{password});
        </insert>
    

    Note:, parameterType="map" here is the map

  3. Write unit test code: UserDaoTest.java

        /*增2 User in a Map*/
        @Test
        public void addUserInMap(){
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("userId", 4);
            map.put("userName", "老四");
            map.put("password", "4444");
    
            userDao.addUserInMap(map);
            sqlSession.commit();
            sqlSession.close();
        }
    

Note: The highlight here is that the key value setting of the map is intentionally different from the columnName in the database, which is one of the characteristics of the universal map we want to show

Map usage summary

  • If you use a POJO object to pass parameters, the underlying layer will directly take the object attributes from the SQL execution, and the SQL statement label specifies the parameters:

    parameterType="User"

  • If you use Map to pass parameters, you must also specify the parameters in the label:

    parameterType="map"

  • If the parameter is just a + is a basic data type , you can avoid specifying the parameter Type and use it automatically.

  • When there are multiple parameters, you can use map or annotation!

3.3 Fuzzy query

Wildcard problem

  • When the transmission parameters include %wildcards, but unsafe

  • SQL splicing wildcard

    <select id="getUserLikeInMap" resultType="com.zhangcl.pojo.User">
        select * from user where name like concat("%",#{value},"%");
    </select>
    

4 Configuration XML

4.1 Introduction

XML placement

Element order

XML feature, all tags can be fixed \ prescribed order, otherwise IDE will report an error

The content of element type "configuration" must match "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)".

Need to master

  • properties
  • settings
  • typeAliases (type alias)

4.2 properties tag

You can use it to reference other external configuration files.

Order \ priority issue

External files can override the attributes in the label, but not

Test 1 pure external file

  1. Write the configuration file: db.properties in the resources directory

    driver=com.mysql.jdbc.Driver
    url="jdbc:mysql://192.168.159.128:3306/mybatis?useUnicode=true&characterEncoding=utf8
    user=root
    password=Ms_910613
    
  2. Introduced in mybatis-config.xml 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>
        <!--引入外部配置文件-->
        <properties resource="db.properties"></properties>
        
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="${driver}"/>
                    <property name="url" value="${url}"/>
                    <property name="username" value="${username}"/>
                    <property name="password" value="${password}"/>
                </dataSource>
            </environment>
        </environments>
    
        <mappers>
            <mapper resource="com/zhangcl/dao/UserMapper.xml"></mapper>
        </mappers>
    
    
    </configuration>
    

    The test passed!

Test 2 , fill in attributes in the label

  1. Cancel two attributes in external file

    driver=com.mysql.jdbc.Driver
    url=jdbc:mysql://192.168.159.128:3306/mybatis?useUnicode=false&characterEncoding=utf8
    # username=root
    # password=Ms_910613
    
  2. Instead, substitute in the configuration s tag

        <!--引入外部配置文件-->
        <properties resource="db.properties">
            <property name="username" value="root"/>
            <property name="password" value="Ms_910613"/>
        </properties>
    

    The test passed!

4.3 environments label

One important thing to remember though: While you can configure multiple environments, you can only choose ONE per SqlSessionFactory instance.

Translation \ Understanding: There can be multiple environments, but only one of them can be used at the same time.

Official website example

<environments default="development">
  <environment id="development">
    <transactionManager type="JDBC">
      <property name="..." value="..."/>
    </transactionManager>
    <dataSource type="POOLED">
      <property name="driver" value="${driver}"/>
      <property name="url" value="${url}"/>
      <property name="username" value="${username}"/>
      <property name="password" value="${password}"/>
    </dataSource>
  </environment>
</environments>

Choose Environment: Propertiesdefault="被选择环境的id"

transactionManager subtag

contain:

  • JDBC, default
  • MANAGER, the official website says that this is "inaction", to use it, you must also configure to close something

dataSource subtag

Connection pool, contains: POOLED (default) | UNPOOLED | JNDI

4.4 typeAliases (type aliases)

effect

  • Can be written Userinstead com.zhangcl.pojo.User(POJO is used less often)

        <typeAliases>
            <typeAlias type="com.zhangcl.pojo.User" alias="User"/>
        </typeAliases>
    
    • Can DIY alias
  • Can let MyBatis scan the Java Bean in the specified package

    <typeAliases>
    	<package name="com.zhangcl.pojo"/>
    </typeAliases>
    
    • If you also need a DIY alias, you can also use annotations

      @Alias("userAlias")
      public class User{
          // ...
      }
      

4.5 settings

Need to focus on

  • cacheEnabled Globally enable or disable any cache configured in all mapper configuration files, default true
  • lazyLoadingEnabled Global switch for lazy loading. When turned on, all associated objects will be lazily loaded. In a specific association relationship, you can set the fetchTypeproperty to override the switch state of the item, the default is false
  • mapUnderscoreToCamelCase, Hump mapping, default false

4.6 Other

The probability used is extremely low:

  • typeHandler (type handler)
  • objectFactory (object factory)
  • plugins
    • MyBatis-plus

4.7 Mappers

MapperRegistry : Mapper file that stores our SQL binding

  • One way: by binding .xmlregistration file

    <mapppers>
    	<mapper resource="com/zhangcl/dao/UserMapper.xml"></mapper>
    </mapppers>
    
  • Second way: by binding DAO interface .javaregistration documents

    <mappers>
    	<mapper class="com.zhangcl.dao.UserDao"></mapper>
    </mappers>
    

    [note]

    1. The interface .java file and the corresponding .xml file name must be the same
    2. And must be in the same directory
  • Method 3: Register by scanning the package

    <mappers>
    	<package name="com.zhangcl.dao"></package>
    </mappers>
    

    [Note] (Same way 2)

5 Scope and life cycle

Incorrect use of this item will cause serious concurrency problems

  • SqlSessionFactoryBuilder

    Once created, it is no longer needed, so local variables

  • SqlSessionFactory

    At the core, it can be imagined as a database connection pool. Once created, it always exists, there is no reason to discard or create it again, so

    The best scope is application scope , singleton mode or static singleton

  • SqlSession

    A request to connect to the connection pool can correspond to multiple Mapper files

    Not thread-safe and cannot be shared, the best scope is

    Request or method scope should be closed after use, otherwise resources will be occupied

Rough diagram

! [image-20200410182859903] (D: \ Weiyun Sync Assistant \ 364291826 \ Sync Folder \ Knowledge Base \ 10-md library Qin Jiang teacher \ Framework \ Mybatis.assets \ image-20200410182859903.png)

Note: Each Mapper here represents a specific business. (Personal understanding, represents a sql a method)

6 FieldName and columnName consistency issues

Test: Inconsistent issues

  1. Database field

    ! [image-20200410192346711] (D: \ Weiyun Sync Assistant \ 364291826 \ Sync Folder \ Knowledge Base \ 10-md Library Qin Jiang Teacher \ Framework \ Mybatis.assets \ image-20200410192346711.png)

  2. The new project is actually copied and modified. And modify the User class

    public class User {
        private int id;
        private String name;
        private String password;	// 注意数据库是pwd, 而这里是password
    }
    
  3. operation result:

    User{id=2, name='张三', password='null'}
    

solve:

  • Method one, select the alias as in sql, but it is too simple, no technical content

  • Method Two, resultMap

    <resultMap id="UserMap" type="User">
        <result column="pwd" property="password"></result>
    </resultMap>
    <select id="getUserById" resultMap="UserMap" >
        select * from mybatis.user where id = #{id};
    </select>
    

changelog:
First published to blog on April 11, 2020

Guess you like

Origin www.cnblogs.com/clzhang/p/12677531.html