mybatis与springdata的一些简单比较与思考
主题
最近在用mybatis做项目,有一些感触想记录下,主要是mybatis(以及它的一些插件)相比较于Spring data(或者jpa,hibernate等)的优势地方.
感触
我觉得mybatis相比于Spring data的最大的几个优势的地方在于:
动态查询
不管是在之前的公司还是现在的公司都有很多这样的业务..比如进来先是一个查询界面,有N多条件,然后下面是个根据条件分页查询的数据,查出数据以后你可以进行一些修改呀查看呀等等操作.

这样的业务如果是Spring data来做的话比较麻烦.
因为上面的条件用户是可以输入也可以不输入的.在原本的公司我看到有几种解决方法:
1.自己动态的拼接hql.所以service的代码里会出现很多if(StringUtils.isEmpty(xxxx查询条件)){hql += "and xxx条件 = :XXX参数"}类似于这样的代码.这样首先是hql拼接,可读性是比较差的,另外SQL是在service层拼接的.可能代码复用的概率会小一点.
2.公司有自己的封装(http://www.cnblogs.com/abcwt112/p/5874401.html).简单来说就是指定一下这个查询是对应哪个entity.然后根据传过来的request里的paramter找到entity对应的field然后还是拼接sql....只不过自己在service里不用拼接了...可以稍微简化一些代码...但是不是很灵活..有些功能还没封装.比如or的条件连接就不行.只能拼接and...然后不能嵌套查询..所以可以说是1方法的简化版但是相比于自己拼接SQL有些常用的功能做不到.
3.虽然公司我一直没看到有人用过.但是我知道.Spring data是在jpa外包装了一层,jpa是有criteria的查询方式的.spring data也有相应的Specifications的那种查询方式.这种方法可以帮助我们动态拼接查询条件..(这种查询方式我用的很少.可能说的不一定对).我觉得这种查询方式有个最不方便的地方在于如果要多表关联查询,你的entity里没有@onetomany或者@manytomany或者@onetoone这样的关键的话你是取不到另外关联的那张表的..这样的话你就不可能拼接那个where条件..这样的情况还是蛮常见的,因为表的关联太多了.不是所有的关联都写成了成员域..所以这种查询方法也是有缺陷的..
总结下的话就是Spring data动态查询拼接SQL比较麻烦..主要是在service里经常要判断XXX参数用户有没有输入..有输入就hql+=....看起来SQL不直观.都不知道完整的SQL结构,也很容易拼错.
这样的业务如果mybatis来做:
1.按照我现在公司的套路,大概是最简单粗暴的.我们mybatis没用任何插件,也没有自动生成任何XML.纯手写.
那么我要做的也就是在XML里写个查询SQL对应的select语句.然后再拼接条件的时候可以用<if>标签去过滤就行了.
这样的好处就是SQL比较直观,到底查什么表一目了然,然后因为拼接SQL相当于是在dao层,所以复用概率会大一些.比如其他业务也要查这张表的数据,可以复用.
Entity与DTO
这个问题主要是entity与dto之间数据拷贝的问题,还有一些建表问题,没用过hibernate或者用hibernate自动生成表的朋友可能不会有这样的感觉.
Spring data:
因为spring data数据库映射到实体用的是entity,而前台显示用的是dto.所以数据肯定需要拷贝. 另外一个比较坑爹的地方是entity如果和spring data的session关联了的话,如果修改了字段,即使不显示的调用dao.update,在出了事务以后也会自动更新数据库的(因为是受管实体).所以拷贝是必须的.这样的话会需要一些时间,另外对象拷贝也蛮麻烦的.特别是还有集合的情况更是麻烦.(之前公司用cglib的bean copier http://www.cnblogs.com/abcwt112/p/6073103.html)
还有个小坑就是如果查出来的对象有懒加载的集合属性,那么当然前后台交互的时候,比如用jackson将entity转化成json的时候会自动调用entity的get方法,导致懒加载被触发,然后hibernate自动调用SQL去查询数据,然而那个时候事务早已关闭,会报错,这也是一个坑,以前公司基本上是一个业务域的相关联对象一次性查出来(也不是很多数据).
另外当建表不是很规范的时候(比如多表关联没有使用外键关联,而是共享主键,又是单向关联的时候)spring data jpa的级联操作可能会产生问题.(http://www.cnblogs.com/abcwt112/p/4849416.html)
mybatis:
很简单..查出什么数据直接用....
公司仍然有entity和dto.其实我觉得只需要留下dto就足够了.有2套对象的话如果dao里的方法的参数不同也是需要转化的.mybatis只是把数据库查询的结果映射到了dto上.我觉得没那么复杂...不需要2套对象.只有一套dto就足够了..还简单些.
非主键的CRUD操作
表的主键在很多时候都是ID自增或者uuid,但是用户并不会知道,他们知道的可能是业务上面的主键,比如超市商品的条形码等等.这种时候我们操作数据库可能不是根据id而是根据这种业务上面的唯一标示去操作数据库.
spring data:
我一直觉得这是Spring data相比于hibernate和jpa最引以为傲的功能,可以根据dao的方法名自动映射成sql.
比如findByName会被自动翻译成select * from xxx where name = :name
updateNameByStateAndLevelIsNotNull会被自动翻译成update xxx set name = :name where state = :state and level is not null
可以说Spring data可以在绝大部分情况下避免写SQL.所以操作数据库比较方便.美中不足的就是如果SQL比较长参数比较多..那么方法名也会比较长....有时候看起来比较累.
mybatis:
让我从首选spring data变成首选mybatis作为持久层框架的一个原因就在这里.(虽然spring data已经做的很好了)
按照公司的做法我们需要手写SQL...那是很坑爹的.绝对没有Spring data好用.但是eclipse有个mybatis的generator插件.......
他可以自动帮我们生成XML..这里生成的几个方法非常非常有用....
List<TmTransportAddressDto> selectByExample(TmTransportAddressExample example);
int updateByExampleSelective(@Param("record") TmTransportAddressDto record, @Param("example") TmTransportAddressExample example);
int updateByExample(@Param("record") TmTransportAddressDto record, @Param("example") TmTransportAddressExample example);
int countByExample(TmTransportAddressExample example);
int deleteByExample(TmTransportAddressExample example);
就是这几个example方法.
看一个使用example的小例子:
TmTransportAddressDto tmTransportAddressDto = new TmTransportAddressDto();
tmTransportAddressDto.setExecutePerson(tmTransportChangeRecord.getDriverNameAfter());
tmTransportAddressDto.setExecuteDeviceNo(tmTransportChangeRecord.getPlateNumberAfter());
tmTransportAddressDto.setExecuteTelephone(tmTransportChangeRecord.getDriverPhoneAfter());
TmTransportAddressExample tmTransportAddressExample = new TmTransportAddressExample();
tmTransportAddressExample.createCriteria()
.andExecuteTelephoneEqualTo(tmTransportChangeRecord.getDriverPhoneBefore()).andSnEqualTo(sn);
countUpdate += tmTransportAddressDao.updateByExampleSelective(tmTransportAddressDto,
tmTransportAddressExample);
上面这9行代码相当于是更新tmTransportAddress表的executePerson,executeDeviceNo等4个字段 where 条件是executeTelphone = XXX and sn = xxx.
这种用法比Spring data还要简单,连dao的方法名都不用写了(其实还是要写的.只是写在了example里...generator自动生成了通用的XML SQL片段)...非常非常好用!
再很多情况下只要自动生成了xml文件以后基本SQL和额外的dao方法都不需要写了..因为example相当于是动态拼接SQL的方法.可以拼接出任意的SQL.
不过我觉得这种用法还是不太适合页面上那种动态条件分页查询,因为也需要在service里拼接条件..只是简化了一些.并没有自己在XML里写完整的SQL直观.
小结
以上便是我最近2个月学习mybatis的一些感触.mybatis在很多情况下确实是比spring data简单好用(其实就是拼SQL的功能很强大).
后面会再分享一些如果我是架构师会怎么在项目里使用mybatis的一些想法
mybatis与springdata的一些简单比较与思考的更多相关文章
- springboot + mybatis 的项目,实现简单的CRUD
以前都是用Springboot+jdbcTemplate实现CRUD 但是趋势是用mybatis,今天稍微修改,创建springboot + mybatis 的项目,实现简单的CRUD 上图是项目的 ...
- 对Springdata模块的简单理解
有关于Spring对数据库的操作属于为Spring中的Springdata模块,对数据库的操作.Spring对JDBC和Mybatis都有封装与简化 可以从以下角度学习研究 SpringData: 1 ...
- mybatis学习笔记(一)-- 简单入门(附测试Demo详细过程)
写在最前 MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生M ...
- 让 MyBatis Generator 变的更简单
MyBatis 是一个 Java 的 ORM 框架,ORM 的出现就是为了简化开发.最初的开发方式是业务逻辑和数据库查询逻辑是分开的,或者在程序中编写 sql 语句,或者调用 sql 存储过程.这样导 ...
- MyBatis 学习记录1 一个简单的demo
主题 最近(N个月前)clone了mybatis的源码..感觉相比于spring真的非常小...然后看了看代码觉得写得很精简...感觉我的写代码思路和这个框架比较相似(很难具体描述...就是相对来说比 ...
- idea+Spring+Mybatis+jersey+jetty构建一个简单的web项目
一.先使用idea创建一个maven项目. 二.引入jar包,修改pom.xml <dependencies> <dependency> <groupId>org. ...
- mybatis 分页插件PageHelper的简单使用
首先在pom.xml配置文件中增加相关的插件. 插件地址:https://github.com/pagehelper/Mybatis-PageHelper <dependency> < ...
- SpringData Redis的简单使用
SpringDate Redis是在Jedis框架的基础之上对Redis进行了高度封装,通过简单的属性配置就可以通过调用方法完成对Redis数据库的操作,而且SpringData Redis使用了连接 ...
- Oracle+mybatis实现对数据的简单增删改查
第一步:--创建一个表空间:名字叫 mybatis,建在D盘下的date文件夹下: 第二步:创建用户,名字叫 lisi ,密码为 :123456 第三步:给用户授权: 第四步:我们在 li ...
随机推荐
- 呵呵sql
INSERT INTO fnd_document_folder_structure_t (folder_name,parent_folder_id,company_type_id,inv_flag, ...
- MySQL 导入.sql文件
对于新手,刚接触Mysql数据库不知道,怎么导入sql脚本数据库. 或者说几百M的,导入肯定会卡死,所以用命令来导入是比较好的选择, 讲下方法. 在 linux 终端下 执行 mysql -uroot ...
- MYSQL在当前日期的基础上加上N(年月日分秒)
//把id为1的那条数据的开始时间改为现在 结束时间改为开始时间的1个月后 update 表明 set begintime=now(),endtime=date_add(NOW(), interv ...
- 【mongodb】Mongodb初识
MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系 ...
- direct2d封装
图片项目
- 使用反相器的rc振荡电路
多谐振荡器是一种自激振荡电路,该电路在接通电源后无需外接触发信号就能产生一定频率和幅值的矩形脉冲波或方波.由于多谐振荡器在工作过程中不存在稳定状态,故又称为无稳态电路. 一.门电路组成的多谐振荡器 1 ...
- spring事务的配置
前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的. ...
- npm 可执行模块的开发&&私服发布
备注: 大家日常在使用npm 安装依赖的时候有一些是命令行工具,比如vue-cli,具体的开发比较简单,同时 可以基于此开发一些脚手架,方便开发. 1. 项目初始化 npm init 备注:按照 ...
- BZOJ1590:[Usaco2008 Dec]Secret Message秘密信息
浅谈\(Trie\):https://www.cnblogs.com/AKMer/p/10444829.html 题目传送门:https://lydsy.com/JudgeOnline/problem ...
- python自动发送邮件
Python 的 smtplib 模块提供了发送电子邮件的功能.测试报告出来后,然后就把报告发送到邮箱. 一.先来看简单的列子 使用QQ邮箱发送邮件,使用的是授权码,需要先到QQ邮箱申请授权码. 邮箱 ...