一 概念
1. 什么是 MyBatis?
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
2. SqlSessionFactory
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 是单个数据库映射关系经过编译后的内存映像。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的 Configuration 的实例构建出 SqlSessionFactory 的实例。SqlSessionFactory 是创建 SqlSession 的工厂。
3. SqlSession
SqlSession 是执行持久化操作的对象,它完全包含了面向数据库执行 SQL 命令所需的所有方法,可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。在使用完 SqlSession 后我们应该使用 finally 块来确保关闭它。
4. SqlSessionFactoryBuilder
这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。 你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但最好还是不要一直保留着它,以保证所有的 XML 解析资源可以被释放给更重要的事情。
二 操作步骤
2.1 启动MySQL数据库服务(使用容器)
docker run -d --restart always --name mysql -e MYSQL_ROOT_PASSWORD='drh123' -v ${PWD}/data:/var/lib/mysql -p 3306:3306 mysql:5.7.28
2.2 创建库、表
CREATE DATABASE mybatis DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE USER 'mybatis'@'%' IDENTIFIED BY 'drh123';
GRANT ALL PRIVILEGES ON mybatis.* to mybatis@'%' IDENTIFIED BY 'drh123' WITH GRANT OPTION;
CREATE TABLE user(
id int primary key auto_increment,
username varchar(20),
telephone varchar(20)
);
INSERT INTO mybatis.user (id, username, telephone) VALUES (1, 'Maria', '13813813802');
INSERT INTO mybatis.user (id, username, telephone) VALUES (2, 'Ivan', '13813813801');
INSERT INTO mybatis.user (id, username, telephone) VALUES (6, 'John', '13813813803');
INSERT INTO mybatis.user (id, username, telephone) VALUES (7, 'John', '13813813803');
INSERT INTO mybatis.user (id, username, telephone) VALUES (8, 'John', '13813813803');
INSERT INTO mybatis.user (id, username, telephone) VALUES (9, 'John', '13813813803');
2.3 创建 Maven 项目
mvn archetype:generate -DgroupId=com.ivandu.mybatis -DartifactId=mybatis -DarchetypeArtifactId=maven-archetype-quickstart
2.4 配置 Maven 项目 pom.xml
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ivandu.mybatis</groupId>
<artifactId>mybatis</artifactId>
<packaging>jar</packaging>
<version>1.0.0</version>
<name>mybatis</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.32</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
</build>
</project>
特别注意的是:系统提示找不到 config.xml 或找不到对应的类文件时,可以在 pom.xml 加入:
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
</build>
2.5 配置 resources/mybatis.cfg.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>
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
<typeAliases>
<package name="com.ivandu.mybatis.model"/>
</typeAliases>
<!-- 配置 mybatis 运行环境 -->
<environments default="development">
<environment id="development">
<!-- type="JDBC" 代表直接使用 JDBC 的提交和回滚设置 -->
<transactionManager type="JDBC"/>
<!-- POOLED 表示支持 JDBC 数据源连接池 -->
<!-- 数据库连接池,由 Mybatis 管理,数据库名是 mybatis,MySQL 用户名 mybatis,密码为:drh123 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://10.1.1.88:3306/mybatis?useSSL=false"/>
<property name="username" value="mybatis"/>
<property name="password" value="drh123"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/ivandu/mybatis/mapper/UserMapper.xml"/>
</mappers>
</configuration>
在 mybatis.cfg.xml 加载 mapper:
<mappers>
<!-- 通过 mapper 接口包加载整个包的映射文件 -->
<package name="com.ivandu.mybatis.mapper" />
</mappers>
为 Java Bean 取别名:
<!-- 为 JavaBean 起类别名 -->
<typeAliases>
<!-- 指定一个包名起别名,将包内的 Java 类的类名作为类的类别名 -->
<package name="com.ivandu.mybatis.model" />
</typeAliases>
- <settings>中的logImpl属性配置指定使用LOG4J输出日志。
- <typeAliases>元素下面配置了一个包的别名,通常确定一个类的时候需要使用类的全限定名称,例如:com.ivandu.mybatis.model.User。在MyBatis中需要频繁用到类的全限定名称,为了方便使用,我们配置了 com.ivandu.mybatis.model包,这样配置后,在使用类的时候不需要写包名的部分,只使用Country即可。
- <environments>环境配置中主要配置了数据库连接,数据库的 url 为jdbc:mysql://10.1.1.88:3306/mybatis,后面的username和password分别是数据库的用户名和密码。
- <mappers>中配置了一个包含完整类路径的CountryMapper.xml,这是一个MyBatis的SQL语句和映射配置文件。
需要注意顺序:typeAliases -> environments -> mappers。
2.6 创建 model
package com.ivandu.mybatis.model;
public class User {
private Integer id;
private String username;
private String telephone;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
}
2.7 创建 mapper
package com.ivandu.mybatis.mapper;
import com.ivandu.mybatis.model.User;
import java.util.List;
public interface UserMapper {
void insertUser(User user) throws Exception;
void updateUser(User user) throws Exception;
void deleteUser(Integer id) throws Exception;
User selectUserById(Integer id) throws Exception;
List<User> selectAllUsers() throws Exception;
}
在 mapper 包内定义操作 model 的接口,接口内包括对 model 增删改查的全部方法。同时创建对应的 mapper xml 配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ivandu.mybatis.mapper.UserMapper">
<!-- 自定义返回结果集 -->
<resultMap id="userMapper" type="User">
<id property="id" column="id" javaType="Integer"/>
<result property="username" column="username" javaType="String"/>
<result property="telephone" column="telephone" javaType="String"/>
</resultMap>
<!-- 定义 SQL 语句,其中 id 需要和接口中的方法名一致 -->
<!-- useGeneratedKeys:实现自动生成主键 -->
<!-- keyProperty: 唯一标记一个属性 -->
<!-- parameterType 指明查询时使用的参数类型,resultType 指明查询返回的结果集类型 -->
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
insert into user (username, telephone)
values (#{username}, #{telephone})
</insert>
<update id="updateUser" parameterType="User">
update user
set username=#{username}
where id = #{id}
</update>
<delete id="deleteUser" parameterType="Integer">
delete
from user
where id = #{id}
</delete>
<!-- 如未为 Java Bean 起类别名,resultType="com.ivandu.mybatis.model.User" -->
<!-- 使用 resultType 时,一定要保证,你属性名与字段名相同;如果不相同,就使用 resultMap -->
<select id="selectUserById" parameterType="int" resultType="User">
select *
from user
where id = #{id}
</select>
<select id="selectAllUsers" resultMap="userMapper">
select *
from user
</select>
</mapper>
2.8 配置 resources/log4j.peoperties
# Global logging configuration
log4j.rootLogger=ERROR, stdout
# mybatis logging
log4j.logger.com.ivandu.mybatis.mapper=TRACE
# Console output
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
MyBatis 日志的最低级别是 TRACE,在这个日志级别下,MyBatis会输出执行 SQL 过程中的详细信息,这个级别适合在开发时使用。
2.9 测试
package com.ivandu.mybatis;
import com.ivandu.mybatis.mapper.UserMapper;
import com.ivandu.mybatis.model.User;
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 org.junit.*;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
public class UserMapperTest {
private static SqlSessionFactory sqlSessionFactory;
@BeforeClass
public static void init() throws IOException {
Reader reader = Resources.getResourceAsReader("mybatis.cfg.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
reader.close();
}
// 插入记录
@Test
public void insertUser() {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setId(3);
user.setUsername("John");
user.setTelephone("13813813803");
try {
userMapper.insertUser(user);
sqlSession.commit();
} catch (Exception e)
{
e.printStackTrace();
sqlSession.rollback();
} finally {
sqlSession.close();
}
}
// 使用 UserMapper接口查询
@Test
public void selectAllUsersMapper() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> users = userMapper.selectAllUsers();
for (User user : users) {
System.out.printf("%d %s %s\n", user.getId(), user.getUsername(), user.getTelephone());
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 删除记录
@Test
public void deleteUser(){
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
try {
userMapper.deleteUser(4);
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
sqlSession.rollback();
} finally {
sqlSession.close();
}
}
// 更新记录
@Test
public void updateUser(){
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user;
try {
user = userMapper.selectUserById(1);
user.setUsername("Lily");
userMapper.updateUser(user);
sqlSession.commit();
} catch ( Exception e) {
e.printStackTrace();
sqlSession.rollback();
} finally {
sqlSession.close();
}
}
// 查询所有用户
@Test
public void selectAllUsers() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
List<User> userList = sqlSession.selectList("selectAllUsers");
System.out.println("查找所有用户信息,执行结果如下:");
for (User user: userList) {
System.out.printf("%d %s %s\n",user.getId(),user.getUsername(),user.getTelephone());
}
}
}
// 根据用户id进行查询
@Test
public void selectUserById() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.selectUserById(1);
System.out.println("按ID进行查找,结果如下:");
System.out.println(user.getId() + " " + user.getUsername() + " " + user.getTelephone());
} catch (Exception e) {
e.printStackTrace();
}
}
}
通过 Resources 工具类将mybatis.cfg.xml配置文件读入 Reader。·再通过 SqlSessionFactoryBuilder 建造类使用Reader创建 SqlSessionFactory 工厂对象。在创建 SqlSessionFactory 对象的过程中,首先解析 mybatis.cfg.xml 配置文件,读取配置文件中的 mappers 配置后会读取全部的 UserMapper.xml 进行具体方法的解析,在这些解析完成后,SqlSessionFactory 就包含了所有的属性配置和执行 SQL 的信息。· 使用时通过 SqlSessionFactory 工厂对象获取一个 SqlSession。·通过 SqlSession 的 selectList 方法查找到 UserMapper.xml 中 id="selectAll"的方法,执行SQL 查询。MyBatis 底层使用 JDBC 执行 SQL,获得查询结果集 ResultSet 后,根据 resultType 的配置将结果映射为 User 类型的集合,返回查询结果。
此外,本次测试使用了** try-with-resource** 的异常处理机制,在此简单说明。传统的手动释放外部资源一般放在一般放在 try{}catch(){}finally{} 机制的 finally代 码块中,因为 finally 代码块中语句是肯定会被执行的,即保证了外部资源最后一定会被释放。同时考虑到 finally 代码块中也有可能出现异常,finally 代码块中也有一个 try{}catch(){},这种写法是经典的传统释放外部资源方法,显然是非常繁琐的。
JDK1.7之后有了 try-with-resource 处理机制。首先被自动关闭的资源需要实现 Closeable 或者 AutoCloseable 接口,因为只有实现了这两个接口才可以自动调用 close() 方法去自动关闭资源。写法为 try(){}catch(){},将要关闭的外部资源在try()中创建,catch() 捕获处理异常。其实 try-with-resource 机制是一种语法糖,其底层实现原理仍然是 try{}catch(){}finally{} 写法,不过在 catch(){} 代码块中有一个 addSuppressed() 方法,即异常抑制方法。如果业务处理和关闭连接都出现了异常,业务处理的异常会抑制关闭连接的异常,只抛出处理中的异常,仍然可以通过 getSuppressed() 方法获得关闭连接的异常。
三 Mybatis 配置
3.1 配置文件
MyBatis 配置文件的 **configuration **标签主要包括:
- configuration 配置
- properties 属性
- settings 设置
- typeAliases 类型命名
- typeHandlers 类型处理器
- objectFactory 对象工厂
- plugins 插件
- environments 环境
- environment 环境变量
- transactionManager 事务管理器
- databaseIdProvider 数据库厂商标识
- mappers 映射器
这些属性是可外部配置且动态替换的,例如在上节的基础上在目录 src/resources 下建立了 Java 属性文件 config.properties ,用于配置一些数据库的信息,内容如下:
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://10.1.1.88:3306/mybatis
username=mybatis
password=drh123
注:MyBatis 加载属性的顺序如下(引用自 MyBatis 中文文档:properties):
- 首先读取 properties 元素体内指定的属性。
- 然后根据 properties 元素中的 resource 属性读取类路径下属性文件或根据 url 属性指定的路径读取属性文件,并覆盖已读取的同名属性。
- 最后读取作为方法参数传递的属性,并覆盖已读取的同名属性。
3.2 settings 设置
settings 是 MyBatis 极为重要的设置,它们会改变 MyBatis 的运行时行为,如开启二级缓存、开启延迟加载等。
settings 设置的详细情况请参考 MyBatis 中文文档:settings 。
typeHandlers 的作用是实现 JDBC 类型和 Java 类型的之间的转换,MyBatis 中默认的类型处理器基本能满足日常需求,自定义 typeHandlers 在这里不做介绍。
类型处理器 | Java 类型 | JDBC 类型 |
BooleanTypeHandler | java.lang.Boolean, boolean | 数据库兼容的 BOOLEAN |
ByteTypeHandler | java.lang.Byte, byte | 数据库兼容的 NUMERIC 或 BYTE |
ShortTypeHandler | java.lang.Short, short | 数据库兼容的 NUMERIC 或 SHORT INTEGER |
IntegerTypeHandler | java.lang.Integer, int | 数据库兼容的 NUMERIC 或 INTEGER |
LongTypeHandler | java.lang.Long, long | 数据库兼容的 NUMERIC 或 LONG INTEGER |
FloatTypeHandler | java.lang.Float, float | 数据库兼容的 NUMERIC 或 FLOAT |
DoubleTypeHandler | java.lang.Double, double | 数据库兼容的 NUMERIC 或 DOUBLE |
BigDecimalTypeHandler | java.math.BigDecimal | 数据库兼容的 NUMERIC 或 DECIMAL |
StringTypeHandler | java.lang.String | CHAR, VARCHAR |
ClobReaderTypeHandler | java.io.Reader | - |
ClobTypeHandler | java.lang.String | CLOB, LONGVARCHAR |
NStringTypeHandler | java.lang.String | NVARCHAR, NCHAR |
NClobTypeHandler | java.lang.String | NCLOB |
BlobInputStreamTypeHandler | java.io.InputStream | - |
ByteArrayTypeHandler | byte[] | 数据库兼容的字节流类型 |
BlobTypeHandler | byte[] | BLOB, LONGVARBINARY |
DateTypeHandler | java.util.Date | TIMESTAMP |
DateOnlyTypeHandler | java.util.Date | DATE |
TimeOnlyTypeHandler | java.util.Date | TIME |
SqlTimestampTypeHandler | java.sql.Timestamp | TIMESTAMP |
SqlDateTypeHandler | java.sql.Date DATE | |
SqlTimeTypeHandler | java.sql.Time TIME | |
ObjectTypeHandler | Any | OTHER 或未指定类型 |
EnumTypeHandler | Enumeration Type | VARCHAR-任何兼容的字符串类型,存储枚举的名称(而不是索引) |
EnumOrdinalTypeHandler | Enumeration Type | 任何兼容的 NUMERIC 或 DOUBLE 类型,存储枚举的索引(而不是名称) |
MyBatis 的环境配置实际是数据源的配置。MyBatis 可以配置多个环境,帮助你将 SQL 映射对应到多种数据库。
注:尽管可以配置多个环境,每个 SqlSessionFactory 实例只能对应一个数据库,有几个数据库就需要创建几个 SqlSessionFactory 实例。
接受环境配置的两个方法:
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader, environment);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader, environment,properties);
如果忽略了环境参数,默认环境将会被加载:
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader,properties);
3.3 transactionManager 事务管理器
MyBatis 中的两种事务管理器,即 type="[JDBC|MANAGED]":
- JDBC:直接使用 JDBC 的提交和回滚设置;
- MANAGED:让容器来管理事务的整个生命周期。
dataSource 数据源:
dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。MyBatis 三种內建的数据源类型,即 type="[UNPOOLED|POOLED|JNDI]",这里只详细介绍 UNPOOLED:
(1)UNPOOLED
UNPOOLED 不支持 JDBC 数据源连接池,实现的只是每次被请求时打开和关闭连接。其包含的属性:
- driver:JDBC 驱动的 Java 类的完全限定名,如 MySQL 的 com.mysql.cj.jdbc.Driver;
- url:数据库的 JDBC URL 地址;
- username:数据库的用户名;
- password:数据库的密码;
- defaultTransactionIsolationLevel:默认的连接事务隔离级别。
(2)POOLED
POOLED 支持 JDBC 数据源连接池,利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。除了有 UNPOOLED 的属性外还包括poolMaximumActiveConnections 、 poolMaximumIdleConnections 等属性。
(3)JNDI
JNDI 支持外部数据源连接池,它的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。其包含的属性:
- initial_context:用来在 InitialContext 中寻找上下文;
- data_source:引用数据源实例位置的上下文的路径。
3.4 Mappers
mappers 用于引用已经定义好的映射文件,告诉 MyBatis 去哪寻找映射 SQL 的语句。常见的方法:
(1)通过 resource 加载单个映射文件:
<mappers>
<mapper resource="com/ivandu/mybatis/mapper/UserMapper.xml"/>
</mappers>
(2)通过完全限定资源定位符(绝对路径前加上 file:///)加载单个映射文件:
<mappers>
<mapper url="file:///home/project/MyBatisTest/src/com/ivandu/mybatis/mapper/UserMapper.xml"/>
</mappers>
(3)通过 mapper 接口对象加载单个映射文件:
<mappers>
<mapper class="com.ivandu.mybatis.mapper.UserMapper" />
</mappers>
(4)通过 mapper 接口包加载整个包的映射文件:
<mappers>
<package name="com.ivandu.mybatis.mapper" />
</mappers>
注:(3)和(4)中需要将 mapper 接口类名和 mapper.xml 映射文件名称保持一致,且在同一个目录。主要参考了 MyBatis 中文文档:XML 映射配置文件。
四 告警解除、故障排除
- 告警“XML标记是Empyt Body”解决方案如下:
<id property="id" column="id" javaType="Integer"></id>
改为<id property="id" column="id" javaType="Integer" />
- WARN: This connection is using TLSv1.1 which is now deprecated and will be removed in a future release of Connector/J. 解决方案如下:
JDBC中jdbc:mysql://10.1.1.88:3306/mybatis?useSSL=false的useSSL由true改为false。
五 总结
- 参考资料:Mybatis官网
- GitHub 源码:GitHub:https://github.com/cxwn/mybatis.git tag:1.0.0