同步操作将从 icanci/Java-Review 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
后面的是我自己电脑版本,其他的版本不影响
Maven (3.5.4)
Git (2.22.0)
JDK (9.0.1)
IDEA (2020.1)
fork
出自己的仓库,我们可能做一些注释,所以有自己的仓库方便提交,因为国内访问Github速度太慢,所以我自己是同步到了码云上 https://gitee.com/icanci/mybatis-3
org.apache.ibatis.autoconstructor.AutoConstructorTest
单元测试即可。autoconstructor
下的文件<?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>
<!-- autoMappingBehavior should be set in each test case -->
<!-- 配置环境 -->
<environments default="development">
<!-- 生产环境 -->
<environment id="development">
<!-- 配置事务管理 -->
<transactionManager type="JDBC">
<property name="" value=""/>
</transactionManager>
<!-- 配置数据源 -->
<!-- UNPOOLED 指的是每次都创建新的连接 POOLED 指的是使用同一个 -->
<dataSource type="UNPOOLED">
<!-- 数据库驱动 -->
<property name="driver" value="org.hsqldb.jdbcDriver"/>
<!-- 数据库URL地址 -->
<property name="url" value="jdbc:hsqldb:mem:automapping"/>
<!-- 数据库用户名 -->
<property name="username" value="sa"/>
</dataSource>
</environment>
</environments>
<!-- 接口映射文件 -->
<mappers>
<!-- 具体映射文件路径名 -->
<mapper resource="org/apache/ibatis/autoconstructor/AutoConstructorMapper.xml"/>
</mappers>
</configuration>
在 <environments/>
标签中,配置了事务管理和数据源。考虑到减少外部依赖,所以使用了 HSQLDB 。
在 <mappers>
标签中,配置了需要扫描的 Mapper 文件。目前,仅仅扫描 AutoConstructorMapper.xml
文件。
AutoConstructorMapper.xml
<?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">
<!-- 对应 org.apache.ibatis.autoconstructor.AutoConstructorMapper 接口 -->
<mapper namespace="org.apache.ibatis.autoconstructor.AutoConstructorMapper">
</mapper>
// 此处是使用注解的方式,来编写SQL
public interface AutoConstructorMapper {
@Select("SELECT * FROM subject WHERE id = #{id}")
PrimitiveSubject getSubject(final int id);
@Select("SELECT * FROM subject")
List<PrimitiveSubject> getSubjects();
@Select("SELECT * FROM subject")
List<AnnotatedSubject> getAnnotatedSubjects();
@Select("SELECT * FROM subject")
List<BadSubject> getBadSubjects();
@Select("SELECT * FROM extensive_subject")
List<ExtensiveSubject> getExtensiveSubjects();
}
--
-- Copyright 2009-2018 the original author or authors.
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
DROP TABLE subject
IF EXISTS;
DROP TABLE extensive_subject
IF EXISTS;
CREATE TABLE subject (
id INT NOT NULL,
name VARCHAR(20),
age INT NOT NULL,
height INT,
weight INT,
active BIT,
dt TIMESTAMP
);
CREATE TABLE extensive_subject (
aByte TINYINT,
aShort SMALLINT,
aChar CHAR,
anInt INT,
aLong BIGINT,
aFloat FLOAT,
aDouble DOUBLE,
aBoolean BIT,
aString VARCHAR(255),
anEnum VARCHAR(50),
aClob LONGVARCHAR,
aBlob LONGVARBINARY,
aTimestamp TIMESTAMP
);
INSERT INTO subject VALUES
(1, 'a', 10, 100, 45, 1, CURRENT_TIMESTAMP),
(2, 'b', 10, NULL, 45, 1, CURRENT_TIMESTAMP),
(2, 'c', 10, NULL, NULL, 0, CURRENT_TIMESTAMP);
INSERT INTO extensive_subject
VALUES
(1, 1, 'a', 1, 1, 1, 1.0, 1, 'a', 'AVALUE', 'ACLOB', 'aaaaaabbbbbb', CURRENT_TIMESTAMP),
(2, 2, 'b', 2, 2, 2, 2.0, 2, 'b', 'BVALUE', 'BCLOB', '010101010101', CURRENT_TIMESTAMP),
(3, 3, 'c', 3, 3, 3, 3.0, 3, 'c', 'CVALUE', 'CCLOB', '777d010078da', CURRENT_TIMESTAMP);
创建了 subject
表,并初始化三条数据
创建了 extensive_subject
表,并且初始化三条数据
POJO
AnnotatedSubject
public class AnnotatedSubject {
private final int id;
private final String name;
private final int age;
private final int height;
private final int weight;
public AnnotatedSubject(final int id, final String name, final int age, final int height, final int weight) {
this.id = id;
this.name = name;
this.age = age;
this.height = height;
this.weight = weight;
}
@AutomapConstructor
public AnnotatedSubject(final int id, final String name, final int age, final Integer height, final Integer weight) {
this.id = id;
this.name = name;
this.age = age;
this.height = height == null ? 0 : height;
this.weight = weight == null ? 0 : weight;
}
}
subject
表@AutomapConstructor
注解,表示Mybatis查询之后,再创建 AnnotatedSubject对象,使用该构造方法,实际用处不多public class PrimitiveSubject {
private final int id;
private final String name;
private final int age;
private final int height;
private final int weight;
private final boolean active;
private final Date dt;
public PrimitiveSubject(final int id, final String name, final int age, final int height, final int weight, final boolean active, final Date dt) {
this.id = id;
this.name = name;
this.age = age;
this.height = height;
this.weight = weight;
this.active = active;
this.dt = dt;
}
}
对应的也是 subject
表
和AnnotatedSubject不同,在其构造方法上,weight
和height
方法参数的类型是int,而不是Integer,那么如果subject
表中的记录,这两个字段为 NULL
时,会创建PrimitiveSubject对象报错
BadSubject
public class BadSubject {
private final int id;
private final String name;
private final int age;
private final Height height;
private final Double weight;
public BadSubject(final int id, final String name, final int age, final Height height, final Double weight) {
this.id = id;
this.name = name;
this.age = age;
this.height = height;
this.weight = weight == null ? 0 : weight;
}
private class Height {
}
}
对应的也是 subject
表。
和 AnnotatedSubject 不同,在其构造方法上,height
方法参数的类型是 Height ,而不是 Integer 。因为 MyBatis 无法识别 Height 类,所以会创建 BadSubject 对象报错。
ExtensiveSubject
public class ExtensiveSubject {
private final byte aByte;
private final short aShort;
private final char aChar;
private final int anInt;
private final long aLong;
private final float aFloat;
private final double aDouble;
private final boolean aBoolean;
private final String aString;
// enum types
private final TestEnum anEnum;
// array types
// string to lob types:
private final String aClob;
private final String aBlob;
public ExtensiveSubject(final byte aByte,
final short aShort,
final char aChar,
final int anInt,
final long aLong,
final float aFloat,
final double aDouble,
final boolean aBoolean,
final String aString,
final TestEnum anEnum,
final String aClob,
final String aBlob) {
this.aByte = aByte;
this.aShort = aShort;
this.aChar = aChar;
this.anInt = anInt;
this.aLong = aLong;
this.aFloat = aFloat;
this.aDouble = aDouble;
this.aBoolean = aBoolean;
this.aString = aString;
this.anEnum = anEnum;
this.aClob = aClob;
this.aBlob = aBlob;
}
public enum TestEnum {
AVALUE, BVALUE, CVALUE;
}
}
对应的也是 extensive_subject
表。
这是个复杂对象,基本涵盖了各种类型的数据。
AutoConstructorTest 单元测试类
class AutoConstructorTest {
private static SqlSessionFactory sqlSessionFactory;
// 创建SqlSessionFactory对象,基于mybatis-config.xml 配置文件
@BeforeAll
static void setUp() throws Exception {
// create a SqlSessionFactory
try (Reader reader = Resources.getResourceAsReader("org/apache/ibatis/autoconstructor/mybatis-config.xml")) {
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
}
// populate in-memory database
// 初始化数据到内存数据库,基于 CreateDB.sql 文件
BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
"org/apache/ibatis/autoconstructor/CreateDB.sql");
}
@Test
void fullyPopulatedSubject() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
final AutoConstructorMapper mapper = sqlSession.getMapper(AutoConstructorMapper.class);
final Object subject = mapper.getSubject(1);
assertNotNull(subject);
}
}
@Test
void primitiveSubjects() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
final AutoConstructorMapper mapper = sqlSession.getMapper(AutoConstructorMapper.class);
assertThrows(PersistenceException.class, mapper::getSubjects);
}
}
@Test
void annotatedSubject() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
final AutoConstructorMapper mapper = sqlSession.getMapper(AutoConstructorMapper.class);
verifySubjects(mapper.getAnnotatedSubjects());
}
}
@Test
void badSubject() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
final AutoConstructorMapper mapper = sqlSession.getMapper(AutoConstructorMapper.class);
assertThrows(PersistenceException.class, mapper::getBadSubjects);
}
}
@Test
void extensiveSubject() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
final AutoConstructorMapper mapper = sqlSession.getMapper(AutoConstructorMapper.class);
verifySubjects(mapper.getExtensiveSubjects());
}
}
private void verifySubjects(final List<?> subjects) {
assertNotNull(subjects);
Assertions.assertThat(subjects.size()).isEqualTo(3);
}
}
mybatis-config.xml
配置文件。CreateDB.sql
SQL 文件。此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。