1.Mapper层参数为Map,由Service层负责重载。
Mapper由于机制的问题,不能重载,参数一般设置成Map,但这样会使参数变得模糊,如果想要使代码变得清晰,可以通过service层来实 现重载的目的,对外提供的Service层是重载的,但这些重载的Service方法其实是调同一个Mapper,只不过相应的参数并不一致。
也许有人会想,为什么不在Service层也设置成Map呢?我个人是不推荐这么做的,虽然为了方便,我在之前的项目中也大量采用了这种方式,但 很明显会给日后的维护工作带来麻烦。因为这么做会使你整个MVC都依赖于Map模型,这个模型其实是很不错的,方便搭框架,但存在一个问题:仅仅看方法签 名,你不清楚Map中所拥有的参数个数、类型、每个参数代表的含义。
试想,你只对Service层变更,或者DAO层变更,你需要清楚整个流程中Map传递过来的参数,除非你注释或者文档良好,否则必须把每一层的 代码都了解清楚,你才知道传递了哪些参数。针对于简单MVC,那倒也还好,但如果层次复杂之后,代码会变得异常复杂,而且如果我增加一个参数,需要把每一 个层的注释都添加上。相对于注释,使用方法签名来保证这种代码可控性会来得更可行一些,因为注释有可能是过时的,但方法签名一般不太可能是陈旧的。
2.尽量少用if choose等语句,降低维护的难度。
Mybatis的配置SQL时,尽量少用if choose 等标签,能用SQL实现判断的尽量用SQL来判断(CASE WHEN ,DECODE等),以便后期维护。否则,一旦SQL膨胀,超级恶心,如果需要调试Mybatis中的SQL,需要去除大量的判断语句,非常麻烦。另一方 面,大量的if判断,会使生成的SQL中包含大量的空格,增加网络传输的时间,也不可取。
而且大量的if choose语句,不可避免地,每次生成的SQL会不太一致,会导致ORACLE大量的硬解析,也不可取。
我们来看看这样的SQL
SELECT * FROM T_NEWS_TEXT WHERE 1 = 1 < choose> < if test ="startdate != null and startdate != '' and enddate != null and endate != ''"> AND PUBLISHTIME >= #{startdate} AND PUBLISHTIME <= #{enddate} </ if> <otherwise> AND PUBLISHTIME >= SYSDATE - 7 AND PUBLISHTIME <= SYSDATE </otherwise></ choose >
这样的if判断,其实是完全没有必要的,我们可以很简单的采用DECODE来解决默认值问题:
SELECT * FROM T_NEWS_TEXT WHERE PUBLISHTIME >= DECODE(#{startdate},NULL,SYSDATE-7, #{startdate}) AND PUBLISHTIME <= DECODE(#{enddate},NULL,SYSDATE,#{enddate})
当然有人会想,引入CASE WHEN,DECODE会导致需要ORACLE函数解析,会拖慢SQL执行时间,有兴趣的同学可以回去做一下测试,看看是否会有大的影响。就个人经验而 言,在我的开发过程,没有发现因为函数解析导致SQL变慢的情形。影响SQL执行效率的一般情况下是JOIN、ORDER BY、DISTINCT、PARTITATION BY等这些操作,这些操作一般与表结构设计有很大的关联。相对于这些的效率影响程度,函数解析对于SQL执行速度影响应该是可以忽略不计的。
另外一点,对于一些默认值的赋值,像上面那条SQL,默认成当前日期什么的,其实可以完全提到Service层或Controller层做处理,在Mybatis中应该要少用这些判断。因为,这样的话,很难做缓存处理。如果startdate为空,在SQL上使用动态的SYSDATE,就无法确定缓存startdate日期的key应该是什么了。所以参数最好在传递至Mybatis之前都处理好,这样Mybatis层也能减少部分if choose语句,同时也方便做缓存处理。
当然不使用if choose也并不是绝对的,有时候为了优化SQL,不得不使用if来解决,比如说LIKE语句,当然一般不推荐使用LIKE,但如果存在使用的场景,尽 可能在不需要使用时候去除LIKE,比如查询文章标题,以提高查询效率。 最好的方式是使用lucence等搜索引擎来解决这种全文索引的问题。
总的来说,if与choose判断分支是不可能完全去除的,但是推荐使用SQL原生的方式来解决一些动态问题,而不应该完全依赖Mybatis来完成动态分支的判断,因为判断分支过于复杂,而且难以维护。
3.用XML注释取代SQL注释。
Mybatis中原SQL的注释尽量不要保留,注释会引发一些问题,如果需要使用注释,可以在XML中用来注释,保证在生成的SQL中不会存在SQL注释,从而降低问题出现的可能性。这样做还有一个好处,就是在IDE中可以很清楚的区分注释与 SQL。
现在来谈谈注释引发的问题,我做的一个项目中,分页组件是基于Mybatis的,它会在你写的SQL脚本外面再套一层SELECT COUNT(*) ROWNUM_ FROM (....) 计算总记录数,同时有另一个嵌套
SELECT * FROM TEST WHERE COL1 > 1 -- 这里是注释 <if test="a != null and a != ''">AND COL2 = #{a}</if>
即使传入的参数中存在对应的参数,实际也不会产生效果,因为后面的内容实际上是被完全注释了。这种错误,如果不经过严格的测试,是很难发现的。一般情况下,XML注释完全可以替代SQL注释,因此这种行为应该可以禁止掉。
4.尽可能使用#{},而不是${}.
Mybatis中尽量不要使用${},尽量这样做很方便开发,但是有一个问题,就是大量使用会导致ORACLE的硬解析,拖慢数据库性能,运行越久,数据库性能会越差。对于一般多个字符串IN的处理,可以参考如下的解决方案:http://www.myexception.cn/sql/849573.html,基本可以解决大部分${}.
关于${},另一个误用的地方就是LIKE,我这边还有个案例:比如一些树型菜单,节点会设计成'01','0101',用两位节点来区分层级,这时候, 如果需要查询01节点下所有的节点,最简单的SQL便是:SELECT * FROM TREE WHERE ID LIKE '01%',这种SQL其实无可厚非,因为它也能用到索引,所以不需要特别的处理,直接使用就行了。但如果是文章标题,则需要额外注意了:SELECT * FROM T_NEWS_TEXT WHERE TITLE LIKE '%OSC%',这是怎么也不会用到索引的,上面说了,最好采用全文检索。但如果离不开LIKE,就需要注意使用的方式: ID LIKE #{ID} || '%'而不是ID LIKE '${ID}%',减少硬解析的可能。
有人觉得使用||会增加ORACLE处理的时间,我觉得不要把ORACLE看得太傻,虽然有时候确实非常傻,有空可以再总结ORACLE傻不垃圾的地方,但是稍加测试便知:这种串联方式,对于整个SQL的解析执行,应该是微乎其微的。
当然还有一些特殊情况是没有办法处理的,比如说动态注入列名、表名等。对于这些情况,则比较棘手,没有找到比较方便的手段。由于这种情况出现的可 能性会比较少,所以使用${}倒也不至于有什么太大的影响。当然你如果有代码洁癖的话,可以使用ORACLE的动态执行SQL的机制Execute immediate,这样就可以完全避免${}出现的可能性了。这样会引入比较复杂的模型,这个时候,你就需要取舍了。
针对于以上动态SQL所导致的问题,最激进的方式是全部采用存储过程,用数据库原生的方式来解决,方便开发调试,当然也会带来问题:对开发人员会有更高的要求、存储过程的管理等等,我这边项目没有采用过这种方式,这里不做更多的展开。
5.简单使用Mybatis。
Mybatis的功能相对而言还是比较弱的,缺少了好多必要的辅助库,字符串处理等等,扩展也比较困难,一般也就可能对返回值进行一些处理。因此 最好仅仅把它作为单纯的SQL配置文件,以及简单的ORM框架。不要尝试在Mybatis中做过多的动态SQL,否则会导致后续的维护非常恶心。
参考:http://my.oschina.net/francisxjl/blog/160159
相关推荐
总结,MyBatis通过核心配置文件、映射文件和Mapper接口实现了数据库操作的便捷和灵活。其强大的动态SQL功能、丰富的参数映射和结果集映射,以及缓存机制,都为Java开发人员提供了高效、可控的数据库访问手段。在实际...
根据个人在项目中实际使用Spring boot + Mybatis的经验,系统地总结了Mybatis的基本用法,同时查阅了相关资料,增加了一些面试中应知应会。
王大师技术总结Mybatis思维导图详情教程王大师技术总结Mybatis思维导图详情教程王大师技术总结Mybatis思维导图详情教程王大师技术总结Mybatis思维导图详情教程王大师技术总结Mybatis思维导图详情教程王大师技术总结...
MyBatis是一个优秀的持久层框架,它支持定制化...总结,MyBatis是一个强大的持久层框架,通过灵活的配置和映射机制,简化了数据访问层的开发。理解其核心技术原理并熟练应用,将有助于提升Java项目的开发效率和质量。
总结,MyBatis作为一款轻量级的ORM框架,通过灵活的配置和强大的映射功能,极大地简化了Java开发者对数据库的操作,提高了开发效率。无论是初学者还是资深开发者,理解其工作原理并熟练运用,都将对项目开发带来很大...
《深入浅出MyBatis技术原理与实战》是由杨开振编著的一本关于MyBatis框架的专业书籍,旨在帮助读者全面理解MyBatis的工作机制并掌握其实战应用。MyBatis是一个优秀的Java持久层框架,它简化了数据库操作,通过SQL...
《深入浅出MyBatis技术原理与实战》与《SpringBoot实战第4版》这两本书是IT领域关于数据库持久化框架MyBatis和轻量级Java应用框架SpringBoot的权威指南。在这里,我们将深入探讨这两个关键技术的核心概念、工作原理...
MyBatis 是一款深受开发者喜爱的持久层框架,它简化了Java应用与数据库之间的交互,提供了灵活的SQL映射和对象关系映射功能。在这个"mybatis实验数据包"中,我们可以推测它包含了一些用于教学或者实践MyBatis操作...
技术构成: - 主要编程语言:Java - 文件组成:共29个文件,包括 - Java 源文件:17个 - XML 配置文件:4个 - Git 忽略配置:3个 - Markdown 文档:2个 - 许可证文件:1个 - YML 配置文件:1个 - SQL 备份...
8. 总结: SpringBoot和MyBatis的结合使用,可以实现快速开发,提高开发效率。通过MyBatis Generator,可以自动生成大部分持久层代码,减少了手动编写的工作量,使得开发者能更专注于业务逻辑。在实际项目中,理解...
SSM(spring+spring MVC+mybatis)开发学生信息后台管理系统,实现学生增删改查功能设计一个简单的学生信息管理系统,要求使用SSM框架技术整合实现,用户登录后能够通过Web页面添加、删除、修改和查询学生信息 ...
在Java Web开发中,Servlet和MyBatis是两个非常重要的技术。Servlet3.0作为Java Servlet规范的一个版本,引入了许多新特性,而MyBatis则是一个优秀的持久层框架,简化了数据库操作。本文将深入探讨如何将Servlet3.0...
总结一下,MyBatis-3.3.0和mybatis-spring-1.2.3.jar是Java开发中的两个关键组件,它们帮助开发者实现高效、灵活的数据访问。MyBatis提供了强大的SQL映射功能,而mybatis-spring库则使得在Spring应用中整合MyBatis变...
**Spring MVC 整合 Mybatis 知识点详解** 在现代Java Web开发中,Spring MVC 和 Mybatis 是两个非常流行的框架。Spring MVC 提供了强大...同时,随着技术的发展,还可以结合Spring Boot进一步简化配置,提高开发效率。
5.《尚硅谷_MyBatis_小结(1).avi》是对前面章节的总结,巩固学习成果,同时为后续的深入学习铺平道路。 通过这10个视频的学习,学习者将能够熟练掌握Mybatis的基本操作,理解其核心机制,并具备独立进行Mybatis项目...
### myBatis.net详细手册知识点总结 #### 一、myBatis.net简介 - **定义与定位**:myBatis.net并非纯粹的ORM(Object-Relational Mapping)框架,而是一种半自动化、高度灵活的持久层解决方案。相较于完全自动化的...
总结来说,"SpringBoot整合Mybatis WebSocket"意味着创建一个Web应用,其中SpringBoot负责基础架构和服务器管理,Mybatis处理数据库交互,而WebSocket则用于实现实时的数据传输。这样的组合非常适合构建需要实时交互...
本总结笔记是Spring、Mybatis、SpringMVC的综合学习资源,涵盖了这些框架的基本概念、配置方式、优点与适用场景,以及它们各自组件和功能点的详细解释。适用于初学者入门学习,同时也可以作为面试时的参考资料,帮助...
#### 五、总结 通过以上步骤,我们成功地使用MyBatis开发了一个简单的Java应用程序。从创建数据库到配置MyBatis,再到编写测试类,每个环节都进行了详细的介绍。MyBatis通过简化数据库操作,使开发者能够更加专注于...