Mybatis的一对多(collection)和一对一(association)查询

1、mybatis支持映射复杂的查询结果集

2、表之间的关系

3、实体及其对应关系:

 

@Data
@EqualsAndHashCode(callSuper = false)
public class TestOne implements Serializable {
    private static final long serialVersionUID = 1L;
    private Integer id;    //
    private String nickname;    //
    private List<TestTwo> testTwos;
}

 

 

@Data
@EqualsAndHashCode(callSuper = false)
public class TestTwo implements Serializable {
    private static final long serialVersionUID = 1L;
    private Integer id;    //
    private String nickname;    //
    private Integer oneId;    //
    private TestOne testOne;
}

 

4、mybatis---------Association:  一对一查询的方式

 

<resultMap id="TestTwoAll" type="TestTwo">
        <id property="id" column="twoid"/>
        <result property="nickname" column="twonickname"/>
        <result property="oneId" column="one_id"/>
        <association property="testOne" column="one_id" javaType="TestOne">
            <id property="id" column="oneid"/>
            <result property="nickname" column="onenickname"/>
        </association>
    </resultMap>

    <select id="getTotalById" resultMap="TestTwoAll" parameterType="long">
        SELECT
        one.id as oneid,
        one.nickname as onenickname,
        two.id as twoid,
        two.nickname as twonickname,
        two.one_id
        FROM test_one one,test_two two
        where one.id=two.one_id and two.id=#{value}
    </select>

 

5、mybatis---------Collection:  一对多查询的方式

 

<resultMap id="TestOneAll" type="TestOne">
        <result property="id" column="oneid"/>
        <result property="nickname" column="onenickname"/>
        <collection property="testTwos" column="one_id" ofType="TestTwo" javaType="ArrayList">
            <result property="id" column="twoid"/>
            <result property="nickname" column="twonickname"/>
            <result property="oneId" column="one_id"/>
        </collection>
    </resultMap>

    <select id="getTotalById" resultMap="TestOneAll" parameterType="long">
        SELECT
        one.id as oneid,
        one.nickname as onenickname,
        two.id as twoid,
        two.nickname as twonickname,
        two.one_id
        FROM test_one one,test_two two
        where one.id=two.one_id and one.id=#{VALUE }
        order by twoid desc
    </select>

 

附录:

(1)建表语句:

 

CREATE TABLE `test_one` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nickname` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;



CREATE TABLE `test_two` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nickname` varchar(255) NOT NULL,
  `one_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `test_two_ibfk_1` (`one_id`),
  CONSTRAINT `test_two_ibfk_1` FOREIGN KEY (`one_id`) REFERENCES `test_one` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

 

(2)说明:(引自 http://blog.csdn.net/wxwzy738/article/details/24742495)

  1》

id, result元素

 

<id property="id" column="post_id"/>

<result property="subject" column="post_subject"/>

 

这是最基本的结果集映射。id 和result 将列映射到属性或简单的数据类型字段(String, int, double, Date等)。

这两者唯一不同的是,在比较对象实例时id 作为结果集的标识属性。这有助于提高总体性能,特别是应用缓存和嵌套结果映射的时候。

 

  2》

Association元素

 

<association property="author" column="blog_author_id" javaType=" Author">

<id property="id" column="author_id"/>

<result property="username" column="author_username"/>

</association>

Association元素处理“has-one”(一对一)这种类型关系。联合映射与其它的结果集映射工作方式差不多,指定property、column、javaType(通常MyBatis会自动识别)、jdbcType(如果需要)、typeHandler。

不同的地方是您需要告诉MyBatis 如何加载一个联合查询。MyBatis使用两种方式来加载:

·Nested Select:通过执行另一个返回预期复杂类型的映射SQL语句(即引用外部定义好的SQL语句块)。

·Nested Results:通过嵌套结果映射(nested result mappings)来处理联接结果集(joined results)的重复子集。

首先,让我们检查一下元素属性。正如您看到的,它不同于普通只有select和resultMap属性的结果映射。

Attribute

Description

property

映射数据库列的字段或属性。如果JavaBean 的属性与给定的名称匹配,就会使用匹配的名字。否则,MyBatis 将搜索给定名称的字段。两种情况下您都可以使用逗点的属性形式。比如,您可以映射到”username”,也可以映射到更复杂点的”address.street.number”。

column

数据库的列名或者列标签别名。与传递给resultSet.getString(columnName)的参数名称相同。

注意: 在处理组合键时,您可以使用column= “{prop1=col1,prop2=col2}”这样的语法,设置多个列名传入到嵌套查询语句。这就会把prop1和prop2设置到目标嵌套选择语句的参数对象中。

javaType

完整java类名或别名(参考上面的内置别名列表)。如果映射到一个JavaBean,那MyBatis 通常会自行检测到。然而,如果映射到一个HashMap,那您应该明确指定javaType 来确保所需行为。

jdbcType

支持的JDBC类型列表中列出的JDBC类型。这个属性只在insert,update 或delete 的时候针对允许空的列有用。JDBC 需要这项,但MyBatis 不需要。如果您直接编写JDBC代码,在允许为空值的情况下需要指定这个类型。

typeHandler

我们已经在文档中讨论过默认类型处理器。使用这个属性可以重写默认类型处理器。它的值可以是一个TypeHandler实现的完整类名,也可以是一个类型别名。

联合嵌套选择(Nested Select for Association)

select

通过这个属性,通过ID引用另一个加载复杂类型的映射语句。从指定列属性中返回的值,将作为参数设置给目标select 语句。表格下方将有一个例子。注意:在处理组合键时,您可以使用column=”{prop1=col1,prop2=col2}”这样的语法,设置多个列名传入到嵌套语句。这就会把prop1和prop2设置到目标嵌套语句的参数对象中。

  3》   

Collection元素 

<collection property="posts" ofType="domain.blog.Post">
<id property="id" column="post_id"/>
<result property="subject" column="post_subject"/>
<result property="body" column="post_body"/>
</collection>

collection元素的作用差不多和association元素的作用一样。事实上,它们非常相似,以至于再对相似点进行描述会显得冗余,因此我们只关注它们的不同点。

会像下面这样定义相应属性: 

private List<Post> posts;

映射一个嵌套结果集到一个列表,我们使用collection元素。就像association 元素那样,我们使用嵌套查询,或者从连接中嵌套结果集。 

<resultMap id=”blogResult” type=”Blog”>
<collection property="posts" javaType=”ArrayList” column="blog_id"
ofType="Post" select=”selectPostsForBlog”/>
</resultMap>

<select id=”selectBlog” parameterType=”int” resultMap=”blogResult”>
SELECT * FROM BLOG WHERE ID = #{id}
</select>

<select id=”selectPostsForBlog” parameterType=”int” resultType="Author">
SELECT * FROM POST WHERE BLOG_ID = #{id}
</select>

 

* 一看上去这有许多东西需要注意,但大部分看起与我们在association元素中学过的相似。首先,您会注意到我们使用了collection元素,然后会注意到一个新的属性“ofType”。这个元素是用来区别JavaBean属性(或者字段)类型和集合所包括的类型。因此您会读到下面这段代码。

 

<collection property="posts" javaType=”ArrayList” column="blog_id"

ofType="Post" select=”selectPostsForBlog”/>
 

理解为:“一个名为posts,类型为Post的ArrayList集合(A collection of posts in an ArrayList of type Post)” 。

javaType属性不是必须的,通常MyBatis 会自动识别,所以您通常可以简略地写成:

<collection property="posts" column="blog_id" ofType="Post"

select=”selectPostsForBlog”/>

 

實戰例子:

 <resultMap id="BaseResultMap" type="com.cn.module.order.entity.OmsOrderInvoice" >
    <id column="id" property="id" jdbcType="VARCHAR" />
    <result column="order_id" property="orderId" jdbcType="VARCHAR" />
    <result column="duty_paragraph" property="dutyParagraph" jdbcType="VARCHAR" />
    <result column="invoice_type" property="invoiceType" jdbcType="VARCHAR" />
    <result column="invoice_code" property="invoiceCode" jdbcType="VARCHAR" />
    <result column="invoice_title" property="invoiceTitle" jdbcType="VARCHAR" />
    <result column="address" property="address" jdbcType="VARCHAR" />
    <result column="tell" property="tell" jdbcType="VARCHAR" />
    <result column="bank_deposit" property="bankDeposit" jdbcType="VARCHAR" />
    <result column="bank_account" property="bankAccount" jdbcType="VARCHAR" />
    <result column="invoice_distribu_name" property="invoiceDistribuName" jdbcType="VARCHAR" />
    <result column="invoice_logic_no" property="invoiceLogicNo" jdbcType="VARCHAR" />
    <result column="invoice_people" property="invoicePeople" jdbcType="VARCHAR" />
    <result column="invoice_phone" property="invoicePhone" jdbcType="VARCHAR" />
    <result column="invoice_address" property="invoiceAddress" jdbcType="VARCHAR" />
    <result column="invoice_no" property="invoiceNo" jdbcType="VARCHAR" />
    <result column="invoice_status" property="invoiceStatus" jdbcType="DECIMAL" />
    <result column="remark" property="remark" jdbcType="VARCHAR" />
    <result column="delete_flag" property="deleteFlag" jdbcType="DECIMAL" />
    <result column="create_user" property="createUser" jdbcType="VARCHAR" />
    <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
    <result column="update_user" property="updateUser" jdbcType="VARCHAR" />
    <result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />
<-- data為OmsOrderComm實體中的一個字段 -->
    <collection property="data" ofType="com.cn.module.order.entity.OmsOrderComm"
                  select="findByComm" column="id">
    </collection>
  </resultMap>

 <resultMap id="BaseCommMap" type="com.cn.module.order.entity.OmsOrderComm" >
    <id column="id" property="id" jdbcType="VARCHAR" />
    <result column="order_row_number" property="orderRowNumber" jdbcType="VARCHAR" />
    <result column="comm_id" property="commId" jdbcType="VARCHAR" />
    <result column="comm_name" property="commName" jdbcType="VARCHAR" />
    <result column="comm_code" property="commCode" jdbcType="VARCHAR" />
    <result column="item_number" property="itemNumber" jdbcType="VARCHAR" />
    <result column="order_quantity" property="orderQuantity" jdbcType="VARCHAR" />
    <result column="invoice_count" property="invoiceCount" jdbcType="VARCHAR" />
    <result column="attr_name" property="attrName" jdbcType="VARCHAR" />
    <result column="invoice_money" property="invoiceMoney" jdbcType="VARCHAR" />
   </resultMap>


 1先執行
 <!--通过订单id查找发票实体信息列表-->                                                
  <select id="findByInvoice" parameterType="java.lang.String" resultMap="BaseResultMap">
  	select 
    	id, invoice_no,order_id, duty_paragraph, invoice_code, invoice_type ,invoice_title , address, 
    	tell , bank_deposit , bank_account,invoice_status , invoice_logic_no , invoice_distribu_name, 
    	remark,invoice_people , invoice_phone , invoice_address
    from oms_order_invoice
    where 
   		delete_flag = 0
   		and
    	order_id = #{orderId,jdbcType=VARCHAR}
  </select>

2在執行id="BaseResultMap"中的 select="findByComm"
  <!--查询商品列表-->
  <select id="findByComm" parameterType="java.lang.String" resultMap="BaseCommMap">
  	select 
    	a.id,a.order_row_number,b.comm_id,b.comm_name,b.comm_code,b.item_number,b.order_quantity,c.invoice_count,c.invoice_money,b.attr_name as attrName
    from oms_order_info a
	    left join oms_order_comm b on a.id = b.order_id
	    left join oms_order_invoice_comm c on b.id = c.order_comm_id
    where 
   		a.delete_flag = 0 and b.delete_flag = 0
    	and 
    	c.invoice_id = #{id,jdbcType=VARCHAR}
  </select>

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值