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>