MyBatis —— 第三十章 MyBatis 核心配置文件深入
1. typeHandlers
标签
无论是 MyBatis 在预处理语句(PreparedStatement
)中设置一个参数时,还是从结果集中取出一个值时,都会用类处理器将获取的值以合适的方式转换成 Java 类型。下表描述了一些默认的类型处理器(部分)。
类型处理器 | 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 |
你可以重写类型处理器或创建自己的类型处理器来处理不支持的或非标准的类型,具体做法为:实现 org.apache.ibatis.type.TypeHandler
接口,或者继承一个相当方便的类 org.apache.ibatis.type.BaseTypeHandler
,然后可以选择性地将它映射到一个 JDBC 类型。例如:一个 Java 中的 Date
类型,要想将之存到数据库的时候储存为一个 1970 至今的毫秒数(Timestamp
),取出来时转换成 Java 的 Date
,即 Java 中的 Date
与数据库中的 varchar
毫秒值之间的转换。
开发步骤:
- 定义转换继承类
BaseTypeHandler<T>
- 覆盖 4 个未实现的方法,其中
setNonNullParameter
为 Java 程序设置数据到数据库的回调方法,getNullableResult
为查询时 MySQL 的字符串类型转换成 Java 的Type
类型的方法 - 在 MyBatis 核心配置文件中进行注册
- 测试转换是否正确
示例代码:
sqlMapConfig.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>
<!-- Load the external properties file through the properties tag -->
<properties resource="jdbc.properties"></properties>
<!-- Define alias -->
<typeAliases>
<typeAlias type="com.gregperlinli.domain.User" alias="user" />
</typeAliases>
<!-- Custom type handler -->
<typeHandlers>
<typeHandler handler="com.gregperlinli.handler.DateTypeHandler" />
</typeHandlers>
<!-- Data source environment -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- Load mapping profile -->
<mappers>
<mapper resource="com/gregperlinli/mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
com/yourname/mapper/userMapper.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">
<mapper namespace="com.gregperlinli.mapper.UserMapper">
<insert id="save" parameterType="user">
insert into user values(#{id}, #{username}, #{password}, #{birthday})
</insert>
<select id="findById" parameterType="int" resultType="user">
select * from user where id = #{id}
</select>
</mapper>
com.yourname.domain.User
/**
* @author gregPerlinLi
* @since 2021-10-08
*/
public class User {
private int id;
private String username;
private String password;
private Date birthday;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
com.yourname.mapper.UserMapper
/**
* @author gregPerlinLi
* @since 2021-10-08
*/
public interface UserMapper {
/**
* save user
*
* @param user user to save
*/
void save(User user);
/**
* Find by id
*
* @param id id to find
* @return user
*/
User findById(int id);
}
com.yourname.handler.DateTypeHandler
/**
* @author gregPerlinLi
* @since 2021-10-12
*/
public class DateTypeHandler extends BaseTypeHandler<Date> {
/**
* Convert Java types to the types required by the database
*/
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Date parameter, JdbcType jdbcType) throws SQLException {
long time = parameter.getTime();
ps.setLong(i, time);
}
/**
* Convert types in the database to Java types
* @param columnName Field names to convert
* @param rs Queried result set
*/
@Override
public Date getNullableResult(ResultSet rs, String columnName) throws SQLException {
// Obtain the data (Long) required in the result set, convert it into Date type and return it
long aLong = rs.getLong(columnName);
Date date = new Date(aLong);
return date;
}
/**
* Convert types in the database to Java types
*/
@Override
public Date getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
long aLong = rs.getLong(columnIndex);
Date date = new Date(aLong);
return date;
}
/**
* Convert types in the database to Java types
*/
@Override
public Date getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
long aLong = cs.getLong(columnIndex);
Date date = new Date(aLong);
return date;
}
}
com.yourname.test.MybatisTest
/**
* @author gregPerlinLi
* @since 2021-10-08
*/
public class MybatisTest {
@Test
public void test1() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// Create user
User user = new User();
user.setUsername("Test");
user.setPassword("abc");
user.setBirthday(new Date());
// Perform save operation
userMapper.save(user);
sqlSession.commit();
sqlSession.close();
}
@Test
public void test2() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findById(8);
System.out.println("The birthday of the user is: " + user.getBirthday());
sqlSession.commit();
sqlSession.close();
}
}
2. plugins
标签
MyBatis 可以使用第三方的插件来对功能进行拓展。其中,分页助手 PageHelper
是将分页的复杂操作进行封装,使用简单的方式即可获得分页的相关数据
开发步骤:
导入通用
PageHelper
的坐标<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>3.7.5</version> </dependency> <dependency> <groupId>com.github.jsqlparser</groupId> <artifactId>jsqlparser</artifactId> <version>0.9.1</version> </dependency>
在 MyBatis 核心配置文件中配置
PageHelper
插件<!-- Configure plugins --> <plugins> <plugin interceptor="com.github.pagehelper.PageHelper"> <property name="dialect" value="mysql"/> </plugin> </plugins>
测试分页数据获取
示例代码:
pom.xml
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</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.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>3.7.5</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>
sqlMapConfig.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>
<!-- Load the external properties file through the properties tag -->
<properties resource="jdbc.properties"></properties>
<!-- Define alias -->
<typeAliases>
<typeAlias type="com.gregperlinli.domain.User" alias="user" />
</typeAliases>
<!-- Configure plugins -->
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"/>
</plugin>
</plugins>
<!-- Data source environment -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- Load mapping profile -->
<mappers>
<mapper resource="com/gregperlinli/mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
com/yourname/mapper/UserMapper.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">
<mapper namespace="com.gregperlinli.mapper.UserMapper">
<select id="findAll" resultType="user">
select * from user
</select>
</mapper>
com.yourname.mapper.UserMapper
/**
* @author gregPerlinLi
* @since 2021-10-08
*/
public interface UserMapper {
/**
* Find all
* @return All users
*/
List<User> findAll();
}
com.yourname.test.MybatisTest
/**
* @author gregPerlinLi
* @since 2021-10-08
*/
public class MybatisTest {
@Test
public void test() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// Set paging related parameters Current page + Number of displays per page
PageHelper.startPage(1, 3);
List<User> userList = userMapper.findAll();
userList.forEach(System.out::println);
// Get paging related parameters
PageInfo<User> userPageInfo = new PageInfo<>(userList);
System.out.println("|Current page: " + userPageInfo.getPageNum() +
"|\t|Number of displays per page: " + userPageInfo.getPageSize() +
"|\t|Total number: " + userPageInfo.getTotal() +
"|\t|Total pages: " + userPageInfo.getPages() +
"|\t|Previous page:" + userPageInfo.getPrePage() +
"|\t|Next page:" + userPageInfo.getNextPage() +
"|\t|Is the first page: " + userPageInfo.isIsFirstPage() +
"|\t|Is the last page: " + userPageInfo.isIsLastPage() + "|");
sqlSession.close();
}
}
3. 知识要点
MyBatis 核心文件配置常用标签:
<properties>
:该标签可以加载外部的properties
文件<typeAliases>
:设置类型别名<environments>
:数据源环境配置标签<typeHandlers>
:配置自定义类型处理器<plugins>
:配置 MyBatis 插件