MyBatis关系映射--一对一关系映射
本文详细介绍了MyBatis框架中实现一对一关系映射的两种方式:查询映射和结果映射。通过实例展示了每种映射的XML配置及Java代码实现,对比了两者的优缺点,帮助开发者根据需求选择合适的映射策略。
文章信息
- 原文链接:https://jiayq.blog.csdn.net/article/details/88202406
- 发布时间:2019-03-05 20:35:57
- 阅读量:1
- 分类:java同时被 3 个专栏收录, 订阅专栏, mybatis, MyBatis
- 标签:#MyBatis关系映射–一对一映射, #查询映射和结果映射, #MyBatis映射方式对比, #MyBatis多表一对一映射, #MyBatis映射实例
摘要
文章浏览阅读1.1k次。本文详细介绍了MyBatis框架中实现一对一关系映射的两种方式:查询映射和结果映射。通过实例展示了每种映射的XML配置及Java代码实现,对比了两者的优缺点,帮助开发者根据需求选择合适的映射策略。
MyBatis关系映射–一对一关系
- 1.关系映射
- 2.关系映射的方式
- 2.1查询映射
- 2.2结果映射
- 2.3不同方式的分析
- 2.1查询映射
- 3.例子
- 3.1创建一个MyBatis工程
- 3.2导入jar包
- 3.3实现Java类
- 3.4properties
- 3.5resource
- 3.6mapper
- 3.1创建一个MyBatis工程
- 4.运行结果
- 5.总结
1.关系映射
实际开发中,常常需要关联表进行查询,比如公民和身份证之间的联合查询,在公司,一个人有一个人的工位,一个人有一个人工作的计算机,一个工位可能有工作的计算机,等等。
一对一关系是最简单的关系,也是最基本的关系。
2.关系映射的方式
1.通过查询映射
2.通过结果映射
2.1查询映射
查询映射就是查第一个表时,取出第一个表时,查询第二个表,然后把第一个表和第二个表的结果共同返回去。查询映射就相当于查询2次,使用了2条select语句
查询映射的写法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- 嵌套查询 -->
<resultMap type="people" id="peopleWithCard">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
<association property="card" column="card_id" javaType="card"
select="cardMapper.selectById"></association>
</resultMap>
<select id="selectOneByOne" parameterType="Long" resultMap="peopleWithCard">
select <include refid="baseMapper.str_select_people"></include>
from <include refid="baseMapper.str_table_people"></include>
<where>
<if test="_parameter != null and _parameter != ''">
and id=#{_parameter}
</if>
</where>
</select>
其中cardMapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?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="cardMapper">
<select id="selectById" parameterType="Long" resultType="card">
select <include refid="baseMapper.str_select_card"></include>
from <include refid="baseMapper.str_table_card"></include>
<where>
<if test="_parameter != null and _parameter != ''">
and id=#{_parameter}
</if>
</where>
</select>
<insert id="insertCard" parameterType="card">
insert into <include refid="baseMapper.str_table_card"></include>(<include refid="baseMapper.str_select_card"></include>) values(#{id},#{code})
</insert>
</mapper>
2.2结果映射
结果映射就是通过一条select语句查询出所有的结果,然后把返回的数据封装为实体。
结果映射的写法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!-- 嵌套结果 -->
<sql id="str_select_people_card">
p.id,p.name,p.age,p.sex,p.card_id,c.code
</sql>
<sql id="str_table_people_card">
people p,card c
</sql>
<resultMap type="people" id="resultPeopleWithCard">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
<association property="card" javaType="card">
<id property="id" column="card_id"/>
<result property="code" column="code"/>
</association>
</resultMap>
<select id="selectResult" parameterType="Long" resultMap="resultPeopleWithCard">
select <include refid="str_select_people_card"></include>
from <include refid="str_table_people_card"></include>
<where>
c.id = p.card_id
<if test="_parameter != null and _parameter != ''">
and p.id=#{_parameter}
</if>
</where>
</select>
2.3不同方式的分析
首先关系的映射在不同的方式中,使用不同的方法来实现映射。
在查询映射中,映射关系是通过一条新的通过id查询第二个表的SQL来完成的,如果没有通过id查询第二个表的映射,或者这个映射出现了问题,那么整体的查询映射也不会实现。也就是说查询映射依赖于外部已实现的通过id查询(或者其他主键查询,结果必须唯一)
在结果映射中,映射关系是通过SQL语句的where条件来实现的,mapper的映射只是实现结果的封装。结果映射不依赖与任何外部资源,而且结果映射只需要一条select即可实现。
优缺点:
查询映射,需要2条SQL实现;
结果映射,不需要依赖于外部资源;
查询映射,复用性较好,SQL难度较低;
结果映射,复用性差,SQL难度高。
特别是多个表进行关系的映射时,如果使用查询映射,其查询逻辑较为简单,易于修改,易于开发。
但是因为查询映射需要执行多条语句,肯定没有一次性返回结果的效率高,而且因为查询映射需要依赖多个外部资源,集成难度大,结果映射只需要专注于写SQL即可。
3.例子
3.1创建一个MyBatis工程
3.2导入jar包
3.3实现Java类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package com.client;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import com.util.MyBatisSessionUtils;
public class Main {
@Test
public void queryCard(){
SqlSession session = MyBatisSessionUtils.getSession();
System.out.println(session.selectOne("cardMapper.selectById",1));
session.close();
}
@Test
public void queryPeople(){
SqlSession session = MyBatisSessionUtils.getSession();
System.out.println(session.selectOne("peopleMapper.selectById", 103L));
session.close();
}
@Test
public void queryPeopleWithCard(){
SqlSession session = MyBatisSessionUtils.getSession();
System.out.println(session.selectOne("oneByOneMapper.selectOneByOne",103L));
session.close();
}
@Test
public void queryPeopleWithCardResult(){
SqlSession session = MyBatisSessionUtils.getSession();
System.out.println(session.selectOne("oneByOneMapper.selectResult",103L));
session.close();
}
}
package com.domain;
import java.io.Serializable;
public class Card implements Serializable{
/**
*
*/
private static final long serialVersionUID = -5398573250153908121L;
private Long id;
private String code;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Override
public String toString() {
return "[id="+this.id+",code="+this.code+"]";
}
}
package com.domain;
import java.io.Serializable;
public class People implements Serializable{
/**
*
*/
private static final long serialVersionUID = -3270893239281340723L;
private Long id;
private String name;
private Integer age;
private Integer sex;
private Card card;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public Card getCard() {
return card;
}
public void setCard(Card card) {
this.card = card;
}
@Override
public String toString() {
return "people [id=" + this.id + ",name=" + this.name + ",age="
+ this.age + ",sex=" + this.sex + ",code=" + this.card + "]";
}
}
package com.util;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisSessionUtils {
private static SqlSessionFactory sessionFactory = null;
private static final String PATH="com/resource/mybatis.xml";
static{
try{
Reader reader = Resources.getResourceAsReader(PATH);
sessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (Exception e){
e.printStackTrace();
}
}
public static SqlSession getSession(){
return sessionFactory.openSession();
}
}
3.4properties
log4j.properties
1
2
3
4
5
6
7
8
# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.com=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
ojdbc.properties
1
2
3
4
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@127.0.0.1:1521:oracle
username=study
password=study
3.5resource
mybatis.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?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>
<!-- 配置外在化 -->
<properties resource="com/property/ojdbc.properties"></properties>
<settings>
<!-- 延迟加载全局 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 关联对象属性的延迟加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
<!-- 改变运行时行为 -->
<typeAliases>
<!-- 配置别名 -->
<typeAlias type="com.domain.People" alias="people"/>
<typeAlias type="com.domain.Card" alias="card"/>
</typeAliases>
<!-- 环境配置 -->
<environments default="oracle">
<environment id="oracle">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/mapper/baseMapper.xml"/>
<mapper resource="com/mapper/cardMapper.xml"/>
<mapper resource="com/mapper/peopleMapper.xml"/>
<mapper resource="com/mapper/oneByOneMapper.xml"/>
</mappers>
</configuration>
3.6mapper
baseMapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?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="baseMapper">
<sql id="str_select_people">
p.id,p.name,p.age,p.sex,p.card_id
</sql>
<sql id="str_table_people">
people p
</sql>
<sql id="str_select_card">
c.id, c.code
</sql>
<sql id="str_table_card">
card c
</sql>
</mapper>
cardMapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?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="cardMapper">
<select id="selectById" parameterType="Long" resultType="card">
select <include refid="baseMapper.str_select_card"></include>
from <include refid="baseMapper.str_table_card"></include>
<where>
<if test="_parameter != null and _parameter != ''">
and id=#{_parameter}
</if>
</where>
</select>
<insert id="insertCard" parameterType="card">
insert into <include refid="baseMapper.str_table_card"></include>(<include refid="baseMapper.str_select_card"></include>) values(#{id},#{code})
</insert>
</mapper>
peopleMapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<?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="peopleMapper">
<select id="selectById" parameterType="Long" resultType="people">
select <include refid="baseMapper.str_select_people"></include>
from <include refid="baseMapper.str_table_people"></include>
<where>
<if test="_parameter != null and _parameter != ''">
and id=#{_parameter}
</if>
</where>
</select>
<update id="updatePeopleForCard" parameterType="people">
update <include refid="baseMapper.str_table_people"></include>
card_id = #{card.id}
<where>
<if test="card_id != null and card_id != ''">
and id=#{id}
</if>
</where>
</update>
</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="oneByOneMapper">
<!-- 嵌套查询 -->
<resultMap type="people" id="peopleWithCard">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
<association property="card" column="card_id" javaType="card"
select="cardMapper.selectById"></association>
</resultMap>
<select id="selectOneByOne" parameterType="Long" resultMap="peopleWithCard">
select <include refid="baseMapper.str_select_people"></include>
from <include refid="baseMapper.str_table_people"></include>
<where>
<if test="_parameter != null and _parameter != ''">
and id=#{_parameter}
</if>
</where>
</select>
<!-- 嵌套结果 -->
<sql id="str_select_people_card">
p.id,p.name,p.age,p.sex,p.card_id,c.code
</sql>
<sql id="str_table_people_card">
people p,card c
</sql>
<resultMap type="people" id="resultPeopleWithCard">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
<association property="card" javaType="card">
<id property="id" column="card_id"/>
<result property="code" column="code"/>
</association>
</resultMap>
<select id="selectResult" parameterType="Long" resultMap="resultPeopleWithCard">
select <include refid="str_select_people_card"></include>
from <include refid="str_table_people_card"></include>
<where>
c.id = p.card_id
<if test="_parameter != null and _parameter != ''">
and p.id=#{_parameter}
</if>
</where>
</select>
</mapper>
4.运行结果
queryCard
1
2
3
4
log4j:WARN No appenders could be found for logger (org.apache.ibatis.logging.LogFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
[id=1,code=aPeopleupdateMyBatisupdateMyBatis1011]
queryPeople
1
2
3
4
log4j:WARN No appenders could be found for logger (org.apache.ibatis.logging.LogFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
people [id=103,name=aPeopleupdate,age=53,sex=0,code=null]
queryPeopleWithCard
1
2
3
4
log4j:WARN No appenders could be found for logger (org.apache.ibatis.logging.LogFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
people [id=103,name=aPeopleupdate,age=53,sex=0,code=[id=1,code=aPeopleupdateMyBatisupdateMyBatis1011]]
queryPeopleWithCardResult
1
2
3
4
log4j:WARN No appenders could be found for logger (org.apache.ibatis.logging.LogFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
people [id=103,name=aPeopleupdate,age=53,sex=0,code=[id=1,code=aPeopleupdateMyBatisupdateMyBatis1011]]
5.总结
查询映射与结果映射这两种一对一关系的实现,根据需要进行选择,如果有已经实现且通过测试的查询,那么应该选择查询映射,如果没有实现的查询,且关联的表多个,那么尽可能使用结果映射。按需选择。


