设为首页 收藏本站
查看: 933|回复: 0

[经验分享] mybatis多级关联查询数据封装

[复制链接]

尚未签到

发表于 2016-11-26 06:29:22 | 显示全部楼层 |阅读模式
  最近一个项目用到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的关联查询还有其他集中配置方式,这里只介绍多级关联查询,

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-305561-1-1.html 上篇帖子: Spring整合Mybatis错误 下篇帖子: 使用MyBatis Generator自动创建代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表