mysql 定义XML字段_MyBatis之基于XML的属性与列名映射

上一博客主要是对单表的增删改查,比较简单,而且每个属性与table表的列都是一一对应名字也一样,今天主要学习属性与table表列名不一致的处理,主要有两种一是属性与列名不一致,二是枚举的情况,这里暂时考虑的属性与列名不一致只是单表的情况,至于属性如果是其他model涉及表与表之间的关系的放在下一博客。不过先介绍几个其他的知识点。这些都是参考官网http://www.mybatis.org/mybatis-3/zh/index.html,大家也可以直接参考官网的。本篇博客还是在上一篇博客的基础上做的修改。

一、Properties

上一博客创建了一个DBConfig.xml,因为在上一博客只是做了关于数据库的配置,其实它不仅仅可以配置数据库的属性,还可以配置其他的好多属性,比如properties。所以从这篇开始把DBConfig.xml的名字改为了Config.xml。这里为了使用properties,先建了一properties文件:config.properties.

driver=com.mysql.jdbc.Driver

url=jdbc:mysql://localhost:3306/mybatis

在Config.xml的configuration节点增加如下配置:

如果再配置数据库连接的话就可以使用properties。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

View Code

还有就是Properties在configuration节点设置的位置的问题,可以按照下图的顺序设置各个属性节点,因为在这个地方我也踩到了坑,就是在使用typeAlias的时候,我把typeAlias放在了mappers下面,然后就报错了。

c3956ea7682812f04ab1dc45d562e7c3.png

二、typeAlias

alias别名,这个在sql种也经常用到,在上一博客种我们在UserMapper.xml种如果要参数类型或返回值类型时都会这样Cuiyw.MyBatis.Model.User写上User的全称,其实我们可以使用typeAlias来简化它来减少冗余。这样在用到Cuiyw.MyBatis.Model.User的地方都可以用别名User代替。

如果还觉得麻烦,可以直接指定包名就可以了。

三、属性与列名映射

这是今天的主题,主要是两个内容,一是枚举类型映射,二是属性名与列名不一致怎么映射。

1.自带枚举

如果想使用mybatis自带的枚举类处理,有2种方式,一个是EnumTypeHandler,一个是EnumOrdinalTypeHandler。2者的区别是EnumTypeHandler直接存储name值,而EnumOrdinalTypeHandler会存储enum类里的序号值,此时数据库表字段一般用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})

上面就是就是使用两种方式实现的新增,下面截图是两种方式在数据库的存储情况。

843b13a5ae5757159d6cb144bd1510f5.png

2.resultMap

上面在sql中的status参数中配置,但对于select的操作没有参数那该怎么办呢?于是resultMap出现了。其实它的作用还有好多,今天主要用它做个简单的例子,同时也演示列名和属性名不一致的情况。虽然先只考虑单表的情况,有时候数据库表的字段名与类的属性名也可能不是一一对应的,这种怎么解决呢?我们可以使用resultMap,用它来做关系映射,这样以后在用到的地方也只需要在select中增加属性resultMap,引用的它id就好也特别方便。这里要注意就是在resultMap设置的typeHandler与在insert中设置的要一致。

select * from user where id=#{id}

还是使用昨天的代码,先增加一个,然后把增加的通过id查询出来。

d4b3e2ab8c6992db5d6de6cafb95152f.png

3.自定义枚举

有时候mybatis自带的枚举并不能满足需求,那我们也可以自定义枚举。MyBatis提供了org.apache.ibatis.type.BaseTypeHandler类用于我们自己扩展类型转换器,上面的EnumTypeHandler和EnumOrdinalTypeHandler也都实现了这个接口。

User类

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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模式,保存数字。在用的时候直接引用就好了。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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.自定义枚举优化

上面是针对每个枚举类型创建一个TypeHandler,那如果多的话岂不是很麻烦,那该怎么办呢?有什么优化的方法没?答案当然是有的啦。有单独的一个转到能应用多个,那就会联想的泛型。

1.定义接口

packageCuiyw.MyBatis.Model;public interfaceValuedEnum {intgetValue();

}

2.枚举实现接口

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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构造函数中使用了getEnumConstants()方法,它以声明顺序返回一个数组,该数组包含构成此 class 对象所表示的枚举类的值,或者在此 class 对象不表示枚举类型时返回 null,这样就可以把枚举值与数字值对应起来放在map中。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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.使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值