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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/297394.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Dapr闪电说 - Dapr落地云原生架构

你认识Dapr么?出自微软,面向社区,开源的云原生工具Dapr已经发布多时了,你了解Dapr的相关知识么?无论你是.NET程序员还是Python ,或者Java ,还有Go等都可以用Dapr来完成你的云原生场景。本次闪电…

uboot移植9个步骤_不知道具体的新房装修步骤?9个步骤教你吃透装修

最近有同学准备装修新房了,不知道具体的装修步骤是怎么样的,需要花多少预算?装修时间要多久?其实这也不奇怪,很多没有装修经验的朋友对这方面都不太了解的,今天分享一般装修的流程工序,希望能给…

太牛了,原来古人是这样铸造钱币的。。。

全世界只有3.14 % 的人关注了爆炸吧知识古代钱币是怎么做出来的呢?今天与各位说说古钱币的铸造工艺,抛砖引玉让大家更多了解假货的鉴别特点。关于古代钱币铸造工艺的记录文献资料,遗留极少。关于母钱翻砂技术,最早的史料见于明代宋…

渲染终极者 finalRender R3.5 SE for 3ds max/design 2009/2010/2011 32位/64位 汉

中文名: 终级渲染器 渲染终极者 finalRender R3.5 SE for 3ds max/design 2009/2010/2011 32位/64位 顶渲简体中文版 资源格式: 压缩包 版本: R3.5 发行时间: 2010年 制作发行: 原创:cebas VISUAL TECHNOLOGY Inc 中文:顶渲 Ma5 www.toprender.com 地区: 德国 语言: 简体中文,…

java赋值语句_java并发编程之原子性问题

程序是否线程安全,取决于哪些要素呢,主要是以下三个:原子性,可见性,有序性。今天先一起来学习原子性。原子性:我理解一个操作不可再分,即为原子性。而在并发编程的环境中,原子性的含…

“高阶思维”发展意识

1. 前言这个题目不太好交流,因为每个人的认知层面不同,不好达成大多数人趋近相同的看法。这个题目高度抽象化,不谈具体化的内容显得空洞及不容易理解,谈具体化的内容又无法找到着力点。抽象能力本身就是高阶思维的一种体现形式&a…

SQL Server返回当前实例系统日期和时间的函数

下面列举出SQL Server返回实例系统日期和时间的函数,除了ANSI标准函数CURRENT_TIMESTAMP在应用时无需在函数后多加一对空的小括号"()"外,其余均需。 从返回的数据类型"DATETIME2"就可以知道,后面三个函数是SQL Server 20…

培养沙雕要从娃娃抓起

1 培养沙雕要从娃娃抓起▼2 好了好了你们两个可以去洗发店门口上班了▼3 毛绒版俄罗斯方块纵享丝滑▼4 我还以为会有令人期待的被打环节▼5 小蜘蛛你好我是唐僧,请问我可以跟你回盘丝洞吗▼6 吃冰淇淋讲究直接上手▼7 在等奶茶的美团小哥我也想像他一样出门荡…

详解Ubuntu for Android:Thin Client

原文地址:http://blog.csdn.net/ce123/article/details/7291445 详解Ubuntu for Android:Thin Client 一、Ubuntu for Android的定义 在移动终端性能日益强大、多核处理器基本普及的现在,将通用的Ubuntu操作系统与Android系统进行亲密的整合&…

Dapr + .NET 实战(九)本地调试

前几节开发Dapr应用程序时,我们使用 dapr cli 来启动dapr服务,就像这样:dapr run --dapr-http-port 3501 --app-port 5001 --app-id frontend dotnet .\FrontEnd\bin\Debug\net5.0\FrontEnd.dll如果你想要通过dapr调试服务呢?在…

javadoc文档的生成方法_[springboot 开发单体web shop] 4. Swagger生成Javadoc

Swagger生成JavaDoc在日常的工作中,特别是现在前后端分离模式之下,接口的提供造成了我们前后端开发人员的沟通成本大量提升,因为沟通不到位,不及时而造成的[撕币]事件都成了日常工作。特别是很多的开发人员不擅长沟通,…

15个IT技术人员必须思考的问题

行内的人自嘲是程序猿、屌丝和码农,行外的人也经常拿 IT 人调侃,那么究竟是 IT 人没有价值,还是没有仔细思考过自身的价值? 1. 搞 IT 的是屌丝、码农、程序猿? 人们提到 IT 人的时候,总会想到他们呆板、不解…

mysql innodb表损坏_MySQL数据库INNODB表损坏修复处理过程分享

##状况描述突然收到MySQL报警,从库的数据库挂了,一直在不停的重启,打开错误日志,发现有张表坏了。innodb表损坏不能通过repair table 等修复myisam的命令操作。现在记录下解决过程,下次遇到就不会这么手忙脚乱了。处理…

20幅扎心漫画,道尽无数人的人生!30万网友:这简直是在偷窥我生活...

全世界只有3.14 % 的人关注了爆炸吧知识每个人在这世界上都是独特的个体但我们常常在很多方面把生活过得很类似在ins上,名叫Sanesparza的博主就把生活中的各种细节通过漫画的形式表达引来31万网友围观许多人纷纷表示:这不就是我吗!太扎心了&a…

多种方法解决Exchange 2010 EMC批量启用邮箱之后出..

平时大家在做Exchange 项目的时候都是需要批量导入AD账户和批量启用AD账户的邮箱,但是有一个比较奇怪的问题是当你使用Exchange 2010 EMC来批量启用邮箱之后会出现乱码问题,并且邮箱用户不能发送和接收电子邮件,那么该如何处理乱码问题呢?不要着急,其实有3种方法可以处理Excha…

matlab菲涅尔衍射_有问必答——SYNOPSYS安装体验课堂——可以设计菲涅尔透镜吗?...

问:SYNOPSYS可以设计菲涅尔透镜吗?答:在USS中有多种菲涅尔面型,用户输入参数即可。问:SYNOPSYS中具有的输入方式?答:大家总是有个误区,以为SYNOPSYS需要输入命令运行,其实…

WeakReference reference quene GC

在了解WeakReference之前,先给出一段简单的代码: public class WeakReferenceTest {public static void main(String[] args) throws Exception {Object o new Object();// 默认的构造函数&#xff0c;会使用ReferenceQueue.NULL 作为queueWeakReference<Object> wr ne…

北大4位数学天才,如今齐聚美国搞科研,令人叹息

全世界只有3.14 % 的人关注了爆炸吧知识最近这些年&#xff0c;计算机、电子产业异军突起&#xff0c;人工智能越来越受到追捧和重视&#xff0c;电子产品智能化已经成为发展的一种潮流和趋势。与此同时&#xff0c;国际竞争也日益激烈&#xff0c;这种竞争归根结底还是人才的竞…

为什么 Dapr 如此令人兴奋

如今你构建软件&#xff0c;您可以从数量众多的云服务中进行选择。仅 AWS 就每个月都在不断为其200多项服务添加新服务&#xff0c;而其他云提供商也都在跟上。如果您的公司想与您的竞争对手竞争&#xff0c;您就需要充分利用这些服务&#xff0c;这些服务在不同的云提供商都有…

java对象头_我的并发编程(二):java对象头以及synchronized升级过程

一、概述研究java对象头的目的是详细分析Java的synchronized锁的升级过程&#xff0c;因为synchronized在锁升级的时候&#xff0c;就是依赖对象头的信息来决定的。本博文针对64位的操作系统来对Java对象头进行详解。二、详细分析1. 用户态与内核态内核态与用户态是操作系统的两…