1. 前言

通常后台开发中与数据库打交道是必不可少的。Java中原生操作数据库是通过JDBC是处理的,但是步骤繁琐,冗余,性能较低。为解决这些问题,就出现了各种数据库持久层框架,其中比较灵活轻量的框架就是Mybatis了,也是大部分公司采用的技术。

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级射映。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

我们经常需要编写Mapper接口以及对应的xml文件 ,那么问题来了,在xml文件中如何接收接口中的参数呢??尤其是复杂的Java对象如何取值,这是个值得底层开发人员必须知道的问题。

2. 具体场景

(1)Mapper参数类型

mapper接口中的参数如果是

a. 多个参数;

b. 参数是集合或者数组。

这两种情况下一定要写@Param(value = "XXX")

void deleteByIds(@Param(value = "ids") Set<String> ids);

对应的xml文件:

<delete id="delete" parameterType="java.util.Set">DELETE FROM<include refid="tableName" />WHERE id in<foreach collection="ids" item="item" open="(" close=")"index="index" separator=",">#{item,jdbcType=VARCHAR}</foreach>
</delete>

注意collection="ids"与@Param(value = "ids")需要对应。

(2) 批量操作

对于上面的根据id 进行批量删除,采用foreach没有问题,但是如果是根据多个参数进行批量删除,比如:

<foreach  open="(" close=")" separator=";"<delete id="delete" parameterType="java.util.List">delete from tableName where id=#{id} and parentId=#{paretnId}</delete>
</foreach>

这种语句采用foreach将参数 填入则会出现错误。目前解决的方式是在service层对集合遍历然后调用对应的mapper,这中方式当数据量大的时候可能会阻塞程序,当然还可以采用case when的xml书写,但是比较复杂。

(3) TypeHandler的使用方式

通常,我们定义实体类对象包含各种数据,基本类型,时间,枚举类,布尔型,集合类等其他包装类型,那么在做resultMap映射时,除开基本类型和时间类型mybatis可以自动对应数据库中字段,其他类型都需要做个类型转换的帮助类,下面展示的是将常用类型转化为字符类型,以便存入数据库。由于便于集中处理,数据库中使用的字段全为varchar。

(a) set集合映射

如果在resultMap中有字段的映射,要跟上typeHandler;

<result column="ids" jdbcType="VARCHAR"property="ids"typeHandler="typeHandler.Set2CharTypeHandler" />

如果在增删改查的操作中,需要用到此字段,也必须加上typeHandler;

<if test="ids!=null">ids=#{filterPolicyIds,jdbcType=VARCHAR,typeHandler=typeHandler.Set2CharTypeHandler},
</if>

我们要做的就是就是编写Set2CharTypeHandler类实现TypeHandler接口,重写三个方法。mybatis会去遍历所有的TypeHandler找到对应的类型,将set集合与string 做相应的互转。

public class Set2CharTypeHandler implements TypeHandler {//存入数据的时候要调用的方法@Overridepublic void setParameter(PreparedStatement preparedStatement, int i, Object o, JdbcType jdbcType) throws SQLException {Set list = (Set)o;String setStr = StringUtils.join(list,",");preparedStatement.setString(i,setStr);}//下面两种方法是取数据时候需要调用@Overridepublic Object getResult(ResultSet resultSet, String s) throws SQLException {String result = resultSet.getString(s);String [] arrRes = result.split(",");return new HashSet<>(Arrays.asList(arrRes));}@Overridepublic Object getResult(CallableStatement callableStatement, int i) throws SQLException {String result = callableStatement.getString(i);String [] arrRes = result.split(",");return new HashSet<>(Arrays.asList(arrRes));}}

(b) 布尔类的映射

  • resultMap的映射:

<result column="enable" jdbcType="VARCHAR" property="enable"typeHandler="typeHandler.Bool2CharTypeHandler" />
  • 增删改查的操作字段映射:

<if test="enable!='null'">enable = #{enable,typeHandler=typeHandler.Bool2CharTypeHandler}
</if>
  • typeHandler代码示范:

注意@MappedJdbcTypes(JdbcType.VARCHAR)  和 @MappedTypes(Boolean.class) 不是必须的

@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(Boolean.class)
public class Bool2CharTypeHandler implements TypeHandler {@Overridepublic void setParameter(PreparedStatement preparedStatement, int i, Object o, JdbcType jdbcType) throws SQLException {boolean enable = (boolean)o;preparedStatement.setString(i,enable?"Y":"N");}@Overridepublic Boolean getResult(ResultSet resultSet, String s) throws SQLException {String result = resultSet.getString(s);return StringUtils.isEmpty(result)?false:result.equalsIgnoreCase("Y")?true:false;}@Overridepublic Boolean getResult(CallableStatement callableStatement, int i) throws SQLException {String result = callableStatement.getString(i);return StringUtils.isEmpty(result)?false:result.equalsIgnoreCase("Y")?true:false;}
}

(c) 枚举类的映射

  • 枚举类的定义

public enum RoleCategory {USER("U"),RESOURCE("R");@Getterprivate String type;private RoleCategory(String type) {this.type=type;}public static RoleCategory fromType(String type) {for(RoleCategory item:values()) {if(item.type.equalsIgnoreCase(type)||item.toString().equalsIgnoreCase(type)) {return item;}}throw new CodedException(IErrorCodeService.NOT_SUPPORT_TYPE_OR_FUNCTION,"not support role category[\"+type+\"].");}
}
  • typeHandler代码示范

@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(RoleCategory.class)
public class RoleCategory2StringTypeHandler implements TypeHandler{@Overridepublic void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {RoleCategory category=(RoleCategory)parameter;ps.setString(i,category.getType());      }@Overridepublic RoleCategory getResult(ResultSet rs, String columnName) throws SQLException {String result = rs.getString(columnName);      return RoleCategory.fromType(result);}@Overridepublic RoleCategory getResult(CallableStatement cs, int columnIndex) throws SQLException {String result = cs.getString(columnIndex);   return RoleCategory.fromType(result);}
}

(d) 复杂包装类

  • 类型定义:

包含自定义对象Target,List, Set,枚举类RoleCatetory

@Data
public class PolicySet{private String description;private Target target;private List<Policy> policies=new ArrayList<>();private RoleCategory role=RoleCategory.USER;private Set<String> referencedPolicyId=new HashSet<>();
}
  • typeHandler代码, 这里使用了JSON解析:

public class PolicyModelTypeHandler implements TypeHandler {@Overridepublic void setParameter(PreparedStatement preparedStatement, int i, Object o, JdbcType jdbcType) throws SQLException {preparedStatement.setString(i, JSON.toJSONString(o));}@Overridepublic PolicySet getResult(ResultSet resultSet, String s) throws SQLException {String result = resultSet.getString(s);return JSON.parseObject(result,PolicySet.class);}@Overridepublic PolicySet getResult(CallableStatement callableStatement, int i) throws SQLException {String result = callableStatement.getString(i);return JSON.parseObject(result,PolicySet.class);}
}

转载于:https://my.oschina.net/woniuyi/blog/3007593

2019年1月实习总结-Mabatis相关相关推荐

  1. 某马php就业班资源,某论坛搞的最新2019年3月开课的*马PHP76期(基础班+就业班)...

    781375e68ef3264f0e.png (15.06 KB) 2020-3-11 22:01 上传 951315e68ef400f71d.png (19.62 KB) 2020-3-11 22: ...

  2. 机器人工程专业简介与开设高校名单详细完整版(2019年4月更新-专业代码:080803T)

    中小学(K12)人工智能和机器人兴趣(STEAM)基础内容推荐: https://blog.csdn.net/ZhangRelay/article/details/83988827 2018 ROS ...

  3. 安卓 每日一题 2019年9-12月问题及答案

    最新 文章连接,本文不再同步 安卓 每日一题 2019年9-12月问题及答案 文章目录 安卓 每日一题 2019年9-12月问题及答案 安卓2019年09月每日一题 安卓2019年10月每日一题 安卓 ...

  4. 天津12月计算机二级报名入口,2019年12月天津计算机二级考试报名入口已开通

    [摘要]天津市2019年12月计算机二级考试报名入口已开通,准备参加天津12月考试的小伙伴们抓紧时间去报名了,为了方便大家报名,环球网校小编整理了2019年12月天津计算机二级考试报名入口,小伙伴们快 ...

  5. 资源|2019 年 11 月最新《TensorFlow 2.0 深度学习算法实战》中文版教材免费开源(附随书代码+pdf)...

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送 2019 年 10 月,谷歌正式宣布,开源机器学习库 TensorFlow 2.0 现在 ...

  6. vb中mschart利用数组作图_选考VB算法解析之2019年4月高考真题卷第17题

    说在前面 在对数组排序时,我们常把数组分成已排序区域和待排序区域,并使用左右边界来划分待排序区域的范围:对分查找时我们也引入了左右边界的概念.可见左右边界在数组中是一个非常重要的概念,它在分段处理数组 ...

  7. 吉林省计算机等级二级,吉林省2019年9月计算机等级二级考试教程:二级MSOffice高级应用上机指导...

    &nbsp&nbsp[导读]:吉林省2019年9月计算机等级二级考试教程:二级MSOffice高级应用上机指导,更多吉林等级考试计算机等级考试用书,请访问易考吧吉林等级考试栏目 吉林省 ...

  8. 2019年1月14日【第一天正式学习】

    2019年1月14日星期一 任务一.把 elfpass 拷贝进 seed 虚拟机,设成 root 所有 suid 程序,用普通用户去攻击获得 root权限.可以先静态分析,搞不定再用 gdb 动态调试 ...

  9. mysql 数据趋势,2019年8月全球数据库流行度排行--oracle、mysql增长趋势明显

    在谈论数据库的最新趋势时,我们习惯了参考DB-Engine上所提供的排名信息.每当新的报告出来时,我们也时常看到各个媒体网站争先发布关于最新排名的分析内容. 前段时间DB-Engines 的2019年 ...

最新文章

  1. 在CSS中定义a:link、a:visited、a:hover、a:active顺序
  2. (十六)java springcloud版b2b2c社交电商spring cloud分布式微服务-使用spring cloud Bus刷新配置...
  3. eclipse常用快捷键汇总
  4. casio dt-930 条码采集器 盘点软件源程序
  5. Linux cat指令(用于连接文件并打印到标准输出设备上)
  6. 罗达克氏血液学: 临床原理与应用 Rodak‘s Hematology: Clinical Principles and Applications
  7. C# Httpclient编程
  8. 安装MariaDB和Apache
  9. apache 反向代理_通过 Apache 与 Nginx 配置 AJP 配置反向代理
  10. AndroidStudio_后台_服务的介绍_生命周期_注册_启动停止---Android原生开发工作笔记215
  11. 单片机从00到99c语言,跪求单片机0~99数码管显示用C语言编写的程序
  12. Oracle Restart能够用来给Oracle GoldenGate 做 High Availability 使用么?
  13. c语言课外读书笔记谭浩强,谭浩强C语言读书笔记
  14. ACM大佬算法课程福利分享
  15. R语言绘制列线图nomogram分步骤从头到尾实战
  16. 中国传统文化课程笔记
  17. QCC3040---Local name module
  18. 正版星界边境服务器,《星界边境(Starbound)》正式版联机教程
  19. 从字符串中提取IP子串(C语言)
  20. Pinyin4J使用方法

热门文章

  1. 开发那些事儿:Go转码H.265异常导致视频播放黑屏的解决步骤
  2. 吐血力作:平台云deis之deis客户端使用
  3. iOS播放多种格式视频
  4. CentOS安装MySQL详解
  5. 数据库知识点+sql语句增删改查(详解)
  6. YOLO的XML和TXT标注文本解释
  7. Java+Servlet+filter+javascript+html+jsp登入注册更新个人信息
  8. [转]昨天电话面试,我痛斥自以为是的面试官
  9. 【算法】Java数据结构节点定义
  10. csapp大作业程序人生-Hello’s P2P