这里以一对一单向关联为例。对使用或不使用association的配置进行举例。

 实体类:

@Data
@ToString
@NoArgsConstructor
public class IdCard {
private Integer id;
private String number;
private Date expiredTime; public IdCard(Integer id) {
this.id = id;
} } @Data
@ToString
@NoArgsConstructor
public class Person {
protected Integer id;
protected String name;
protected IdCard idCard; public Person(Integer id) {
this.id = id;
}
}

----------------------------------------------

对于关联属性的配置,有5种方式:

---------------------------------------------

方式零:使用内连接+级联属性:

<?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.sunwii.mybatis.mapper.PersonMapper">
<resultMap type="PersonResult" id="PersonMap">
<id property="id" column="id" />
<result property="name" column="name" />
<!-- 一对一关联:单向。方式零:使用级联属性 -->
<result property="idCard.id" column="cid"/>
<result property="idCard.number" column="number"/>
<result property="idCard.expiredTime" column="expired_time"/>
</resultMap>
<select id="selectById" parameterType="Integer"
resultMap="PersonMap">
select p.id id, p.name name,c.id cid,c.number
number,c.expired_time expired_time from t_person p
inner join t_idcard
c on p.idcard_id=c.id and p.id=#{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.sunwii.mybatis.mapper.PersonMapper">
<resultMap type="PersonResult" id="PersonMap">
<id property="id" column="id" />
<result property="name" column="name" /> <!-- 一对一关联:单向。方式一:使用扩展类,必须重写setter方式,并且父类必须将字段修改成protected,同时修改type。不推荐 -->
<result property="cardId" column="cid" />
<result property="cardNumber" column="number" />
<result property="cardExpiredTime" column="expired_time" />
</resultMap>
<select id="selectById" parameterType="Integer"
resultMap="PersonMap">
select p.id id, p.name name,c.id cid,c.number
number,c.expired_time expired_time from t_person p
inner join t_idcard
c on p.idcard_id=c.id and p.id=#{id}
</select>
</mapper>

扩展类:

package com.sunwii.mybatis.beanresult;

import java.util.Date;

import com.sunwii.mybatis.bean.IdCard;
import com.sunwii.mybatis.bean.Person; @SuppressWarnings("unused")
public class PersonResult extends Person{
private Integer cardId;
private String cardNumber;
private Date cardExpiredTime; public PersonResult() {
super();
//即时实例化关联对象
super.setIdCard(new IdCard());
} public void setCardId(Integer cardId) {
this.cardId = cardId;
//设置
super.getIdCard().setId(cardId);
} public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
//设置
super.getIdCard().setNumber(cardNumber);
}
public void setCardExpiredTime(Date cardExpiredTime) {
this.cardExpiredTime = cardExpiredTime;
//设置
super.getIdCard().setExpiredTime(cardExpiredTime);
} }

方式二:使用内连接+association内联result设置:

<?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.sunwii.mybatis.mapper.PersonMapper">
<resultMap type="PersonResult" id="PersonMap">
<id property="id" column="id" />
<result property="name" column="name" /> <!-- 一对一关联:单向。方式二:使用内联方式直接列出。 -->
<association property="idCard" column="idcard_id" javaType="IdCard">
<id column="cid" property="id" />
<result column="number" property="number" />
<result column="expired_time" property="expiredTime" />
</association>
</resultMap>
<select id="selectById" parameterType="Integer"
resultMap="PersonMap">
select p.id id, p.name name,c.id cid,c.number
number,c.expired_time expired_time from t_person p
inner join t_idcard
c on p.idcard_id=c.id and p.id=#{id}
</select>
</mapper>

方式三:使用内连接+association引用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.sunwii.mybatis.mapper.PersonMapper">
<resultMap type="PersonResult" id="PersonMap">
<id property="id" column="id" />
<result property="name" column="name" /> <!-- 一对一关联:单向。方式三:使用resultMap引用。
注意的是column名称必须与关联表select时的一致(需要修改关联表的select,所以更建议使用select引用方式(见下) -->
<association property="idCard" column="cid"
resultMap
="com.sunwii.mybatis.mapper.IdCardMapper.IdCardMap" /> </resultMap>
<select id="selectById" parameterType="Integer"
resultMap="PersonMap">
select p.id id, p.name name,c.id cid,c.number
number,c.expired_time expired_time from t_person p
inner join t_idcard
c on p.idcard_id=c.id and p.id=#{id}
</select>
</mapper>

注意:对于IdCardMapper,为配合方式三需要修改查询到的id属性为cid(即指定column="cid"):

<mapper namespace="com.sunwii.mybatis.mapper.IdCardMapper">
<resultMap type="IdCard" id="IdCardMap">
<id property="id" column="cid" />
<result property="number" column="number" />
<result property="expiredTime" column="expired_time" />
</resultMap>
<select id="selectById" parameterType="Integer"
resultMap="IdCardMap">
select id as cid ,number,expired_time from t_idcard where id=#{id}
</select>
</mapper>

方式四:使用单表查询+association引用select方式,不用inner查询(以避免再次查询),可以利用延迟加载,配置:

<mapper namespace="com.sunwii.mybatis.mapper.PersonMapper">
<resultMap type="PersonResult" id="PersonMap">
<id property="id" column="id" />
<result property="name" column="name" /> <!-- 一对一关联:单向。方式四:使用select引用,可以设置延迟加载方式 -->
<association property="idCard" column="idcard_id"
javaType="IdCard"
select="com.sunwii.mybatis.mapper.IdCardMapper.selectById" fetchType="lazy"/>
</resultMap>
<select id="selectById" parameterType="Integer"
resultMap="PersonMap">
select id, name, idcard_id from t_person p where p.id=#{id}
</select>
</mapper>

一个一对一单向关联使用注解的例子:(采用方式四非join方式,延迟加载)

Mapper接口类:

@Mapper
public interface IdCardMapper {
@Select("select id,number,expired_time from t_idcard where id=#{id}")
@Results(id="IdCardMap", value = {
@Result(property = "id", column = "id"),
@Result(property = "number", column = "number"),
@Result(property = "expiredTime", column = "expired_time"),
})
public IdCard selectById(Integer id); @Insert("insert into t_idcard(number,expired_time) values(#{number},#{expiredTime}")
@Options(keyColumn = "id",keyProperty = "id",useGeneratedKeys = true)
public int insertIdCard(IdCard idCard); @Update("update t_idcard set number=#{number},expired_time=#{expiredTime}")
public int updateIdCard(IdCard idCard); @Delete("delete from t_idcard where id=#{id}")
public int deleteIdCard(IdCard idCard);
}
@Mapper
public interface PersonMapper {
    @Select("select id,name,idcard_id from t_person where id=#{id}")
@Results(id="PersonMap",value = {
@Result(property = "id",column = "id"),
@Result(property = "name",column = "name"),
@Result(property = "idCard",column = "idcard_id",
one=@One(select = "com.sunwii.mybatis.mapper.IdCardMapper.selectById",fetchType = FetchType.LAZY))
})
public Person selectById(Integer id); @Insert("insert into t_person(name,idcard_id) values(#{name},#{idCard.id})")
@Options(keyColumn = "id",keyProperty = "id",useGeneratedKeys = true)
public int insertPerson(Person person); @UpdateProvider(type = com.sunwii.mybatis.provider.PersonDynamicSqlProvider.class, method = "update")
public int updatePerson(Person person); @Delete("delete from t_person where id=#{id}")
public int deletePerson(Person person); }

动态SQL支持:

public class PersonDynamicSqlProvider {
public String update(Person person) {
return new SQL() {
{
UPDATE("t_person");
SET("name=#{name}"); if(person.getIdCard()!=null) {
SET("idcard_id=#{idCard.id}");
} WHERE("id=#{id}");
}
}.toString();
}
}

业务层:

@Service
public class IdCardServiceImpl implements IdCardService{
@Autowired
private IdCardMapper idCardMapper; @Override
public IdCard getIdCard(Integer id) {
return idCardMapper.selectById(id);
} @Override
@Transactional
public void updateIdCard(IdCard idCard) {
idCardMapper.updateIdCard(idCard);
} @Override
@Transactional
public void insertIdCard(IdCard idCard) {
idCardMapper.insertIdCard(idCard);
} }
@Service
public class PersonServiceImpl implements PersonService {
@Autowired
private PersonMapper personMapper; @Autowired
private IdCardMapper idCardMapper; @Override
public Person getPerson(Integer id) {
return personMapper.selectById(id);
} @Override
@Transactional
public void insertPersion(Person person) {
// 一对于单向关联:执行主表的插入前,先执行从被关联表的插入并获取其最新插入的主健
// 由于插件后会自动更新关联实体的ID,所以这里不需要进行设置
IdCard idCard = person.getIdCard(); // 这种方式将对Person的属性设置时不进行setIdCart(),会将IdCard的插入延迟,可在后续进行补充的添加(不要求一定要有IdCard)。
// 必须配合<if test="idCard != null">来操作
if (idCard != null) {
idCardMapper.insertIdCard(idCard);
} personMapper.insertPerson(person); } @Override
@Transactional
public void updatePersion(Person person) {
// 每次更新都要先更新被关联表,这样不行,必须独立到从表的更新去=>idCardService.updateIdCard(idCard)
// IdCard idCard = person.getIdCard();
// if (idCard != null && idCard.getId() != null) {
// idCardMapper.updateIdCard(idCard);
// } personMapper.updatePerson(person); } @Override
@Transactional
public void deletePersion(Person person) {
// 一对于单向关联:执行主表的删除后,再执行被关联表的删除
// 由于插件后会自动更新关联实体的ID,所以这里不需要进行设置 personMapper.deletePerson(person); IdCard idCard = person.getIdCard(); // 有IdCard则删除
if (idCard != null) {
idCardMapper.deleteIdCard(idCard);
}
} }

SpringUtil工具类:

public class SpringUtil {
private static ApplicationContext context = null;
static {
context = new ClassPathXmlApplicationContext("applicationContext.xml");
}
public static ApplicationContext getContext() {
return context;
}
}

Mybatis配置文件:

<?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>
<settings>
<setting name="lazyLoadingEnabled" value="true" />
<setting name="aggressiveLazyLoading" value="false" />
</settings> <typeAliases>
<package name="com.sunwii.mybatis.bean" />
</typeAliases> </configuration>

Spring配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mybatis
="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd
http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd"> <!-- 引入jdbcs配置文件 -->
<context:property-placeholder
location="classpath:jdbc.properties" /> <!-- 数据库连接池 -->
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${user}" />
<property name="password" value="${password}" />
<property name="maxActive" value="210" />
<property name="maxIdle" value="50" />
</bean> <!-- mybatis -->
<bean id="sessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation"
value="classpath:mybatis-config.xml" />
<property name="mapperLocations"
value="classpath:com/sunwii/mybatis/bean/*.xml" />
</bean> <!-- Mapper动态代理开发扫描 -->
<mybatis:scan base-package="com.sunwii.mybatis.mapper" /> <!-- 事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean> <!-- 事务注解 -->
<tx:annotation-driven
transaction-manager="transactionManager" /> <!-- 组件扫描 -->
<!-- Service扫描 -->
<context:component-scan
base-package="com.sunwii.mybatis.service.impl" />
</beans>

 

测试类:

public class TestOne2OnePerson {
private ApplicationContext context = SpringUtil.getContext();
private PersonService personService = (PersonService) context.getBean(PersonService.class);
private IdCardService idCardService = (IdCardService) context.getBean(IdCardService.class); @Test
public void testPersonInsert() {
// 一对一单向:添加。
Person person = new Person();
person.setName("person-1"); IdCard idCard = new IdCard();
idCard.setNumber(UUID.randomUUID().toString());
idCard.setExpiredTime(CurrentUtil.currentDate()); person.setIdCard(idCard); personService.insertPersion(person);
} @Test
public void testPersonInsert2() {
// 一对一单向:添加。
Person person = new Person();
person.setName("person-8");
personService.insertPersion(person); //后续的操作,添加idCard并更新Person
IdCard idCard = new IdCard();
idCard.setNumber(UUID.randomUUID().toString());
idCard.setExpiredTime(CurrentUtil.currentDate());
idCardService.insertIdCard(idCard);
person.setIdCard(idCard);
personService.updatePersion(person); } @Test
public void testPersonSelect() {
// 一对一单向:查询。
int id = 6;
Person person = personService.getPerson(id);
System.out.println(person.toLasyString());
System.out.println(person.toString());
} @Test
public void testPersonUpdate() {
// 一对一单向:更新。
int id = 6;
Person person = personService.getPerson(id);
person.setName("person-1-update");
personService.updatePersion(person); System.out.println(person);
} @Test
public void testIdCardUpdate() {
// 一对一单向:更新。
int id = 3;
Person person = personService.getPerson(id); IdCard idCard = person.getIdCard();
idCard.setNumber(UUID.randomUUID().toString()); idCardService.updateIdCard(idCard); System.out.println(person);
} @Test
public void testPersonDelete() {
// 一对一单向:删除。
int id = 3;
Person person = personService.getPerson(id);
personService.deletePersion(person); }
}

 以上为注解版的一对一的使用示例,也可以使用非注解版(XML版本),需要增加Mapper映射文件。

Mapper映射文件:

PersonMapper.xml:

<?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.sunwii.mybatis.mapper.PersonMapper">
<resultMap type="PersonResult" id="PersonMap">
<id property="id" column="id" />
<result property="name" column="name" /> <!-- 一对一关联:单向。方式四:使用select引用方式 -->
<association property="idCard" column="idcard_id"
javaType="IdCard"
select="com.sunwii.mybatis.mapper.IdCardMapper.selectById"
fetchType="lazy" /> </resultMap>
<select id="selectById" parameterType="Integer"
resultMap="PersonMap">
select id, name, idcard_id from t_person p where p.id=#{id}
</select> <insert id="insertPerson" parameterType="Person" keyColumn="id"
keyProperty="id" useGeneratedKeys="true">
insert into t_person(name,idcard_id)
values(#{name},#{idCard.id})
</insert> <update id="updatePerson" parameterType="Person">
update t_person set name=#{name}
<if test="idCard != null">
,idcard_id=#{idCard.id}
</if>
where id=#{id}
</update> <delete id="deletePerson" parameterType="Person">
delete from t_person
where id=#{id}
</delete>
</mapper>

IdCardMapper.xml:

<?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.sunwii.mybatis.mapper.IdCardMapper">
<resultMap type="IdCard" id="IdCardMap">
<id property="id" column="cid" />
<result property="number" column="number" />
<result property="expiredTime" column="expired_time" />
</resultMap> <select id="selectById" parameterType="Integer" resultMap="IdCardMap">
select id as cid ,number,expired_time from t_idcard where id=#{id}
</select> <select id="selectById2" parameterType="Integer" resultType="IdCard">
select id,number,expired_time as expiredTime from t_idcard where id=#{id}
</select> <insert id="insertIdCard" parameterType="IdCard" keyColumn="id"
keyProperty="id" useGeneratedKeys="true">
insert into
t_idcard(number,expired_time) values(#{number},#{expiredTime})
</insert> <update id="updateIdCard" parameterType="IdCard">
update t_idcard set
number=#{number},expired_time=#{expiredTime} where id=#{id}
</update> <delete id="deleteIdCard" parameterType="IdCard">
delete from t_idcard
where id=#{id}
</delete>
</mapper>

一对多(以及多对一)的示例(含XML版本和注解版本),链接:

https://www.cnblogs.com/dreamyoung/p/11803605.html

多对多(以及多对一)的示例(含XML版本和注解版本),链接:

https://www.cnblogs.com/dreamyoung/p/11804936.html

自关联示例(含XML版本和注解版本),链接:

https://www.cnblogs.com/dreamyoung/p/11810921.html

===============end of <<Mybatis中使用association进行关联的几种方式>>=====================

Mybatis中使用association进行关联的几种方式的更多相关文章

  1. MyBatis 中传递多个参数的 4 种方式

    方式 1 :封装成对象入参  #{对应实体类的属性} //UserMapper.java 接口 /** * 多条件查询:根据用户名称(模糊查询)和用户角色查询用户列表(参数:对象入参) * @para ...

  2. Prism框架中View与Region关联的几种方式

    Prism.Regions命名空间下有2个重要接口:IRegionManager.IRegion IRegionManager接口中的方法与属性:AddToRegion().RegisterViewW ...

  3. Dojo初探之2:设置dojoConfig详解,dojoConfig参数详解+Dojo中预置自定义AMD模块的四种方式(基于dojo1.11.2)

    Dojo中想要加载自定义的AMD模块,需要先设置好这个模块对应的路径,模块的路径就是这个模块的唯一标识符. 一.dojoConfig参数设置详解 var dojoConfig = { baseUrl: ...

  4. C# 中一些类关系的判定方法 C#中关于增强类功能的几种方式 Asp.Net Core 轻松学-多线程之取消令牌

    1.  IsAssignableFrom实例方法 判断一个类或者接口是否继承自另一个指定的类或者接口. public interface IAnimal { } public interface ID ...

  5. 聊聊业务系统中投递消息到mq的几种方式

    背景 电商中有这样的一个场景: 下单成功之后送积分的操作,我们使用mq来实现 下单成功之后,投递一条消息到mq,积分系统消费消息,给用户增加积分 我们主要讨论一下,下单及投递消息到mq的操作,如何实现 ...

  6. Action中取得request,session的四种方式

    Action中取得request,session的四种方式 在Struts2中,从Action中取得request,session的对象进行应用是开发中的必需步骤,那么如何从Action中取得这些对象 ...

  7. WPF中使用文件浏览对话框的几种方式

    原文:WPF中使用文件浏览对话框的几种方式 WPF本身并没有为我们提供文件浏览的控件, 也不能直接使用Forms中的控件,而文件浏览对话框又是我们最常用的控件之一. 下面是我实现的方式 方式1: 使用 ...

  8. Struts2中获取HttpServletRequest,HttpSession等的几种方式

    转自:http://www.kaifajie.cn/struts/8944.html package com.log; import java.io.IOException; import java. ...

  9. 转 Velocity中加载vm文件的三种方式

    Velocity中加载vm文件的三种方式   velocitypropertiespath Velocity中加载vm文件的三种方式:    方式一:加载classpath目录下的vm文件 Prope ...

随机推荐

  1. 关于 ElementUI 通知组件 notification 重叠问题的解决方案

    转载链接:https://blog.csdn.net/csdn_yudong/article/details/101271214 ElementUI 通知组件(notification) 多个时会重叠 ...

  2. Centos 7.x卸载ibus黑屏修复及fcitx搜狗拼音安装方法

    ibus黑屏修复 百度出来的fcitx安装方法,都要卸载ibus,如果没有注意同时卸载掉的依赖包的话,gnome桌面中的一些关键库也没被卸载. 修复方法很简单,重新安装Gnome sudo yum - ...

  3. linux下如何使用adb连接在qemu中运行的安卓系统?

    1. 运行安卓系统, 如下: $sudo qemu-system-x86_64 -m 4096 -boot d -enable-kvm -smp 3 -net nic -net user,hostfw ...

  4. Java基础 awt Frame 窗体的大小不可调

        JDK :OpenJDK-11      OS :CentOS 7.6.1810      IDE :Eclipse 2019‑03 typesetting :Markdown   code ...

  5. 利用Superlance监控Supervisor运行状态并实现报警

    Superlance是基于supervisor的事件机制实现的一系列命令行的工具集,它实现了许多supervisor本身没有实现的实用的进程监控和管理的特性,包括内存监控,http接口监控,邮件和短信 ...

  6. C#中如何获取系统文件及操作系统的环境变量等

    C#中获取系统环境变量需要用到Environment 类. 其中提供了有关当前环境和平台的信息以及操作它们的方法.该类不能被继承 以下代码得到%systemdrive%的值,即“C:” string ...

  7. SNF快速开发平台2019-用户安全控制-权限管理模型实践-权限都在这里

    1.1    是否保存密码 勾选记住密码后,再次开启程序用户密码不需要再次输入,直接显示在密码输入框内,方便快捷. 图 4.1‑1 记住密码的登录页面框 1.2    是否自动登录 勾选自动登录后,再 ...

  8. bootcss 之 .table-hover 类 鼠标悬停

    通过添加 .table-hover 类可以让 <tbody> 中的每一行对鼠标悬停状态作出响应. <table class="table table-hover" ...

  9. 我最近买的书里面带的CD盘,放电脑里后,说是0字节,但是可以播放,不能把里面的东西复制出来

    我最近买的书里面带的CD盘,放电脑里后,说是0字节,但是可以播放,不能把里面的东西复制出来,有track1,track2之类的文件,都只有几十字节大,请问有没有什么方法把里面的音乐复制出来??? 用w ...

  10. Linux shell字符串操作

    #!/bin/bash #镜像名 image="asr-server" #镜像版本 ver="5.2.1" #容器名 dname="asr" ...