Mybatis中使用association进行关联的几种方式

5495 admin
刘诗雯世界杯

系列文章目录

一对一单向关联的示例(含XML版本和注解版本) 一对多(以及多对一)的示例(含XML版本和注解版本) 多对多(以及多对一)的示例(含XML版本和注解版本) 自关联示例(含XML版本和注解版本)

文章目录

系列文章目录前言实体类使用内连接+级联属性(不使用association)

一、关联属性XML版本方式一:使用内连接+扩展类(不推荐)方式二:使用内连接+association内联result设置方式三:使用内连接+association引用resultMap方式四:使用单表查询+association引用select方式,不用inner查询(以避免再次查询),可以利用延迟加载

二、关联属性注解版本Mapper接口类:业务层:SpringUtil工具类:Mybatis配置文件:Spring配置文件:测试类:

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

前言

当使用 MyBatis 进行查询的时候如果一个 JavaBean 中包含另一个 JavaBean 或者 Collection 时,可以通过 MyBatis 的嵌套查询来获取需要的结果; 这里以一对一单向关联为例。对使用或不使用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;

}

}

使用内连接+级联属性(不使用association)

代码如下(示例):

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

一、关联属性XML版本

方式一:使用内连接+扩展类(不推荐)

代码如下(示例):

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

扩展类:

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设置

代码如下(示例):

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

方式三:使用内连接+association引用resultMap

代码如下(示例):

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

resultMap="com.sunwii.mybatis.mapper.IdCardMapper.IdCardMap" />

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

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

代码如下(示例):

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

javaType="IdCard"

select="com.sunwii.mybatis.mapper.IdCardMapper.selectById" fetchType="lazy"/>

二、关联属性注解版本

一个一对一单向关联使用注解的例子:(采用方式五非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);

// 使用动态sql

@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 (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配置文件:

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-config.dtd">

Spring配置文件:

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">

location="classpath:jdbc.properties" />

class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

class="org.mybatis.spring.SqlSessionFactoryBean">

value="classpath:mybatis-config.xml" />

value="classpath:com/sunwii/mybatis/bean/*.xml" />

class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

transaction-manager="transactionManager" />

base-package="com.sunwii.mybatis.service.impl" />

测试类:

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:

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

javaType="IdCard"

select="com.sunwii.mybatis.mapper.IdCardMapper.selectById"

fetchType="lazy" />

keyProperty="id" useGeneratedKeys="true">

insert into t_person(name,idcard_id)

values(#{name},#{idCard.id})

update t_person set name=#{name}

,idcard_id=#{idCard.id}

where id=#{id}

delete from t_person

where id=#{id}

IdCardMapper.xml:

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

keyProperty="id" useGeneratedKeys="true">

insert into

t_idcard(number,expired_time) values(#{number},#{expiredTime})

update t_idcard set

number=#{number},expired_time=#{expiredTime} where id=#{id}

delete from t_idcard

where id=#{id}

恋爱游戏有哪些 十大必玩恋爱游戏推荐 《DayZ》黑夜保持時間介紹