Mybatis一对一 关联查询
一、单向
实际开发过程中,经常存在一对一关系,比如一个人只能有一个身份证,一个身份证只能给一个人使用,这就是一对一的关系。
一对一关系推荐使用唯一主外键关联,即两张表使用外键关联关系,由于是一对一关联,因此还需要给外键增加unique唯一约束。
1.数据库设计
创建身份证表tb_card 及 个人信息表 tb_person。
其中:tb_card表中的id为主键,tb_person表中的card_id为外键,并设unique唯一约束。
创建身份证表
create table tb_card(
cid int primary key auto_increment, #卡号id
ccode varchar(18) #卡号
);
创建个人信息表
create table tb_person(
pid int primary key auto_increment, #个人信息id
pname varchar(50), #个人信息姓名
psex varchar(4), #个人信息性别
page int, #个人信息年龄
card_id int UNIQUE, #个人信息卡号
CONSTRAINT fk_id FOREIGN KEY(card_id) REFERENCES tb_card(cid)
);
2.实体类及接口
2.1 在com.liuYongQi.MyBatis4.pojo包中创建Card类和Person类,分别映射tb_card表和tb_person表。
package com.liuYongQi.MyBatis4.pojo;
import java.io.Serializable;
/**
* @ClassName: Card
* @Description: 身份证tb_card实体类
* @Author: Administrator
* @CreateDate: 2018/10/2 20:29
* @UpdateUser: Administrator
* @UpdateDate: 2018/10/2 20:29
* @UpdateRemark: 修改内容
* @Version: 1.0
*/
public class Card implements Serializable {
private Integer cid; //卡号id
private String ccode; //卡号
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public String getCcode() {
return ccode;
}
public void setCcode(String ccode) {
this.ccode = ccode;
}
public Card(Integer cid, String ccode) {
this.cid = cid;
this.ccode = ccode;
}
public Card(String ccode) {
this.ccode = ccode;
}
public Card() {
}
@Override
public String toString() {
return "Card{" +
"cid=" + cid +
", ccode='" + ccode + '\'' +
'}';
}
}
package com.liuYongQi.MyBatis4.pojo;
import java.io.Serializable;
/**
* @ClassName: Person
* @Description: 个人信息表tb_person实体类
* @Author: Administrator
* @CreateDate: 2018/10/2 20:42
* @UpdateUser: Administrator
* @UpdateDate: 2018/10/2 20:42
* @UpdateRemark: 修改内容
* @Version: 1.0
*/
public class Person implements Serializable {
private Integer pid; //个人信息id
private String pname; //个人信息姓名
private String psex; //个人信息性别
private Integer page; //个人信息年龄
private Integer card_id; //个人信息卡号
private Card card; //人和身份证是一对一的关系,即一个人只有一个身份证
public Person(Integer pid, String pname, String psex, Integer page, Card card) {
this.pid = pid;
this.pname = pname;
this.psex = psex;
this.page = page;
this.card = card;
}
public Person() {
}
public Integer getPid() {
return pid;
}
public void setPid(Integer pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public String getPsex() {
return psex;
}
public void setPsex(String psex) {
this.psex = psex;
}
public Integer getPage() {
return page;
}
public void setPage(Integer page) {
this.page = page;
}
public Card getCard() {
return card;
}
public void setCard(Card card) {
this.card = card;
}
public Integer getCard_id() {
return card_id;
}
public void setCard_id(Integer card_id) {
this.card_id = card_id;
}
@Override
public String toString() {
return "Person{" +
"pid=" + pid +
", pname='" + pname + '\'' +
", psex='" + psex + '\'' +
", page=" + page +
", card_id=" + card_id +
", card=" + card +
'}';
}
}
2.2 在com.liuYongQi.MyBatis4.dao中分别创建Card类和Person类的接口(做接口注册)
package com.liuYongQi.MyBatis4.dao;
import com.liuYongQi.MyBatis4.pojo.Card;
/**
* @ClassName: ICardDao
* @Description: 身份证tb_card实体类接口
* @Author: Administrator
* @CreateDate: 2018/10/2 20:56
* @UpdateUser: Administrator
* @UpdateDate: 2018/10/2 20:56
* @UpdateRemark: 修改内容
* @Version: 1.0
*/
public interface ICardDao {
/**
* @Author Administrator
* @Description 根据卡号id查询卡号对象
* @Date 20:57 2018/10/2
* @Param [cid]
* @return com.liuYongQi.MyBatis4.pojo.Card
* @exception
*/
public Card selectCardByCid(int cid);
}
package com.liuYongQi.MyBatis4.dao;
import com.liuYongQi.MyBatis4.pojo.Card;
import com.liuYongQi.MyBatis4.pojo.Person;
/**
* @ClassName: IPersonDao
* @Description: 个人信息表tb_person实体类接口
* @Author: Administrator
* @CreateDate: 2018/10/2 20:58
* @UpdateUser: Administrator
* @UpdateDate: 2018/10/2 20:58
* @UpdateRemark: 修改内容
* @Version: 1.0
*/
public interface IPersonDao {
/**
* @Author Administrator
* @Description 根据个人id查询个人信息对象
* @Date 20:59 2018/10/2
* @Param [pid]
* @return com.liuYongQi.MyBatis4.pojo.Person
* @exception
*/
public Person selectPersonByPid(int pid);
}
3对象/关系映射文件
3.1使用嵌套结果映射来处理重复的联合结果的子集:
(1)在com.liuYongQi.MyBatis4.mapper包中创建Card类和Person类对象/关系映射文件。
CardMapper.xml文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--Card接口注册-->
<mapper namespace="com.liuYongQi.MyBatis4.dao.ICardDao">
<!--根据卡号id查询卡号对象-->
<select id="selectCardByCid" parameterType="int" resultType="com.liuYongQi.MyBatis4.pojo.Card">
select * from tb_card where cid=#{cid}
</select>
</mapper>
|
PersonMapper.xml文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--Person接口注册-->
<mapper namespace="com.liuYongQi.MyBatis4.dao.IPersonDao">
<!--根据个人id查询个人信息对象,返回结果为resultMap-->
<select id="selectPersonByPid" parameterType="int" resultMap="personMapper">
select * from tb_person p , tb_card c where p.card_id=c.cid and pid=#{pid}
</select>
<!--映射Person对象的resultMap(结果映射集)id需要和何resultMap的id一致-->
<resultMap id="personMapper" type="com.liuYongQi.MyBatis4.pojo.Person">
<id property="pid" column="pid"></id> <!--主键-->
<result property="pname" column="pname"></result>
<result property="psex" column="psex"></result>
<result property="page" column="page"></result>
<result property="card_id" column="card_id"></result>
<!--一对一关联映射:association-->
<association property="card" javaType="com.liuYongQi.MyBatis4.pojo.Card">
<id property="cid" column="cid"></id>
<result property="ccode" column="ccode"></result>
</association>
</resultMap>
</mapper>
|
(2)在MyBatisConfig.xml中配置mapper映射文件
<?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>
<!--1. 配置数据库环境,默认使用development数据库构建环境-->
<environments default="development">
<!--配置环境变量-->
<environment id="development">
<!--配置事务管理器类别-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/db_mybatis?useUnicode=true&characterEncoding=UTF-8"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</dataSource>
</environment>
</environments>
<!--2. 加载映射器:实体类对象/关系映射文件-->
<mappers>
<mapper resource="com/liuYongQi/MyBatis4/mapper/CardMapper.xml"></mapper>
<mapper resource="com/liuYongQi/MyBatis4/mapper/PersonMapper.xml"></mapper>
</mappers>
</configuration>
3.2通过执行另外一个SQL映射语句来返回预期的复杂类型
相关属性解释:
PersonMapper.xml文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--Person接口注册-->
<mapper namespace="com.liuYongQi.MyBatis4.dao.IPersonDao">
<!--根据个人id查询个人信息对象,返回结果为resultMap-->
<select id="selectPersonByPid" parameterType="int" resultMap="personMapper">
select * from tb_person where pid=#{pid}
</select>
<!--映射Person对象的resultMap(结果映射集)id需要和何resultMap的id一致-->
<resultMap id="personMapper" type="com.liuYongQi.MyBatis4.pojo.Person">
<id property="pid" column="pid"></id>
<result property="pname" column="pname"></result>
<result property="psex" column="psex"></result>
<result property="page" column="page"></result>
<result property="card_id" column="card_id"></result>
<!--复杂类型的集 嵌入结果映射 – 结果映射自身的集,或者参考一个-->
<collection property="card" column="card_id" select="selectCardByCid"></collection>
</resultMap>
<!--根据卡号id查询卡号对象-->
<select id="selectCardByCid" resultType="com.liuYongQi.MyBatis4.pojo.Card" parameterType="int">
select cid cid,ccode ccode from tb_card where cid=#{cid}
</select>
|
4.测试
在com.liuYongQi.test.TestCRUD中创建测试类进行测试
package com.liuYongQi.test;
import com.liuYongQi.MyBatis4.dao.ICardDao;
import com.liuYongQi.MyBatis4.dao.IPersonDao;
import com.liuYongQi.MyBatis4.pojo.Card;
import com.liuYongQi.MyBatis4.pojo.Person;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class TestCRUD {
//获得SqlSession对象,通过SqlSession操作CRUD
private SqlSession sqlSession;
private ICardDao icardDao ;
private IPersonDao ipersonDao;
@Before
public void before(){
//读取配置文件,获取SQLSessionFactory
try {
//通过Resources类加载核心配置文件,得到文件的输入流
InputStream inputStream = Resources.getResourceAsStream("MyBatisConfig.xml");
//创建会话工厂,编译配置文件流,sqlSessionFactory
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//通过sqlSessionFactory得到sqlSession象
sqlSession = sqlSessionFactory.openSession();
//通过sqlSession获得映射实例类的父接口
icardDao = sqlSession.getMapper(ICardDao.class);
ipersonDao = sqlSession.getMapper(IPersonDao.class);
} catch (IOException e) {
e.printStackTrace();
}
}
@After
public void after(){
sqlSession.commit();
}
@Test
public void testCard(){
Card card = icardDao.selectCardByCid(1);
System.out.println(card);
}
|
二、双向
双向只需要在单向的基础上改动一点点东西就可以了
Card实体类:
package com.liuYongQi.MyBatis4.pojo;
import java.io.Serializable;
/**
* @ClassName: Card
* @Description: 身份证tb_card实体类
* @Author: Administrator
* @CreateDate: 2018/10/2 20:29
* @UpdateUser: Administrator
* @UpdateDate: 2018/10/2 20:29
* @UpdateRemark: 修改内容
* @Version: 1.0
*/
public class Card implements Serializable {
private Integer cid; //卡号id
private String ccode; //卡号
//一个身份证只属于一个人
private Person person;
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public String getCcode() {
return ccode;
}
public void setCcode(String ccode) {
this.ccode = ccode;
}
public Card(Integer cid, String ccode) {
this.cid = cid;
this.ccode = ccode;
}
public Card(String ccode) {
this.ccode = ccode;
}
public Card() {
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
@Override
public String toString() {
return "Card{" +
"cid=" + cid +
", ccode='" + ccode + '\'' +
", person=" + person +
'}';
}
}
CardMapper.xml文件:
<?xml version="1.0" encoding="UTF-8" ?>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--Card接口注册-->
<mapper namespace="com.liuYongQi.MyBatis4.dao.ICardDao">
<!--根据卡号id查询卡号对象-->
<select id="selectCardByCid" parameterType="int" resultMap="cardMapper">
select * from tb_card c,tb_person p where c.cid=p.card_id and c.cid=#{cid}
</select>
<!--映射Card对象的resultMap(结果映射集)id需要和何resultMap的id一致-->
<resultMap id="cardMapper" type="com.liuYongQi.MyBatis4.pojo.Card">
<id property="cid" column="cid"></id>
<result property="ccode" column="ccode"></result>
<association property="person" javaType="com.liuYongQi.MyBatis4.pojo.Person">
<id property="pid" column="pid"></id>
<result property="pname" column="pname"></result>
<result property="psex" column="psex"></result>
<result property="page" column="page"></result>
<result property="card_id" column="card_id"></result>
</association>
</resultMap>
</mapper>
|
今天的测试就到这里了,谢谢大家的支持!
如果大家想浏览我的下一篇文章,请留言
版权声明:此文章属于原创,不准随意转载:https://blog.csdn.net/LYQ2332826438