mybatis的typeHandler

来源:https://www.cnblogs.com/guoyansi19900907/archive/2018/09/06/9601973.html
-Advertisement-
Play Games

typeHandler作用: 1.傳參時將javaType類型轉換成jdbcType 2.結果集中ResultSet中取值時,jdbcType轉換為javaType; 系統自定義的typeHandler: 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之間的轉換。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • c/c++ 標準庫 vector 標準庫 vector的小例子 test1~test7 c++ include include using namespace std; class A{ public: A(){cout v1; vector v2; / //test2 / vector v3(2) ...
  • 題意 輸入一個整數X,求一個整數N,使得N!恰好大於$X^X$。 Sol 考試的時候只會$O(n)$求$N!$的首碼和啊。 不過最後的結論挺好玩的 $n! \approx \sqrt{2 \pi n} (\frac{n}{e})^n$ 然後就可以$O(1)$算啦 ...
  • python名片管理是我根據視頻自己敲敲的代碼,後續學習會持續更新 代碼 card_main.py card_tools.py ...
  • 集合中線程安全的類有:vector,stack,hashtable,enumeration,除此之外均是非線程安全的類與介面 Collection 是對象集合, Collection 有兩個子介面 List 和 Set, List 可以通過下標 (1,2..) 來取得值,值可以重覆,而 Set 只能 ...
  • 父類的靜態成員初始化>父類的靜態代碼塊>子類的靜態成員初始化>子類的靜態代碼塊>父類的代碼塊>父類的構造方法>子類的代碼塊>子類的構造方法 註意: 1.靜態成員和靜態代碼塊只有在類載入的時候執行一次,再次創建實例時,不再執行,因為只在方法區存在一份,屬於一整個類。 2.上述的是通用的載入順序,如果沒 ...
  • 1 import java.util.Arrays; 2 3 public class ArrayOperator { 4 5 public static void main(String[] args) { 6 // TODO Auto-generated method stub 7 ArrLis... ...
  • 我們都知道HashTable是線程安全的類,因為使用了Synchronized來鎖整張Hash表來實現線程安全,讓線程獨占; ConcurrentHashMap的鎖分離技術就是用多個鎖來控制對Hash表的不同部分進行修改,因為我可能只需要對一小塊部分進行操作,而如果鎖整張表開銷太大了,其內部實現就是 ...
  • 目錄 分隔符 字元類和類型 重覆 子表達式 子表達式計數 定位到字元串的開始或末尾 分支 匹配特殊字元 特殊字元含義 分隔符 正則表達式必須包含在一對分隔符中。可以選擇任何非字母,數字,"\" 或空格的字元作為分隔符。字元串的開始和結束必須有匹配的分隔符。 最常用的分隔符是"/"。 如匹配"shop ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...