Mybatis20_mybatis核心配置文件深入7
一、typeHandler概述
无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型。下表描述了一些默认的类型处理器(截取部分)。
你可以重写类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。具体做法为:实现 org.apache.ibatis.type.TypeHandler 接口, 或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler, 然后可以选择性地将它映射到一个JDBC类型。例如需求:一个Java中的Date数据类型,我想将之存到数据库的时候存成一个1970年至今的毫秒数,取出来时转换成java的Date,即java的Date与数据库的varchar毫秒值之间转换。
开发步骤:
1、定义转换类继承类BaseTypeHandler<T>
2、覆盖4个未实现的方法,其中setNonNullParameter为java程序设置数据到数据库的回调方法,getNullableResult为查询时 mysql的字符串类型转换成 java的Type类型的方法
3、在MyBatis核心配置文件中进行注册
4、测试转换是否正确
二、typeHandler测试环境搭建
1、数据库:user表新增一个字段birthday
2、使用代码在user表插入数据
User.java类:
package com.itheima.domain; import java.util.Date; 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 + '\'' + ", birthday=" + birthday + '}'; } }
UserMapper.java:
package com.itheima.mapper; import com.itheima.domain.User; public interface UserMapper { public void save(User user); }
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.itheima.mapper.UserMapper">
<insert id="save" parameterType="user">
insert into user values(#{id},#{username},#{password},#{birthday})
</insert>
</mapper>
MyBatisTest.java:
package com.itheima.test; import com.itheima.domain.User; import com.itheima.mapper.UserMapper; 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.Test; import java.io.IOException; import java.io.InputStream; import java.util.Date; 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 mapper = sqlSession.getMapper(UserMapper.class); //创建user User user = new User(); user.setUsername("ceshi"); user.setPassword("abc"); user.setBirthday(new Date()); //执行保存操作 mapper.save(user); sqlSession.commit(); sqlSession.close(); } }
执行test1,查看控制台打印结果:
报错了,因为birthday插入的时候用的是date类型,数据库中是int类型,类型转换不了。
三、自定义DateTypeHandler实现
实现java的Date与数据库的long毫秒值之间转换:
main-java-com.itheima.handler.DateTypeHander.java:
package com.itheima.handler; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Date; public class DateTypeHandler extends BaseTypeHandler<Date> { @Override //将java类型 转换成 数据库需要的类型 public void setNonNullParameter(PreparedStatement ps, int i, Date parameter, JdbcType jdbcType) throws SQLException { long time = parameter.getTime(); ps.setLong(i,time); } @Override //将数据库中类型 转换成 java类型 //String参数 要转换的字段名称 //ResultSet 查询出的结果集 public Date getNullableResult(ResultSet rs, String columnName) throws SQLException { //获得结果集中需要的数据(long) 转换成 Date类型返回 long aLong = rs.getLong(columnName); Date date = new Date(aLong); return date; } @Override //将数据库中类型 转换成 java类型 public Date getNullableResult(ResultSet rs, int columnIndex) throws SQLException { long aLong = rs.getLong(columnIndex); Date date = new Date(aLong); return date; } @Override //将数据库中类型 转换成 java类型 public Date getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { long aLong = cs.getLong(columnIndex); Date date = new Date(aLong); return date; } }
main-resources-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> <!--通过properties标签加载外部properties文件--> <properties resource="jdbc.properties"/> <!--定义别名--> <typeAliases> <typeAlias type="com.itheima.domain.User" alias="user"/> </typeAliases> <!--注册类型处理器--> <typeHandlers> <typeHandler handler="com.itheima.handler.DateTypeHandler"></typeHandler> </typeHandlers> <!--数据源环境--> <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> <!--加载映射文件--> <mappers> <mapper resource="com/itheima/mapper/UserMapper.xml"/> </mappers> </configuration>
UserMapper.java:
package com.itheima.mapper; import com.itheima.domain.User; public interface UserMapper { public void save(User user); public User findById(int id); }
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.itheima.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>
MybatisTest.java:
package com.itheima.test; import com.itheima.domain.User; import com.itheima.mapper.UserMapper; 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.Test; import java.io.IOException; import java.io.InputStream; import java.util.Date; 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 mapper = sqlSession.getMapper(UserMapper.class); //创建user User user = new User(); user.setUsername("ceshi"); user.setPassword("abc"); user.setBirthday(new Date()); //执行保存操作 mapper.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 mapper = sqlSession.getMapper(UserMapper.class); //执行查询操作 User user = mapper.findById(8); System.out.println("user中的birthday:"+ user.getBirthday()); sqlSession.commit(); sqlSession.close(); } }
执行test1,无报错执行成功,查看数据库发现插入数据成功。
执行test2,查看控制台打印结果:
四、plugins标签
MyBatis可以使用第三方的插件来对功能进行扩展,分页助手PageHelper是将分页的复杂操作进行封装,使用简单的方式即可获得分页的相关数据。
1、开发步骤:
①导入通用PageHelper的坐标
②在mybatis核心配置文件中配置PageHelper插件
③测试分页数据获取
2、分页代码实现
2.1 查询全部代码编写
UserMapper.java:
package com.itheima.mapper; import com.itheima.domain.User; import java.util.List; public interface UserMapper { public List<User> findAll(); }
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.itheima.mapper.UserMapper"> <select id="findAll" resultType="user"> select * from user </select> </mapper>
MybatisTest.java:
package com.itheima.test; import com.itheima.domain.User; import com.itheima.mapper.UserMapper; 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.Test; import java.io.IOException; import java.io.InputStream; import java.util.Date; import java.util.List; public class MybatisTest { @Test public void test3() throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); //执行查询操作 List<User> userList = mapper.findAll(); for (User user : userList) { System.out.println(user); } sqlSession.commit(); sqlSession.close(); } }
执行test3,检查控制台打印结果:
2.2 plugins分页助手的代码实现
pom.xml导入通用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>1.0</version> </dependency>
在mybatis核心配置文件中配置PageHelper插件 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> <!--通过properties标签加载外部properties文件--> <properties resource="jdbc.properties"/> <!--定义别名--> <typeAliases> <typeAlias type="com.itheima.domain.User" alias="user"/> </typeAliases> <!--注册类型处理器--> <typeHandlers> <typeHandler handler="com.itheima.handler.DateTypeHandler"></typeHandler> </typeHandlers> <!--配置分页助手插件--> <plugins> <plugin interceptor="com.github.pagehelper.PageHelper"> <!--指定方言--> <property name="dialect" value="mysql"></property> </plugin> </plugins> <!--数据源环境--> <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> <!--加载映射文件--> <mappers> <mapper resource="com/itheima/mapper/UserMapper.xml"/> </mappers> </configuration>
MybatisTest.java:
package com.itheima.test; import com.github.pagehelper.PageHelper; import com.itheima.domain.User; import com.itheima.mapper.UserMapper; 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.Test; import java.io.IOException; import java.io.InputStream; import java.util.Date; import java.util.List; public class MybatisTest { @Test public void test3() throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); //设置分页的相关参数 当前页+每页显示的条数 PageHelper.startPage(1,3); //执行查询操作 List<User> userList = mapper.findAll(); for (User user : userList) { System.out.println(user); } sqlSession.commit(); sqlSession.close(); } }
执行test3,查看控制台打印结果:pagehelper坐标版本在5.0以上会报错,改成5.0以下版本就没问题
3、分页相关数据获取
package com.itheima.test; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.itheima.domain.User; import com.itheima.mapper.UserMapper; 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.Test; import java.io.IOException; import java.io.InputStream; import java.util.Date; import java.util.List; public class MybatisTest { @Test public void test3() throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); //设置分页的相关参数 当前页+每页显示的条数 PageHelper.startPage(2,2); //执行查询操作 List<User> userList = mapper.findAll(); for (User user : userList) { System.out.println(user); } //获得与分页相关参数 PageInfo<User> pageInfo = new PageInfo<User>(userList); System.out.println("当前页:"+pageInfo.getPageNum()); System.out.println("每页显示条数:"+pageInfo.getPageSize()); System.out.println("总条数:"+pageInfo.getTotal()); System.out.println("总页数:"+pageInfo.getPages()); System.out.println("上一页:"+pageInfo.getPrePage()); System.out.println("下一页:"+pageInfo.getNextPage()); System.out.println("是否是第一页:"+pageInfo.isIsFirstPage()); System.out.println("是否是最后一页:"+pageInfo.isIsLastPage()); sqlSession.commit(); sqlSession.close(); } }
执行test3,查看控制台打印结果:
当前页:2 每页显示条数:2 总条数:5 总页数:3 上一页:1 下一页:3 是否是第一页:false 是否是最后一页:false
五、知识小结
MyBatis核心配置文件常用标签:
1、properties标签:该标签可以加载外部的properties文件
2、typeAliases标签:设置类型别名
3、environments标签:数据源环境配置标签
4、typeHandlers标签:配置自定义类型处理器
5、plugins标签:配置MyBatis的插件,分页助手PageHelper