最近一个项目用到mybatis,花了一点时间看了官方文档,后面就搭建起了框架,着手进行开发,mybatis上手很容易,但是有一些小的细节的注意(下文说明),否则错误很难查找,对于用惯了Hibernate的开发人员来说,使用mybatis可能可能需要加强SQL。大概说一下mybatis优缺点,欢迎补充。
mybatis优点:
1. 易于上手和掌握。
2. sql写在xml里,便于统一管理和优化。
3. 解除sql与程序代码的耦合。
4. 提供映射标签,支持对象与数据库的orm字段关系映射
5. 提供对象关系映射标签,支持对象关系组建维护
6. 提供xml标签,支持编写动态sql。
mybatis缺点:
1. sql工作量很大,尤其是字段多、关联表多时,更是如此。
2. sql依赖于数据库,导致数据库移植性差。
3. 由于xml里标签id必须唯一,导致DAO中方法不支持方法重载。
4. 字段映射标签和对象关系映射标签仅仅是对映射关系的描述,具体实现仍然依赖于sql。(比如配置了一对多Collection标签,如果sql里没有join子表或查询子表的话,查询后返回的对象是不具备对象关系的,即Collection的对象为null)
5. DAO层过于简单,对象组装的工作量较大。
6. 不支持级联更新、级联删除。
7. 编写动态sql时,不方便调试,尤其逻辑复杂时。
8. 提供的写动态sql的xml标签功能简单(连struts都比不上),编写动态sql仍然受限,且可读性低。
9. 使用不当,容易导致N+1的sql性能问题。
10. 使用不当,关联查询时容易产生分页bug。
11. 若不查询主键字段,容易造成查询出的对象有“覆盖”现象。
12. 参数的数据类型支持不完善。(如参数为Date类型时,容易报没有get、set方法,需在参数上加@param)
13. 多参数时,使用不方便,功能不够强大。(目前支持的方法有map、对象、注解@param以及默认采用012索引位的方式)
查询结果说明:
mybatis可以通过配置返回Java对象,例如查询一个用户对象,下面为mapper配置,select查询可以指定返回resultType或者resultMap。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.sclead.dao.mapper.UserMapper"> <resultMap type="com.sclead.dao.entity.User" id="userMap"> <id property="userId" column="user_id" /> <result property="depId" column="dep_id" /> <result property="userName" column="user_name" /> <result property="realName" column="real_name" /> <result property="password" column="user_pw" /> <result property="createTime" column="user_create_time" /> <result property="state" column="user_state" /> <result property="note" column="user_note" /> <!-- 关联查询单位信息 --> <association property="department" resultMap="com.sclead.dao.mapper.DepartmentMapper.depMap"/> <!-- 关联查询角色信息 --> <collection property="roles" resultMap="com.sclead.dao.mapper.RoleMapper.roleMap"/> </resultMap> <!-- 公用sql --> <sql id="baseSql"> select u.*,d.*,r.* from ly_user u left join ly_department d on u.dep_id = d.dep_id left join ly_user_role ur on ur.user_id = u.user_id left join ly_role r on r.role_id = ur.role_id </sql> <!-- 查询一个用户 --> <select id="getUserById" parameterType="int" resultMap="userMap"> <include refid="baseSql"/> where user_id=#{userId} </select> <!-- 查询所有记录 --> <select id="getAllUser" resultMap="userMap"> <include refid="baseSql"/> </select> </mapper>
如果实体类属性和数据库中字段名一样,则可以直接指定resultType,值为定义的实体类,mybatis会默认创建resultMap指定对应关系,resultType=“User”,User需在配置中定义,如下段代码,查询成功后返回User对象。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <typeAliases> <typeAlias type="com.sclead.dao.entity.User" alias="User"/> <!-- <mappers> <mapper resource="com/sclead/dao/mapper/xml/user-mapper.xml"/> </mappers> --> </configuration>
如果实体类属性和数据库中字段名称不相同,必须在配置中声明resultMap映射,指定字段和属性对应关系,查询时指定resultMap,查询成功后会返回User对象,或者是User集合。
三张表关联查询,这里定义三张表,A、B、C,B关联A,C关联B,在查询A的时候同时查询B和C,在A实体类中定义B对象集合,在B实体类中定义C对象集合。
A表{a_id,......},B表{b_id,b_a_id,......},C表{c_id,c_b_id,......}
public class A { private int aId; private List<B> bs; public int getaId() { return aId; } public void setaId(int aId) { this.aId = aId; } public List<B> getBs() { return bs; } public void setBs(List<B> bs) { this.bs = bs; } } public class B { private int bId; private int baId; private List<C> cs; public int getBId() { return bId; } public void setBId(int bid) { this.bId = bid; } public int getBaId() { return baId; } public void setBaId(int baId) { this.baId = baId; } public List<C> getCs() { return cs; } public void setCs(List<C> cs) { this.cs = cs; } } public class C { private int cId; private int cbId; public int getcId() { return cId; } public void setcId(int cId) { this.cId = cId; } public int getCbId() { return cbId; } public void setCbId(int cbId) { this.cbId = cbId; } }
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.abc.AMapper"> <resultMap type="com.abc.A" id="aMap"> <id property="a_Id" column="a_id" /> <!-- 其它字段略 --> <!-- 关联查询B数据 --> <collection property="bs" resultMap="com.sbc.BMapper.bMap"/> </resultMap> <!-- 公用sql --> <sql id="baseSql"> select * from ly_a a left join ly_b b on a.a_id = b.b_a_id left join ly_c c on b.b_id = c.c_b_id </sql> <!-- 查询所有记录 --> <select id="getAllA" resultMap="aMap"> <include refid="baseSql"/> </select> <!-- 查询一个 --> <select id="getAById" parameterType="int" resultMap="aMap"> <include refid="baseSql"/> where a.a_id=#{a_id} </select> </mapper>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.abc.BMapper"> <resultMap type="com.abc.B" id="aMap"> <id property="bId" column="b_id" /> <id property="baId" column="b_a_id" /> <!-- 其它字段略 --> <!-- 关联查询C数据 --> <collection property="cs" resultMap="com.sbc.CMapper.cMap"/> </resultMap> </mapper>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.abc.CMapper"> <resultMap type="com.abc.C" id="cMap"> <id property="cId" column="c_id" /> <id property="cbId" column="c_b_id" /> <!-- 其它字段略 --> </resultMap> </mapper>
在调用getAById或者getAllA,返回A对象或者A集合,A对象中已经封装了关联的B对象,B对象中已经封装了关联的C对象。
mybatis的关联查询还有其他集中配置方式,这里只介绍多级关联查询,
相关推荐
自关联查询一对多的例子,也就是充当一方,以新闻栏目为例子
主要介绍了MyBatis之自查询使用递归实现 N级联动效果,本文给大家分享两种实现方式,需要的的朋友参考下吧
了解数据表之间以及对象之间的三种关联关系 2.熟悉关联关系中的嵌套查询和 嵌套结果 3.掌握一对一,一对多,和多对多关联映射作用
Mybatis实现关联查询一对一和一对多实现,具体效果看博文 http://blog.csdn.net/evankaka/article/details/45674101
mybatis 关联查询 一对一 一对多 ResultMap association collection 完整代码
该资源主要通过举例讲述mybatis中的一对一关联查询,并用两种不同的方法进行操作。
* * * * * MyBatis的关联映射 为什么学习MyBatis关联关系? 9.1 关联关系概述 实际的开发中,对数据库的操作常常会涉及到多张表,这在面向对象中就涉及到了对象与对象之间的关联关系。针对多表之间的操作,MyBatis...
实现Mybatis框架中一对多关联映射的查询操作。 User用户表 - Order_form订单表属于 1-N 的关系。 一个用户对象包含一批订单信息
支持mysl底过程查询,可以查询帖子评论的多级回复以及每个回复关联的用户信息.可以作为类似于帖子回复这种嵌套递归查询业务的模板,可移植性高.如果疑问之处可多多交流
完成实例,下载就可以直接运行springmvc+mybatis自己花了几天时间辛苦整合的封装,不过最近没有时间算一个半成品,想加入自定义注解来完成映射关系,不过没时间了,就到这里吧!
spring多数据源的处理_mybatis实现跨库查询
Mybatis拦截器记录数据更新历史记录到MongoDB的源码,另外需要配置拦截器到mybatis配置文件中。
NULL 博文链接:https://zhaoshijie.iteye.com/blog/2003209
mybatis 关联下旬 一对多 一对一 多对多
eclipse中Mybatis与mapper.xml映射文件的关联,直接点击类上面的方法,就可以跳转相应的方法的位置
Mybatis关联映射 Mybatis关联映射 Mybatis关联映射 Mybatis关联映射 Mybatis关联映射
MyBatis关联映射代码
编写程序,对MyBatis的关联映射进行应用,要求对一对一、一对多、多对多三种关系,分别应用嵌套查询和嵌套结果两种方式,来实现操作。
NULL 博文链接:https://qihaibo1989.iteye.com/blog/2354597
二、为什么学习MyBatis关联关系? 实际的开发中,对数据库的操作常常会涉及到多张表,这在面向对象中就涉及到了对象与对象之间的关联关系。针对多表之间的操作,MyBatis提供了关联映射,通过关联映射就可以很好的...