zoukankan      html  css  js  c++  java
  • mybatis的typeHandler

    typeHandler作用:

      1.传参时将javaType类型转换成jdbcType

      2.结果集中ResultSet中取值时,jdbcType转换为javaType;

    系统自定义的typeHandler:

      mybatis系统内部定义了一系列的typeHandler;基本涵盖了我们正常使用的类型转换;如下

    选取一个系统自定义的typeHandler看看;

    在包org.apache.ibatis.type下有一个StringTypeHandler.java

    源码如下:

    public class StringTypeHandler extends BaseTypeHandler<String> {
    
      @Override
      public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
          throws SQLException {
        ps.setString(i, parameter);
      }
    
      @Override
      public String getNullableResult(ResultSet rs, String columnName)
          throws SQLException {
        return rs.getString(columnName);
      }
    
      @Override
      public String getNullableResult(ResultSet rs, int columnIndex)
          throws SQLException {
        return rs.getString(columnIndex);
      }
    
      @Override
      public String getNullableResult(CallableStatement cs, int columnIndex)
          throws SQLException {
        return cs.getString(columnIndex);
      }
    }
    View Code

    StringTypeHandler继承了BaseTypeHandler;而BaseTypeHandler实现了接口TypeHandler,

    BaseTypeHandler中代码

    /**
     *    Copyright 2009-2015 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.
     */
    package org.apache.ibatis.type;
    
    import java.sql.CallableStatement;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    import org.apache.ibatis.executor.result.ResultMapException;
    import org.apache.ibatis.session.Configuration;
    
    /**
     * @author Clinton Begin
     * @author Simone Tripodi
     */
    public abstract class BaseTypeHandler<T> extends TypeReference<T> implements TypeHandler<T> {
    
      protected Configuration configuration;
    
      public void setConfiguration(Configuration c) {
        this.configuration = c;
      }
    
      @Override
      public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
        if (parameter == null) {
          if (jdbcType == null) {
            throw new TypeException("JDBC requires that the JdbcType must be specified for all nullable parameters.");
          }
          try {
            ps.setNull(i, jdbcType.TYPE_CODE);
          } catch (SQLException e) {
            throw new TypeException("Error setting null for parameter #" + i + " with JdbcType " + jdbcType + " . " +
                    "Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. " +
                    "Cause: " + e, e);
          }
        } else {
          try {
            setNonNullParameter(ps, i, parameter, jdbcType);
          } catch (Exception e) {
            throw new TypeException("Error setting non null for parameter #" + i + " with JdbcType " + jdbcType + " . " +
                    "Try setting a different JdbcType for this parameter or a different configuration property. " +
                    "Cause: " + e, e);
          }
        }
      }
    
      @Override
      public T getResult(ResultSet rs, String columnName) throws SQLException {
        T result;
        try {
          result = getNullableResult(rs, columnName);
        } catch (Exception e) {
          throw new ResultMapException("Error attempting to get column '" + columnName + "' from result set.  Cause: " + e, e);
        }
        if (rs.wasNull()) {
          return null;
        } else {
          return result;
        }
      }
    
      @Override
      public T getResult(ResultSet rs, int columnIndex) throws SQLException {
        T result;
        try {
          result = getNullableResult(rs, columnIndex);
        } catch (Exception e) {
          throw new ResultMapException("Error attempting to get column #" + columnIndex+ " from result set.  Cause: " + e, e);
        }
        if (rs.wasNull()) {
          return null;
        } else {
          return result;
        }
      }
    
      @Override
      public T getResult(CallableStatement cs, int columnIndex) throws SQLException {
        T result;
        try {
          result = getNullableResult(cs, columnIndex);
        } catch (Exception e) {
          throw new ResultMapException("Error attempting to get column #" + columnIndex+ " from callable statement.  Cause: " + e, e);
        }
        if (cs.wasNull()) {
          return null;
        } else {
          return result;
        }
      }
    
      public abstract void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;
    
      public abstract T getNullableResult(ResultSet rs, String columnName) throws SQLException;
    
      public abstract T getNullableResult(ResultSet rs, int columnIndex) throws SQLException;
    
      public abstract T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException;
    
    }
    View Code

    getResult分别用columnName和columnIndex从ResultSet中获取数据,CallableStatement表示从存储过程中获取结果及数据的方法;

    下面我们创建自定义typeHandler

    RoleMapper.java

    package com.learn.charter2.mapper;
    
    import java.util.List;
    
    import com.learn.charter2.po.Role;
    
    public interface RoleMapper {
        Role getRole(Long id) throws Exception;
        int deleteRole(Long id) throws Exception;
        int insertRole(Role role) throws Exception;
        List<Role> findRole(Role role) throws Exception;
    }
    View Code

    Role.java

    package com.learn.charter2.po;
    
    public class Role {
        private Long id;
        private String roleName;
        private String note;
        private Integer pk;
        
        public Long getId() {
            return id;
        }
        public void setId(Long id) {
            this.id = id;
        }
        public String getRoleName() {
            return roleName;
        }
        public void setRoleName(String roleName) {
            this.roleName = roleName;
        }
        public String getNote() {
            return note;
        }
        public void setNote(String note) {
            this.note = note;
        }
        public Integer getPk() {
            return pk;
        }
        public void setPk(Integer pk) {
            this.pk = pk;
        }
        
    
        
    
    }
    View Code

    SqlSessionFactoryUtil.java

    package com.learn.charter2.util;
    
    import java.io.InputStream;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    public class SqlSessionFactoryUtil {
        private static SqlSessionFactory sqlSessionFactory=null;
        private static final Class class_lock=SqlSessionFactoryUtil.class;
        private SqlSessionFactoryUtil() {
        }
        public static SqlSessionFactory initSqlSessionFactory(){
            String resource="mybatis-config.xml";
            InputStream inputStream=null;
            try {
                inputStream=Resources.getResourceAsStream(resource);
            } catch (Exception e) {
                Logger.getLogger(SqlSessionFactoryUtil.class.getName()).log(Level.SEVERE,null,e);
            }
            synchronized (class_lock) {
                if(sqlSessionFactory==null){
                    sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
                }
            }
            return sqlSessionFactory;
        }
        public static SqlSession openSqlSession(){
            if(sqlSessionFactory==null){
                initSqlSessionFactory();
            }
            return sqlSessionFactory.openSession();
        }
    }
    View Code

    log4j.properties

    log4j.rootLogger=debug,stdout
    log4j.logger.org.mybatis=debug
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%5p %d %C:%m%n

    mybatis-config.xml

     1 <?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">
     2 <configuration>
     3     <typeHandlers>
     4         <typeHandler handler="com.learn.charter2.util.MyStringTypeHandler" javaType="string" jdbcType="VARCHAR"/>
     5         <typeHandler handler="com.learn.charter2.util.MyIntergerTypeHandler" javaType="int" jdbcType="VARCHAR"/>
     6     </typeHandlers>
     7     <environments default="development">
     8         <environment id="development">
     9             <transactionManager type="JDBC">
    10                 <property name="autoCommit" value="false" />
    11             </transactionManager>
    12             <dataSource type="POOLED">
    13                 <property name="driver" value="com.mysql.jdbc.Driver" />
    14                 <property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
    15                 <property name="username" value="root" />
    16                 <property name="password" value="gys" />
    17             </dataSource>
    18         </environment>
    19     </environments>
    20     <mappers>
    21         <mapper resource="com/learn/charter2/mapper/roleMapper.xml" />
    22     </mappers>
    23 </configuration>

    roleMapper.xml

     1 <?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">
     2 <mapper namespace="com.learn.charter2.mapper.RoleMapper">
     3     
     4     <resultMap type="com.learn.charter2.po.Role" id="roleMap">
     5         <id column="id" property="id" javaType="long" jdbcType="BIGINT"/>
     6         <result column="role_name" property="roleName" javaType="string" jdbcType="VARCHAR"/>
     7         <result column="note" property="note" typeHandler="com.learn.charter2.util.MyStringTypeHandler"/>
     8         <result column="pk" property="pk" typeHandler="com.learn.charter2.util.MyIntergerTypeHandler"/>
     9     </resultMap>
    10 
    11 
    12     <select id="getRole" parameterType="long" resultMap="roleMap"> 
    13     select id,role_name as roleName,note from t_role where id=#{id}
    14     </select>
    15     
    16     <select id="findRole" parameterType="com.learn.charter2.po.Role" resultMap="roleMap"> 
    17     select id,role_name as roleName,note,pk from t_role 
    18     <where>
    19         <if test="roleName !=null">
    20              role_name like concat('%',#{roleName,javaType=string,jdbcType=VARCHAR,typeHandler=com.learn.charter2.util.MyStringTypeHandler},'%')
    21         </if>
    22         <if test="pk !=null">
    23         and pk =#{pk,javaType=int,jdbcType=VARCHAR,typeHandler=com.learn.charter2.util.MyIntergerTypeHandler}
    24          </if> 
    25     </where>    
    26 
    27 
    28     </select>
    29     
    30     <insert id="insertRole" parameterType="com.learn.charter2.po.Role">
    31         insert into t_role
    32         (role_name,note)
    33         values
    34         (#{roleName},#{note})
    35     </insert>
    36     <delete id="deleteRole" parameterType="long">
    37         delete from t_role where id=#{id}
    38     </delete>
    39 </mapper>

    MyIntergerTypeHandler.java

     1 package com.learn.charter2.util;
     2 
     3 
     4 import java.sql.CallableStatement;
     5 import java.sql.PreparedStatement;
     6 import java.sql.ResultSet;
     7 import java.sql.SQLException;
     8 
     9 import org.apache.ibatis.type.JdbcType;
    10 import org.apache.ibatis.type.MappedJdbcTypes;
    11 import org.apache.ibatis.type.MappedTypes;
    12 import org.apache.ibatis.type.TypeHandler;
    13 import org.apache.log4j.Logger;
    14 
    15 import sun.security.action.GetIntegerAction;
    16 
    17 
    18 /**
    19  * @MappedTypes({Integer.class})
    20    @MappedJdbcTypes(JdbcType.VARCHAR)
    21  *
    22  */
    23 public class MyIntergerTypeHandler implements TypeHandler<Integer> {
    24     
    25     private Logger log=Logger.getLogger(MyIntergerTypeHandler.class);
    26 
    27     private int getInt(String v){
    28         if("a".equals(v)){
    29             return 10;
    30         }else if("b".equals(v)){
    31             return 20;
    32         }else if("c".equals(v)){
    33              return 30;
    34         }else{
    35             return 60;
    36         }
    37     }
    38     @Override
    39     public Integer getResult(CallableStatement cs, int index)
    40             throws SQLException {
    41         log.info("使用我的IntegerTypeHandler,CallbleStatment下表获取字符串");
    42         return getInt(cs.getString(index));
    43     }
    44 
    45     @Override
    46     public Integer getResult(ResultSet rs, int index) throws SQLException {
    47         log.info("使用我的IntegerTypeHandler,ResultSet下标获取字符串");
    48         return getInt(rs.getString(index));
    49     }
    50 
    51     @Override
    52     public Integer getResult(ResultSet rs, String colName) throws SQLException {
    53         log.info("使用我的IntegerTypeHandler,ResultSet 列名获取字符串");
    54         return getInt(rs.getString(colName));
    55     }
    56 
    57     @Override
    58     public void setParameter(PreparedStatement ps, int index, Integer value,JdbcType jt) throws SQLException {
    59         log.info("使用我的IntegerTypeHandler==index:"+index+";value:"+value);
    60         String v="";
    61         if(value==1){
    62             v="a";
    63         }else if(value==2){
    64             v="b";
    65         }else if(value==3){
    66             v="c";
    67         }else {
    68             v="guoyansi";
    69         }
    70         ps.setString(index, v);
    71     }
    72 }

    MyStringTypeHandler.java

     1 package com.learn.charter2.util;
     2 
     3 
     4 import java.sql.CallableStatement;
     5 import java.sql.PreparedStatement;
     6 import java.sql.ResultSet;
     7 import java.sql.SQLException;
     8 
     9 import org.apache.ibatis.type.JdbcType;
    10 import org.apache.ibatis.type.MappedJdbcTypes;
    11 import org.apache.ibatis.type.MappedTypes;
    12 import org.apache.ibatis.type.TypeHandler;
    13 import org.apache.log4j.Logger;
    14 
    15 
    16 @MappedTypes({String.class})
    17 @MappedJdbcTypes(JdbcType.INTEGER)
    18 public class MyStringTypeHandler implements TypeHandler<String> {
    19     private Logger log=Logger.getLogger(MyStringTypeHandler.class);
    20     
    21     @Override
    22     public String getResult(CallableStatement cs, int index)
    23             throws SQLException {
    24         log.info("使用我的StringTypeHandler,CallbleStatment下表获取字符串");
    25         return cs.getString(index);
    26     }
    27 
    28     @Override
    29     public String getResult(ResultSet rs, int index) throws SQLException {
    30         log.info("使用我的StringTypeHandler,ResultSet下标获取字符串");
    31         return rs.getString(index);
    32     }
    33 
    34     @Override
    35     public String getResult(ResultSet rs, String colName) throws SQLException {
    36         log.info("使用我的StringTypeHandler,ResultSet 列名获取字符串");
    37         return rs.getString(colName);
    38     }
    39 
    40     @Override
    41     public void setParameter(PreparedStatement ps, int index, String value,
    42             JdbcType jt) throws SQLException {
    43         value=value+"m";
    44         log.info("使用我的StringTypeHandler==index:"+index+";value:"+value);
    45         ps.setString(index, value);
    46     }
    47     
    48     
    49 }

    Charter2Main.java

     1 package com.learn.charter2.main;
     2 
     3 import java.util.List;
     4 
     5 import org.apache.ibatis.session.SqlSession;
     6 
     7 import com.learn.charter2.mapper.RoleMapper;
     8 import com.learn.charter2.po.Role;
     9 import com.learn.charter2.util.SqlSessionFactoryUtil;
    10 
    11 public class Charter2Main {
    12     public static void main(String[] args) {
    13         SqlSession sqlSession = null;
    14         try {
    15             sqlSession = SqlSessionFactoryUtil.openSqlSession();
    16             RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
    17             Role role = new Role();
    18             role.setPk(10);
    19             List<Role> list=roleMapper.findRole(role);
    20             for(Role r:list){
    21                 System.out.println("id:"+r.getId()+";roleName:"+r.getRoleName()+";note:"+r.getNote()+";pk:"+r.getPk());
    22             }
    23         } catch (Exception e) {
    24             System.err.println(e.getMessage());
    25             sqlSession.rollback();
    26         }finally{
    27             if(sqlSession!=null){
    28                 sqlSession.close();
    29             }
    30         }
    31     }
    32 
    33 }

    自定义typeHandler的三个步骤:

    1.定义typeHandler(MyIntergerTypeHandler.java     MyStringTypeHandler.java)

    2.配置typeHandler(mybatis-config.xml中3-6行)

    3.指定入参中哪个字段使用typeHandler(mapper.xml中19-24行)

    4.指定出参中哪个字段使用typeHandler(mapper.xml中7-8行)

    以MyIntergerTypeHandler为例,运行一下Charter2Main.java

    Charter2Main 中传入的pk参数是10,被typeHandler默默的转换成了guoyansi;
    因为guoyansi在数据库中找到了值,在被返回到java中,guoyansi又被typeHandler转化成了60;
    这个例子展示的就是Integer和String之间的转换。
  • 相关阅读:
    笔记-树形dp
    20181018 考试记录
    20181015 考试记录&数论
    [模板]2-SAT 问题&和平委员会
    FLask的偏函数应用
    Flask中的g到底是个什么鬼?
    Flask源码关于local的实现
    Flask的“中间件”
    Flask之模板
    FLask之视图
  • 原文地址:https://www.cnblogs.com/guoyansi19900907/p/9601973.html
Copyright © 2011-2022 走看看