MyBatis之TypeHandler

  以高校写web应用的时候经常会面逢这么个问题,当自家一旦插入一久数,某个数是Date类型,数据库中也是VARCHAR类型,这个上也许会见傻的先将此数量好手动转换成为String类型再插入到数据库被,其实大可不必。MyBatis为咱提供了还好的法就是是TypeHandler来应对Java和jdbc字段类型不匹配的事态。MyBatis中置了好多之TypeHandler,如果我们想只要自己于定义一个TypeHandler可以实现TypeHandler接口,也可以延续BaseTypeHandler类。下面我们兑现一个将Java中之Date类型利用我们打定义的ExampleTypeHandler来转换为JDBC的VARCHAR类型。

  我们对MyBatis的牵线先局限在采用,在会下后我们重究其原理、源码。

 1 package day_8_mybatis.util;
 2 
 3 import java.sql.CallableStatement;
 4 import java.sql.PreparedStatement;
 5 import java.sql.ResultSet;
 6 import java.sql.SQLException;
 7 import java.util.Date;
 8 
 9 import org.apache.ibatis.type.BaseTypeHandler;
10 import org.apache.ibatis.type.JdbcType;
11 
12 /**
13  * 注意在引入Date所在的包时,是java.util.Date,而不是java.sql.Date,这一点不要搞错。
14  * @author turbo
15  *
16  * 2016年10月23日
17  */
18 public class ExampleTypeHandler extends BaseTypeHandler<Date> {
19 
20     /* 根据列名,获取可以为空的结果
21      * @see org.apache.ibatis.type.BaseTypeHandler#getNullableResult(java.sql.ResultSet, java.lang.String)
22      */
23     @Override
24     public Date getNullableResult(ResultSet rs, String columnName)
25             throws SQLException {
26         String sqlTimetamp = rs.getString(columnName);
27         if (null != sqlTimetamp){
28             return new Date(Long.valueOf(sqlTimetamp));
29         }
30         return null;
31     }
32 
33     /* 根据列索引,获取可以为空的结果
34      * @see org.apache.ibatis.type.BaseTypeHandler#getNullableResult(java.sql.ResultSet, int)
35      */
36     @Override
37     public Date getNullableResult(ResultSet rs, int columnIndex)
38             throws SQLException {
39         String sqlTimetamp = rs.getString(columnIndex);
40         if (null != sqlTimetamp){
41             return new Date(Long.valueOf(sqlTimetamp));
42         }
43         return null;
44     }
45 
46     /*47      * @see org.apache.ibatis.type.BaseTypeHandler#getNullableResult(java.sql.CallableStatement, int)
48      */
49     @Override
50     public Date getNullableResult(CallableStatement cs, int columnIndex)
51             throws SQLException {
52         String sqlTimetamp = cs.getString(columnIndex);
53         if (null != sqlTimetamp){
54             return new Date(Long.valueOf(sqlTimetamp));
55         }
56         return null;
57     }
58 
59     /* 设置非空参数
60      * @see org.apache.ibatis.type.BaseTypeHandler#setNonNullParameter(java.sql.PreparedStatement, int, java.lang.Object, org.apache.ibatis.type.JdbcType)
61      */
62     @Override
63     public void setNonNullParameter(PreparedStatement ps, int i, Date parameter,
64             JdbcType jdbcType) throws SQLException {
65         ps.setString(i, String.valueOf(parameter.getTime()));
66     }
67 
68     
69 
70 }

  我们曾从定义了一个TypeHandler,接着我们设当mybatis-config.xml中登记。

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE configuration  
 3   PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  
 4   "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5   
 6 <configuration>
 7 <!-- 注意configuration中各个属性配置的顺序应为:properties,settings,typeAliases,typeHandlers,objectFactory,objectWrapperFactory,reflectorFactory,plugins,environments,databaseIdProvider,mappers)-->
 8     <properties>
 9         <property name="driver" value="com.mysql.jdbc.Driver"/>
10         <property name="url" value="jdbc:mysql://localhost:3306/test"/>    
11         <property name="username" value="root"/>
12         <property name="password" value="0000"/>
13     </properties>
14     <typeHandlers>
15         <typeHandler handler="day_8_mybatis.util.ExampleTypeHandler" javaType="java.util.Date" jdbcType="VARCHAR"/>
16     </typeHandlers>
17     
18     <environments default="development">
19         <environment id="development">
20             <transactionManager type="JDBC" />
21             <dataSource type="POOLED">
22                 <property name="driver" value="${driver}"/>
23                 <property name="url" value="${url}"/>
24                 <property name="username" value="${username}"/>
25                 <property name="password" value="${password}"/>
26             </dataSource>            
27         </environment>
28     </environments> 
29     <mappers>
30         <mapper resource="day_8_mybatis/mapper/UserMapper.xml"/>
31         <mapper resource="day_8_mybatis/mapper/NoteMapper.xml"/>
32     </mappers>    
33     
34 </configuration>
35 
36  

  注意各个属性配置出各个的分,不能够随随便便穿插。

  准备工作早就开得了了,我们随后以的实现POJO类
Note里面包含id和date字段。

 1 package day_8_mybatis.pojo;
 2 
 3 import java.util.Date;
 4 
 5 /**
 6  * @author turbo
 7  *
 8  * 2016年10月23日
 9  */
10 public class Note {
11     private int id;
12     private Date date;
13     public int getId() {
14         return id;
15     }
16     public void setId(int id) {
17         this.id = id;
18     }
19     public Date getDate() {
20         return date;
21     }
22     public void setDate(Date date) {
23         this.date = date;
24     }
25 }

就是背和数据库交互Dao层的NoteMapper接口,我们只有举例查询以及插。

 1 package day_8_mybatis.mapper;
 2 
 3 import day_8_mybatis.pojo.Note;
 4 
 5 /**
 6  * @author turbo
 7  *
 8  * 2016年10月23日
 9  */
10 public interface NoteMapper {
11     Note queryNote(int id);
12     void insertNote(Note note);
13 }

  我们又来瞧当NoteMapper.xml中凡哪些利用我们刚刚自定义之TypeHandler。

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE mapper  
 3   PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
 4   "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
 5 <mapper namespace="day_8_mybatis.mapper.NoteMapper">
 6     <resultMap type="day_8_mybatis.pojo.Note" id="note-base">
 7         <result property="id" column="id"/>
 8         <result property="date" column="date" typeHandler="day_8_mybatis.util.ExampleTypeHandler"/>
 9     </resultMap>
10     
11     <select id="queryNote" parameterType="int" resultMap="note-base">
12         select * from note where id = #{id}
13     </select>
14     <insert id="insertNote" parameterType="day_8_mybatis.pojo.Note">
15         insert into note (id, date) values(#{id}, #{date, typeHandler=day_8_mybatis.util.ExampleTypeHandler})  <!--使用我们自定义的TypeHandler-->
16     </insert>
17 </mapper> 

  最后我们在客户端测试一下。

 1 package day_8_mybatis;
 2 
 3 import java.io.IOException;
 4 import java.util.Date;
 5 
 6 import org.apache.ibatis.session.SqlSession;
 7 
 8 import day_8_mybatis.mapper.NoteMapper;
 9 import day_8_mybatis.pojo.Note;
10 import day_8_mybatis.util.SessionFactory;
11 
12 /**
13  * 客户端
14  * @author turbo
15  *
16  * 2016年9月11日
17  */
18 public class Main {
19 
20     /**
21      * @param args
22      * @throws IOException 
23      */
24     public static void main(String[] args) throws Exception {
25         String resource = "day_8_mybatis/mybatis-config.xml";        //获取mybatis配置文件路径
26         SqlSession sqlSession = SessionFactory.getSqlSession(resource);    //通过SessionFactory工具类(此工具类为自己构造即util包中的SessionFactory)构造SqlSession
27         
28         NoteMapper noteMapper = sqlSession.getMapper(NoteMapper.class);
29         
30         Note note = new Note();
31         note.setId(1);
32         note.setDate(new Date());
33         noteMapper.insertNote(note);    //插入
34         sqlSession.commit();    //注意需要手动提交事务
35         
36         note = noteMapper.queryNote(2);    //查询
37         System.out.println(note.getDate());
38     }
39 
40 }

  注意在34实行代码MyBatis,需要手动提交业务,默认是关门自动提交的,所以要手动提交。开始没有付诸业务,无论怎么还并未办法插入到数据库,后来debug单步调试之时光发现了autoCommit=false,才想起来以此前大学之上吧遇过是是题材因此一下即便定位问题在何处了。

  数据库中只是生一个note表,字段为id类型为int,date字段为varchar。

MyBatis 1

  至此我们便得了自定义之TypeHandler,其实MyBatis为我们提供的TypeHandler已经重重了,不过我们或好考试一管,先管MyBatis学会使用,再究其原理。


顿时是一个能让程序员加buff的大众号

MyBatis 2

网站地图xml地图