mysql 定义XML字段_MyBatis之基于XML的属性与列名映射
上一博客主要是對單表的增刪改查,比較簡單,而且每個屬性與table表的列都是一一對應(yīng)名字也一樣,今天主要學習屬性與table表列名不一致的處理,主要有兩種一是屬性與列名不一致,二是枚舉的情況,這里暫時考慮的屬性與列名不一致只是單表的情況,至于屬性如果是其他model涉及表與表之間的關(guān)系的放在下一博客。不過先介紹幾個其他的知識點。這些都是參考官網(wǎng)http://www.mybatis.org/mybatis-3/zh/index.html,大家也可以直接參考官網(wǎng)的。本篇博客還是在上一篇博客的基礎(chǔ)上做的修改。
一、Properties
上一博客創(chuàng)建了一個DBConfig.xml,因為在上一博客只是做了關(guān)于數(shù)據(jù)庫的配置,其實它不僅僅可以配置數(shù)據(jù)庫的屬性,還可以配置其他的好多屬性,比如properties。所以從這篇開始把DBConfig.xml的名字改為了Config.xml。這里為了使用properties,先建了一properties文件:config.properties.
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis
在Config.xml的configuration節(jié)點增加如下配置:
如果再配置數(shù)據(jù)庫連接的話就可以使用properties。
View Code
還有就是Properties在configuration節(jié)點設(shè)置的位置的問題,可以按照下圖的順序設(shè)置各個屬性節(jié)點,因為在這個地方我也踩到了坑,就是在使用typeAlias的時候,我把typeAlias放在了mappers下面,然后就報錯了。
二、typeAlias
alias別名,這個在sql種也經(jīng)常用到,在上一博客種我們在UserMapper.xml種如果要參數(shù)類型或返回值類型時都會這樣Cuiyw.MyBatis.Model.User寫上User的全稱,其實我們可以使用typeAlias來簡化它來減少冗余。這樣在用到Cuiyw.MyBatis.Model.User的地方都可以用別名User代替。
如果還覺得麻煩,可以直接指定包名就可以了。
三、屬性與列名映射
這是今天的主題,主要是兩個內(nèi)容,一是枚舉類型映射,二是屬性名與列名不一致怎么映射。
1.自帶枚舉
如果想使用mybatis自帶的枚舉類處理,有2種方式,一個是EnumTypeHandler,一個是EnumOrdinalTypeHandler。2者的區(qū)別是EnumTypeHandler直接存儲name值,而EnumOrdinalTypeHandler會存儲enum類里的序號值,此時數(shù)據(jù)庫表字段一般用int類型的處理。
SELECT LAST_INSERT_ID()insert into user(name,age,status) values (#{name},#{age},#{status,typeHandler=org.apache.ibatis.type.EnumTypeHandler})
SELECT LAST_INSERT_ID()insert into user(name,age,status) values (#{name},#{age},#{status,typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler})
上面就是就是使用兩種方式實現(xiàn)的新增,下面截圖是兩種方式在數(shù)據(jù)庫的存儲情況。
2.resultMap
上面在sql中的status參數(shù)中配置,但對于select的操作沒有參數(shù)那該怎么辦呢?于是resultMap出現(xiàn)了。其實它的作用還有好多,今天主要用它做個簡單的例子,同時也演示列名和屬性名不一致的情況。雖然先只考慮單表的情況,有時候數(shù)據(jù)庫表的字段名與類的屬性名也可能不是一一對應(yīng)的,這種怎么解決呢?我們可以使用resultMap,用它來做關(guān)系映射,這樣以后在用到的地方也只需要在select中增加屬性resultMap,引用的它id就好也特別方便。這里要注意就是在resultMap設(shè)置的typeHandler與在insert中設(shè)置的要一致。
select * from user where id=#{id}
還是使用昨天的代碼,先增加一個,然后把增加的通過id查詢出來。
3.自定義枚舉
有時候mybatis自帶的枚舉并不能滿足需求,那我們也可以自定義枚舉。MyBatis提供了org.apache.ibatis.type.BaseTypeHandler類用于我們自己擴展類型轉(zhuǎn)換器,上面的EnumTypeHandler和EnumOrdinalTypeHandler也都實現(xiàn)了這個接口。
User類
packageCuiyw.MyBatis.Model;public enumUserState {
DISABLED(0),
AVAILABLE(1);private intstatus;
UserState(intstatus)
{this.status=status;
}public static UserState fromValue(intvalue)
{for(UserState userState:UserState.values())
{if(userState.status==value)
{returnuserState;
}
}throw new IllegalArgumentException("Cannot create evalue from value: " + value + "!");
}public intgetStatus()
{returnstatus;
}
}
View Code
EnumStatusHandler自定義枚舉類? 這里采用的EnumOrdinalTypeHandler模式,保存數(shù)字。在用的時候直接引用就好了。
packageCuiyw.MyBatis.Model;importjava.sql.CallableStatement;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;importorg.apache.ibatis.type.BaseTypeHandler;importorg.apache.ibatis.type.JdbcType;public class EnumStatusHandler extends BaseTypeHandler{
@Overridepublic void setNonNullParameter(PreparedStatement ps, inti, UserState parameter, JdbcType jdbcType)throwsSQLException {//TODO Auto-generated method stub
ps.setInt(i, parameter.getStatus());
}
@Overridepublic UserState getNullableResult(ResultSet rs, String columnName) throwsSQLException {//TODO Auto-generated method stub
returnUserState.fromValue(rs.getInt(columnName));
}
@Overridepublic UserState getNullableResult(ResultSet rs, int columnIndex) throwsSQLException {//TODO Auto-generated method stub
returnUserState.fromValue(rs.getInt(columnIndex));
}
@Overridepublic UserState getNullableResult(CallableStatement cs, int columnIndex) throwsSQLException {//TODO Auto-generated method stub
returnUserState.fromValue(cs.getInt(columnIndex));
}
}
View Code
4.自定義枚舉優(yōu)化
上面是針對每個枚舉類型創(chuàng)建一個TypeHandler,那如果多的話豈不是很麻煩,那該怎么辦呢?有什么優(yōu)化的方法沒?答案當然是有的啦。有單獨的一個轉(zhuǎn)到能應(yīng)用多個,那就會聯(lián)想的泛型。
1.定義接口
packageCuiyw.MyBatis.Model;public interfaceValuedEnum {intgetValue();
}
2.枚舉實現(xiàn)接口
packageCuiyw.MyBatis.Model;public enum UserState implementsValuedEnum {
DISABLED(0),
AVAILABLE(1);private intstatus;
UserState(intstatus)
{this.status=status;
}//public static UserState fromValue(int value)//{//for(UserState userState:UserState.values())//{//if(userState.status==value)//{//return userState;//}//}//throw new IllegalArgumentException("Cannot create evalue from value: " + value + "!");//}//
//public int getStatus()//{//return status;//}
public intgetValue() {//TODO Auto-generated method stub
returnstatus;
}
}
View Code
3.定義EnumTypeHandler
在ValuedEnumTypeHandler構(gòu)造函數(shù)中使用了getEnumConstants()方法,它以聲明順序返回一個數(shù)組,該數(shù)組包含構(gòu)成此 class 對象所表示的枚舉類的值,或者在此 class 對象不表示枚舉類型時返回 null,這樣就可以把枚舉值與數(shù)字值對應(yīng)起來放在map中。
packageCuiyw.MyBatis.Model;importjava.sql.CallableStatement;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.util.HashMap;importjava.util.Map;importorg.apache.ibatis.type.BaseTypeHandler;importorg.apache.ibatis.type.JdbcType;public class ValuedEnumTypeHandler > extends BaseTypeHandler{private Classtype;private Map map = new HashMap();public ValuedEnumTypeHandler(Classtype) {if (type == null) {throw new IllegalArgumentException("Type argument cannot be null");
}this.type =type;
E[] enums=type.getEnumConstants();if (enums == null) {throw new IllegalArgumentException(type.getSimpleName() + " does not represent an enum type.");
}for(E e : enums) {
ValuedEnum valuedEnum=(ValuedEnum) e;
map.put(valuedEnum.getValue(), e);
}
}
@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throwsSQLException {//TODO Auto-generated method stub
ValuedEnum valuedEnum =(ValuedEnum) parameter;
ps.setInt(i, valuedEnum.getValue());
}
@Overridepublic E getNullableResult(ResultSet rs, String columnName) throwsSQLException {int i =rs.getInt(columnName);if(rs.wasNull()) {return null;
}else{returngetValuedEnum(i);
}
}
@Overridepublic E getNullableResult(ResultSet rs, int columnIndex) throwsSQLException {int i =rs.getInt(columnIndex);if(rs.wasNull()) {return null;
}else{returngetValuedEnum(i);
}
}
@Overridepublic E getNullableResult(CallableStatement cs, int columnIndex) throwsSQLException {int i =cs.getInt(columnIndex);if(cs.wasNull()) {return null;
}else{returngetValuedEnum(i);
}
}private E getValuedEnum(intvalue) {try{returnmap.get(value);
}catch(Exception ex) {throw newIllegalArgumentException("Cannot convert " + value + " to " + type.getSimpleName() + " by value.", ex);
}
}
}
View Code
4.使用
總結(jié)
以上是生活随笔為你收集整理的mysql 定义XML字段_MyBatis之基于XML的属性与列名映射的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: influxdb mysql对比_Inf
- 下一篇: jdbc mysql user_tab_