版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
案例一:
数据库表使用了联合主键,逆向生成的时候生成了两个实体类。看起来别扭。
但还是可以用。后来就先取消主键,生成完后再将主键加上。还有就是,tinyint
本来以为用来表示比较小的整数,结果生成了布尔型的属性。后来就表示是和
否才用tinyint了。逆向生成的sql语句绝对不能人为改动,否则再次生成的
时候会重复生成。但遑,尽管踩过坑,我还是觉得mybatis超级好用,比
hibernate好多了。虽然hibernate我只试过一点之后就完全转向了mybatis
To
案例二:
sum()和count。使用场景不对导致出错:
count。、count。)、count(O)就是指绝对的行数,哪怕某行所有字段全部为
null也会计算在内。count⑴和count。相比Jnnodb来说count(*)效率低。
如果count(列名)查询出来的结果就是查出列名中不为null的行数;
sum(列名)对指定列名进行求和
MyBatis把int类型的0处理成空串''和mysql处理空串''为0的问题,在
Mybatis的hopper中整数类型条件该如何判断?
当数据库字段类型是整数,如果参数变量为空字符串或者NULL,Mybatis会
自动将参数赋值0,所以如果要判断整数参数的多种状态在传递数值到
Mapper之前就要判断是否为空字符串和NULL并将相应的状态数值赋值给该
参数,否则参数值等于空字符串、NULL和0得到的结果是一样的。
一般情况下,涉及到int类型的操作的时候,在Service中会统一把数字类型
先变成字符串类型,然后再传递到Mapper中操作。
时间戳的使用
在创建新记录的时候把这个字段设置为当前时间,但以后修改时,不再刷新它
(可以给createtime使用这个):
TIMESTAMPDEFAULTCURRENT_TIMESTAMP
在创建新记录和修改现有记录的时候都对这个数据列刷新(可以给update使
用这个):
TIMESTAMPDEFAULTCURRENT_TIMESTAMPONUPDATE
CURRENT_TIMESTAMP
在使用resultMap的时候,要把ID写在第一行,否则的话,就会报错。
案例三:
XML转义字符,如果直接写就会报错,需要用左边一列的转义字符
•<<小于号
•>>大于号
•&&和
•"单引号
•…双引号
案例四:
前几天在项目中碰到来说下吧。大神可绕道。在使用selectOne查询个数时,
如果你写了resultType为Integer然后在业务代码中很自然的用一个变量int
去接当前这个方法的返回,如果按照你传入的条件在数据库中没有找到相关的
值,止匕时selectOne方法的返回值会是一个null,当你使用Java的自动诉箱
机制的时候会报出一个无情的NPE。
原因:Java在自动拆箱的时候会调用Integer类中的intValue方法,如果当
前对象为则抛出
null,NPEW
因此,在接受的时候要判空,否则可能异常。
案例五:
多参数的使用
MyBatis的查询或者更新中,如果需要多个参数有如下几种办法:
•对象映射,建立一个Java对象,并作为接口的参数,对象的属性可以
直接使用#{属性名}的方式访问;
•Map,参数为一个Map,key对于属性名,value对于参数值,这个方
法就是传参数是需要建立一个Map的临时对象;
•@param参数注解,在接口方法参数前加入参数名称注解,这样就可以
直接在Mapper中通过参数名访问;
•通过序号访问,第一个参数#{0}或#223011},第二个参数#{1},
#{param2}
MyBatis中时间字段的使用-返回
时间字段的返回目前笔者采用放回字符串的方式:
date_format(update_time,,%Y-%c-%d%H:%i:%s')updatetime
采用MySQL的时间格式化方法。
或者放回Timestamp类型的数据,要求放回对象属性参数为Timestamp.
MyBatis中时间字段的使用-参数
如果需要查询一段时间范围的数据时,可以通过以下动态SQL的方式查询数
据:
andIbr.update_time>#{startTime}
andlbr.update_time<#{endTime,javaType=Date>jdbcType=TIMESTAMP}
对于的接口方法名称如下:
...DatestartTime^DateendTime...
我想这个方法会比通过格式转换的效率要高一些
MyBatis中时间字段的使用-写入
写入可是直接写入Timestamp的数据,需要描述一些写入的jdbcType,如
下:
{installTime,jdbcType=TIMESTAMP)
Mapper•层参数为Map,由Service层负责重载,
Mapper由于机制的问题,不能重载,参数一般设置成Map,但这样会使参
数变得模糊,如果想要使代码变得清晰,可以通过service层来实现重载的目
的,对外提供的Service层是重载的,但这些重载的Service方法其实是调同
一个Mapper,只不过相应的参数并不一致。
也许有人会想,为什么不在Service层也设置成M叩呢?我个人是不推荐这
么做的,虽然为了方便,我在之前的项目中也大量采用了这种方式,但很明显
会给日后的维护工作带来麻烦。因为这么做会使你整个MVC都依赖于Map
模型,这个模型其实是很不错的,方便搭框架,但存在一个问题:仅仅看方法
签名,你不清楚Map中所拥有的参数个数、类型、每个参数代表的含义。
试想,你只对Service层变更,或者DAO层变更,你需要清楚整个流程中
Map传递过来的参数,除非你注释或者文档良好,否则必须把每一层的代码
都了解清楚,你才知道传递了哪些参数。针对于简单MVC,那倒也还好,但
如果层次复杂之后,代码会变得异常复杂,而且如果我增加一个参数,需要把
每一个层的注释都添加上。相对于注释,使用方法签名来保证这种代码可斐性
会来得更可行一些,因为注释有可能是过时的,但方法签名一般不太可能是陈
旧的。
尽量少用ifchoose等语句,降低维护的难度。
Mybatis的配置SQL时,尽量少用ifchoose等标签,能用SQL实现判断的
尽量用SQL来判断(CASEWHEN.DECODE等),以便后期维护。否则,一旦
SQL膨胀,超级恶心,如果需要调试Mybatis中的SQL,需要去除大量的判
断语句,非常麻烦.另一方面,大量的if判断,会使生成的SQL中包含大量
的空格,增加网络传输的时间,也不可取。
而且大量的ifchoose语句,不可避免地,每次生成的SQL会不太一致,会导
致ORACLE大量的硬解析,也不可取。
我们来看看这样的SQL:
这样的if判断,其实是完全没有必要的,我们可以很简单的采用DECODE来解
决默认值问题:
当然有人会想,引入CASEWHEN,DECODE会导致需要ORACLE函数解析,
会拖慢SQL执行时间,有兴趣的同学可以回去做一下测试,看看是否会有大
的影响。就个人经验而言,在我的开发过程,没有发现因为函数解析导致SQL
变慢的情形。影响SQL执行效率的一般情况下是JOIN、ORDERBY、DISTINCT、
PARTITATIONBY等这些操作,这些操作一般与表结构设计有很大的关联。
相对于这些的效率影响程度,函数解析对于SQL执行速度影响应该是可以忽
略不计的。
另外一点对于一些默认值的赋值,像上面那条SQL,默认成当前日期什么的,
其实可以完全提到Service层或Controller层做处理,在Mybatis中应该要
少用这些判断。因为,这样的话,很难做缓存处理。如果startdate为空,在
SQL上使用动态的SYSDATE,就无法确定缓存startdate日期的key应该是
什么了。所以参数最好在传递至Mybatis之前都处理好,这样Mybatis层也
能减少部分ifchoose语句,同时也方便做缓存处理。
当然不使用ifchoose也并不是绝对的,有时候为了优化SQL,不得不使用if
来解决,比如说LIKE语句,当然一般不推荐使用LIKE,但如果存在使用的场
景尽可能在不需要使用时候去除LIKE比如查询文章标题以提高查询效率。
最好的方式是使用lucence等搜索引擎来解决这种全文索引的问题。
总的来说,if与choose判断分支是不可能完全去除的,但是推荐使用SQL
原生的方式来解决一些动态问题,而不应该完全依赖Mybatis来完成动态分
支的判断,因为判断分支过于复杂,而且难以维护。
用XML注释取代SQL注释。
Mybatis中原SQL的注释尽量不要保留,注释会引发一些问题,如果需要使
用注释,可以在XML中用来注释,保证在生成的SQL中不会存在SQL注释,
从而降低问题出现的可能性。这样做还有一个好处,就是在IDE中可以很清楚
的区分注释与SQL.
现在来谈谈注释引发的问题,我做的一个项目中,分页组件是基于Mybatis
的,它会在你写的SQL脚本外面再套一层SELECTCOUNT(*)ROWNUM,
FROM(....)计算总记录数,同时有另一个嵌套SELECT*FROM(...)WHERE
ROWNUM>10ANDRONNUM<10*2这种方式生成分页信息,如果你
的脚本中最后一行出现了注释,则添加的部分会成为注释的一部分,执行就会
报错。除此之外,某些情况下也可能导致部分条件被忽略,如下面的情况:
SELECT*FROMTEST
WHEREC0L1>1-这里是注释ANDC0L2=#{a}
即使传入的参数中存在对应的参数,实际也不会产生效果,因为后面的内容实
际上是被完全注释了。这种错误,如果不经过严格的测试,是很难发现的。-
般情况下,XML注释完全可以替代SQL注释,因此这种行为应该可以禁止掉。
尽可能使用'#{}',而不是'${}'.
Mybatis中尽量不要使用${},尽量这样做很方便开发,但是有一个问题,就
是大量使用会导致ORACLE的硬解析,拖慢数据库性能,运行越久,数据库
性能会越差。
关于${},另一个误用的地方就是LIKE,我这边还有个案例:比如一些树型菜
单,节点会设计成’01':0101',用两位节点来区分层级,这时候,如果需要查询
01节点下所有的节点,最简单的SQL便是:SELECT*FROMTREEWHEREID
LIKE6%',这种SQL其实无可厚非,因为它也能用到索引,所以不需要特别
的处理,直接使用就行了。但如果是文章标题,则需要额外注意了:SELECT*
FROMT_NEWS_TEXTWHERETITLELIKE'%OSC%',这是怎么也不会用到
索引的,上面说了,最好采用全文检索。但如果离不开LIKE,就需要注意使用
的方式:IDLIKE#{ID}||'%'而不是IDLIKE'
有人觉得使用||会增加ORACLE处理的时间我觉得不要把ORACLE看得太傻,
虽然有时候确实非常傻,有空可以再总结ORACLE傻不垃圾的地方,但是稍
加测试便知:这种串联方式,对于整个SQL的解析执行,应该是微乎其微的。
当然还有一些特殊情况是没有办法处理的,比如说动态注入列名、表名等。对
于这些情况,则比较棘手,没有找到比较方便的手段。由于这种情况出现的可
能性会比较少,所以使用ID有人觉得使用||会增加ORACLE处理的时间,我
觉得不要把ORACLE看得太傻,虽然有时候确实非常傻,有空可以再总结
ORACLE傻不垃圾的地方,但是稍加测试便知:这种串联方式,对于整个SQL
的解析执行,应该是微乎其微的。当然还有一些特殊情况是没有办法处理的,
比如说动态注入列名、表名等。对于这些情况,则比较棘手,没有找到比较方
便的手段。由于这种情况出现的可能性会比较少,所以使用。倒也不至于有什
么太大的影响"当然你如果有代码洁癖的话,可以使用ORACLE的动态执行
SQL的机制Executeimmediate,这样就可以完全避免${}出现的可能性了。
这样会引入比较复杂的模型,这个时候,你就需要取舍了。
针对于以上动态SQL所导致的问题,最激进的方式是全部采用存储过程,用
数据库原生的方式来解决,方便开发调试,当然也会带来问题:对开发人员会
有更高的要求、存储过程的管理等等,我这边项目没有采用过这种方式,这里
不做更多的展开。
简单使用Mybatise
Mybatis的功能相对而言还是比较弱的,缺少了好多必要的辅助库,字符串处
理等等,扩展也比较困难,一般也就可能对返回值进行一些处理。因此最好仅
仅把它作为单纯的SQL配置文件以及简单的ORM框架。不要尝试在Mybatis
中做过多的动态SQL,否则会导致后续的维护非常恶心。
几点技巧总结;
1、查询很多字段时可以提出来再引入到sql语句
提取:
id,type,shopCouId,Path,fromDate^toDate^insDate>insUserld^
updDate,updUserld,delFlg
引入:
select
fromadinfo
whereid=#{id,jdbcType=INTEGER}
2、如果sql语句中需要使用<,符号时,需要使用<>"或者CDATA
内部所有东西都会被解析器忽略
selecttype,shopCouId,Path
fromadinfo
WHEREdelFlg='0'
andfromDate<#{date}andtoDate>=#{date}
3、缓存使用
在增删查改时,可以使用缓存属性控制数据缓存
4、可以判断传进来的参数,再进行操作
andlangCd=#{langCdjdbcType=VARCHAR}
5、可以在sql语句中直接进行加减乘除计算,模糊查询时,需要注意使用方
式
SELECTsum(Cnt)+#{netCnt,jdbcType=INTEGER}
FROMcollectcntb
WHEREb.shopld=#{shopld>jdbcType=INTEGER)
ANDb.delflg='0'
newCnt=newCnt+1,
netCnt=netCnt+1,
sumCnt=sumCnt+1,
ANDo.oTimeLIKEC0NCAT('%',#{sdate),'%')
MyBatis把int类型的0处理成空串〃和mysql处理空串〃为0的问题
当数据库字段类型是整数,如果参数变量为空字符串或者NULL,Mybatis会
自动将参数赋值0,所以如果要判断整数参数的多种状态在传递数值到
Mapper之前就要判断是否为空字符串和NULL并将相应的状态数值赋值给该
参数,否则参数值等于空字符串、NULL和0得到的结果是一样的。
一般情况下,涉及到int类型的操作的时候,在Service中会统一把数字类型
先变成字符串类型,然后再传递到Mapper中操作。
案例六:
使用mybatis进行批量insert的时候会自动封装成一个m叩key是list要
存的数据变成了数组需要注意在xml里面如果使用自己定义的collection要
在传参时定义一个mapkey是自己定义的变量名哦。
在使用resultMap的时候,要把ID写在第一行,否则的话,就会报错。
优缺点
总结下mybatis的优缺点,以便大家对于mybatis的了解能更全面些。但我
所说的优缺点,仅是我个人总结并结合使用体验后得出的结果,并不能代表大
众想法,因此才以“浅谈"作为文章标题。如果大家的见解与我不同,欢迎积极
提出来一块讨论,我也借以弥补自己认识的不足和短见。
优点:
1.易于上手和掌握。
2.sql写在xml里,便于统一管理和优化。
3.解除sql与程序代码的耦合。
4.提供映射标签,支持对象与数据库的orm字段关系映射
5.提供对象关系映射标签,支持对象关系组建维护
6.提供xml标签,支持编写动态sql。
缺点:
1.sql工作量很大,尤其是字段多、关联表多时,更是如此。
2.sql依赖于数据库,导致数据库移植性差.
3.由于xml里标签id必须唯一,导致DAO中方法不
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025云南西双版纳勐海县黎明农场集团有限责任公司招聘工作人员1人笔试历年参考题库附带答案详解
- 2025中铁二院工程集团有限责任公司招聘20人笔试历年参考题库附带答案详解
- 2025中国太平洋财险南昌中支招聘小额人伤专员2人笔试历年参考题库附带答案详解
- 2025东方电气风电(凉山)有限公司面向全社会招聘工作人员笔试历年参考题库附带答案详解
- 2026反式脂肪酸控制政策对食用油配方改进的强制驱动报告
- 锻件校正工岗前规章考核试卷含答案
- 2026南亚通信设备(基站)市场发展现状竞争与投资评估规划分析报告
- 2026南亚电子商务(零售)市场发展现状调研与投资竞争力规划分析报告
- 2026南亚乳制品加工业供需趋势分析投资服务评估规划分析研究报告
- 客户沟通与服务规范手册
- 2026年湖南长沙新奥燃气有限公司社会招聘5人考试参考题库及答案解析
- 2026年安全生产月知识竞赛试题(7套完整版 含答案)
- 2026年全国安全生产月主题培训
- 2026文化和旅游部恭王府博物馆招聘应届毕业生4人考试备考试题及答案解析
- 2025年江苏省中考道德与法治试题及答案解析
- 昆明供电局项目制用工招聘笔试真题2025
- 2026年4月自考07816公共行政学试题及答案含评分参考
- 放射性肠炎治疗管理
- 2026年二级建造师之二建机电工程实务真题含答案详解
- 医师重新执业注册申请审核表
- 内蒙古杉杉年产4万吨锂离子电池负极新能源材料加工项目环境影响报告表
评论
0/150
提交评论