您好,登錄后才能下訂單哦!
前言
最近在工作中遇到一個問題,在設計數(shù)據(jù)庫的時候,我們有時候會把表里的某個字段的值設置為數(shù)字或者為英文來表示他的一些特殊含義。就拿設置成數(shù)字來說,假如1對應是學生,2對應是教師,在Java里面定義成這樣的枚舉,但是一般使用mybatis查出來的話,我們想要讓它自動裝換成我們想要的枚舉,不需要再手動根據(jù)數(shù)值去判斷設置成我們想要的枚舉。要是實現(xiàn)這樣的效果,那么我們就要用到mybatis的BaseTypeHandler了。
BaseTypeHandler介紹
讓我們來看看要繼承BaseTypeHandler這個抽象類,需要覆寫哪些方法:
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;
實現(xiàn)了這些抽象類,當?shù)玫浇Y(jié)果集的時候,程序就會回調(diào)這些方法,例如根據(jù)名稱獲取當前行的某一列的值,那么就會直接回調(diào)getNullableResult(ResultSet rs, String columnName)
這個方法,根據(jù)名稱得到當行的當前列的值,然后我們在這里去調(diào)用枚舉,匹配枚舉中的每一個值,相等的話直接返回該枚舉,達到自動轉(zhuǎn)換成我們想要的枚舉的效果。其他的重載方法類似,只不過是有些根據(jù)列索引,有些根據(jù)列名稱做枚舉自動轉(zhuǎn)換而已。
好了,介紹就到這里,讓我們來看看具體實現(xiàn)。。
自動轉(zhuǎn)換實現(xiàn)例子
創(chuàng)建數(shù)據(jù)庫表
創(chuàng)建枚舉
package net.itaem.less; import java.util.HashMap; import java.util.Map; /** * @author: Fighter168 */ public enum PersonType{ STUDENT("1","學生"), TEACHER("2","教師"); private String value; private String displayName; static Map<String,PersonType> enumMap=new HashMap<String, PersonType>(); static{ for(PersonType type:PersonType.values()){ enumMap.put(type.getValue(), type); } } private PersonType(String value,String displayName) { this.value=value; this.displayName=displayName; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public String getDisplayName() { return displayName; } public void setDisplayName(String displayName) { this.displayName = displayName; } public static PersonType getEnum(String value) { return enumMap.get(value); } }
創(chuàng)建Po實體類
/** * @author: Fighter168 */ public class Person { private String id; private String name; //枚舉 private PersonType personType; //set get 方法。。 }
創(chuàng)建Dao接口
創(chuàng)建一個簡單的測試dao,這里簡單的提供一個測試的查詢方法。
/** * @author: Fighter168 */ public interface PersonDao { public List<Person> query(); }
創(chuàng)建枚舉轉(zhuǎn)換處理器
package net.itaem.handler; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import net.itaem.less.PersonType; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; /** * @author: Fighter168 */ public class PersonTypeHandler extends BaseTypeHandler<PersonType>{ private Class<PersonType> type; private PersonType[] enums; /** * 設置配置文件設置的轉(zhuǎn)換類以及枚舉類內(nèi)容,供其他方法更便捷高效的實現(xiàn) * @param type 配置文件中設置的轉(zhuǎn)換類 */ public PersonTypeHandler(Class<PersonType> type) { if (type == null) throw new IllegalArgumentException("Type argument cannot be null"); this.type = type; this.enums = type.getEnumConstants(); if (this.enums == null) throw new IllegalArgumentException(type.getSimpleName() + " does not represent an enum type."); } @Override public PersonType getNullableResult(ResultSet rs, String columnName) throws SQLException { // 根據(jù)數(shù)據(jù)庫存儲類型決定獲取類型,本例子中數(shù)據(jù)庫中存放String類型 String i = rs.getString(columnName); if (rs.wasNull()) { return null; } else { // 根據(jù)數(shù)據(jù)庫中的value值,定位PersonType子類 return PersonType.getEnum(i); } } @Override public PersonType getNullableResult(ResultSet rs, int columnIndex) throws SQLException { // 根據(jù)數(shù)據(jù)庫存儲類型決定獲取類型,本例子中數(shù)據(jù)庫中存放String類型 String i = rs.getString(columnIndex); if (rs.wasNull()) { return null; } else { // 根據(jù)數(shù)據(jù)庫中的value值,定位PersonType子類 return PersonType.getEnum(i); } } @Override public PersonType getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { // 根據(jù)數(shù)據(jù)庫存儲類型決定獲取類型,本例子中數(shù)據(jù)庫中存放String類型 String i = cs.getString(columnIndex); if (cs.wasNull()) { return null; } else { // 根據(jù)數(shù)據(jù)庫中的value值,定位PersonType子類 return PersonType.getEnum(i); } } @Override public void setNonNullParameter(PreparedStatement ps, int i, PersonType parameter, JdbcType jdbcType) throws SQLException { // baseTypeHandler已經(jīng)幫我們做了parameter的null判斷 ps.setString(i, parameter.getValue()); } }
創(chuàng)建Mapper映射文件
PersonDao對應的PersonMapper映射文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="net.itaem.dao.PersonDao" > <resultMap id="resultMap" type="net.itaem.po.Person" > <result column="id" property="id" jdbcType="CHAR" /> <result column="name" property="name" jdbcType="CHAR" /> <result column="type" property="personType" jdbcType="CHAR" /> </resultMap> <select id="query" resultMap="resultMap"> select * from person </select> </mapper>
其實handler還可以寫在PersonMapper.xml這里,寫成下面這樣:
<result column="type" property="personType" typeHandler="net.itaem.handler.PersonTypeHandler"/>
創(chuàng)建Spring的配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> <property name="username" value="root"/> <property name="password" value="123abc"/> <!-- 連接池啟動時候的初始連接數(shù) --> <property name="initialSize" value="10"/> <!-- 最小空閑值 --> <property name="minIdle" value="5"/> <!-- 最大空閑值 --> <property name="maxIdle" value="20"/> <property name="maxWait" value="2000"/> <!-- 連接池最大值 --> <property name="maxActive" value="50"/> <property name="logAbandoned" value="true"/> <property name="removeAbandoned" value="true"/> <property name="removeAbandonedTimeout" value="180"/> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="configLocation" value="classpath:/resource/cfg.xml"/> <property name="dataSource" ref="dataSource"/> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="net.itaem.dao"/> </bean> </beans>
創(chuàng)建mybatis的配置文件
下面是為mybatis創(chuàng)建配置文件cfg.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> <typeHandlers> <typeHandler handler="net.itaem.handler.PersonTypeHandler" javaType="net.itaem.less.PersonType" jdbcType="CHAR"/> </typeHandlers> <!-- mapping 文件路徑配置 --> <mappers> <mapper resource="resource/PersonMapper.xml" /> </mappers> </configuration>
創(chuàng)建測試用例
/** * @author: Fighter168 */ public class SpringTest { public static void main(String[] args) { ApplicationContext context=new ClassPathXmlApplicationContext("resource/ApplicationContext.xml"); PersonDao personDao=(PersonDao) context.getBean("personDao"); List<Person> list=personDao.query(); for(Person p:list){ System.out.println(p.toString()); } } }
測試結(jié)果展示
結(jié)果是成功自動轉(zhuǎn)換成了我們想要的枚舉
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。