`
chenyunhong
  • 浏览: 139783 次
  • 性别: Icon_minigender_1
  • 来自: 真的不知道
社区版块
存档分类
最新评论

mybatis多级关联查询数据封装

阅读更多

       最近一个项目用到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自关联查询

    本篇文章将重点讲解 MyBatis 中的自关联查询,以“新闻栏目”为例,探讨如何实现一对多的关系。 在新闻系统中,栏目(Category)与新闻(News)通常存在一对多的关系:一个栏目可以包含多个新闻,而一个新闻则属于...

    MyBatis之自查询使用递归实现 N级联动效果(两种实现方式)

    "MyBatis之自查询使用递归实现 N级联动效果" MyBatis是一个功能强大且灵活的持久层框架,它支持自查询和递归查询,下面我们将探讨如何使用MyBatis实现 N级联动效果。 递归查询 递归查询是指在一个查询中调用自身...

    基于mybatis的collection标签实现帖子评论多级回复以及关联用户信息查询

    在本场景中,我们探讨的是如何利用MyBatis的`collection`标签来实现帖子评论的多级回复以及与用户信息的关联查询。MyBatis是一个强大的Java持久层框架,它简化了数据库操作,使得开发者能更专注于SQL语句本身,而...

    mybatis 关联查询完整代码

    本篇文章将详细探讨MyBatis在关联查询中的一对一和一对多关系映射,以及如何通过ResultMap配置来实现这些复杂的查询。 在数据库设计中,一对一和一对多的关系非常常见。一对一关系通常出现在两个表之间,其中一个表...

    MyBatis的关联映射实践报告

    了解数据表之间以及对象之间的三种关联关系 2.熟悉关联关系中的嵌套查询和 嵌套结果 3.掌握一对一,一对多,和多对多关联映射作用

    Mybatis实现关联查询一对一和一对多实现

    Mybatis实现关联查询一对一和一对多实现,具体效果看博文 http://blog.csdn.net/evankaka/article/details/45674101

    实现Mybatis框架中一对多关联映射的查询操作。

    通过以上步骤,Mybatis能够根据配置的映射规则,自动将查询结果中的多条订单数据转化为User对象中的Order列表,从而实现了1-N关联映射的查询操作。在实际项目中,这样的设计使得数据的获取和处理更为便捷,降低了...

    mybatis+springmvc自己整合封装的实例

    本实例"mybatis+springmvc自己整合封装的实例"是作者花费时间精心整合的一个半成品,尽管未能实现全部计划的功能,如自定义注解映射,但仍然具有很高的学习价值。以下将详细介绍这个整合过程中的关键知识点。 1. ...

    mybatis关联查询案例

    该资源主要通过举例讲述mybatis中的一对一关联查询,并用两种不同的方法进行操作。

    spring多数据源的处理_mybatis实现跨库查询

    Spring 2.x 的版本中采用 Proxy 模式,就是我们在方案中实现一个虚拟的数据源,并且用它来封装数据源选择逻辑,这样就可以有效地将数据源选择逻辑从 Client 中分离出来。 为了实现多数据源处理,我们需要定义一个...

    Mybatis 一对多关联查询(两种方法)

    在Mybatis框架中,一对多关联查询是一种常见的数据操作,用于获取一个实体对象与其关联的多个子对象的数据。...理解并熟练掌握这两种方法,将有助于我们在实际开发中更高效地处理复杂的数据查询需求。

    Mybatis通用DAO设计封装(mybatis)

    同时,定义ResultMap来映射查询结果到实体类,可以处理复杂的数据类型和关联关系。 4. **Mapper代理**: Mybatis使用`SqlSession`和`MapperFactoryBean`来创建Mapper对象的代理,调用DAO方法时,实际上执行的是...

    Spring整合MyBatis关联查询示例

    本示例将探讨如何在Spring环境中实现MyBatis的关联查询,包括一对多、一对一和多对多关系的处理。理解这些关联关系对于构建复杂的业务逻辑至关重要。 首先,我们需要配置Spring与MyBatis的整合。这通常涉及以下几个...

    基于java的企业级应用开发:MyBatis的关联映射.ppt

    关联映射是MyBatis中处理对象与对象间关联关系的关键特性,尤其在企业级应用开发中,面对复杂的数据库表关联,关联映射能有效地简化数据访问逻辑。 在关系型数据库中,常见的关联关系有三种:一对一(One-to-One)...

    Spring boot2基于Mybatis实现多表关联查询

    Spring Boot 2 基于 MyBatis 实现多表关联查询 Spring Boot 2 是目前非常流行的 Java 框架,它提供了许多强大的功能,例如自动配置、 starters 机制等。MyBatis 是一个流行的持久层框架,提供了强大的数据库交互...

    MyBatis的关联映射

    **MyBatis关联映射详解** 在Java开发中,MyBatis作为一个优秀的持久层框架,提供了灵活的数据映射功能,使得数据库操作变得简单而高效。其中,关联映射是MyBatis中的一个重要特性,用于处理数据库中复杂的关系,如...

    MyBatis关联映射代码

    2. 嵌套结果:当主表和子表的数据在同一查询结果集中时,MyBatis会根据ResultMap来解析并关联这些数据。这种方式适用于主表和子表数据在同一个SELECT语句中返回的情况。 以下是一个简单的例子,展示了如何在MyBatis...

    mybatis_xml关联插件

    关联Java类与Mapper XML文件的关键在于注解和XML映射文件的正确设置。在Mapper接口的Java类中,你会看到类似这样的注解`@Mapper`,这个注解告诉Mybatis这是一个Mapper接口。每个方法都对应XML映射文件中的一个SQL...

    mybatis 的高级关联查询源码

    在关联查询中,MyBatis 允许我们在 `collection` 标签内定义 `&lt;select&gt;` 子标签,用于执行 SQL 查询获取子集合数据。这里可以编写一个带有参数的 SQL 语句,通过主表的 ID 或其他关联字段来查询子表的数据。 3. **...

    Mybatis拦截器记录数据更新历史记录到MongoDB

    本文将深入探讨如何使用Mybatis拦截器来记录数据更新历史记录,并将其存储到MongoDB中。 首先,我们来理解Mybatis拦截器的原理。Mybatis的拦截器是基于Java的动态代理机制实现的,它允许我们在特定的执行点(如SQL...

Global site tag (gtag.js) - Google Analytics