IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Mybatis配置一对一关系 -> 正文阅读

[Java知识库]Mybatis配置一对一关系

与其说是Mybatis配置一对一,不如说是我们手动配置好数据库的表关联然后映射到Mybatis上去
这里以双向关联为例

1.设计数据表

关于一对一的设计我一般使用两种方式,入下图
在这里插入图片描述

一.使用唯一外键关联

即在任意一张表中添加外键参照对方表的主键,并设置Unique属性,
不过这种方式有个缺点,参照表的Null值只能有一个,在一些特殊情况下不合适

二.主键同时作为外键

优点是可以少设计一列,空间被省下来了,但
是必须要依赖对方表的主键

这里以第一种方式建两张表

CREATE TABLE t_person (
p_id int IDENTITY(1,1),
p_name VARCHAR(20),
P_birth DateTime,
PRIMARY KEY(p_id)
)
CREATE TABLE t_idcard(
c_id int IDENTITY(1,1),
c_number VARCHAR(30),
c_jiguan VARCHAR(30),
c_p_id int UNIQUE,
PRIMARY KEY(c_id),
FOREIGN KEY(c_p_id) REFERENCES t_person(p_id)
)

2.设计实体对象

实体对象是其中最简单的一步
如下:

public class Person {
	
	private Integer PersonID;
	
	private String Name;
	
	private Date Birth;
	
	private IDCard idcard;
	//省略Getter&Setter方法
}
public class IDCard {
	
	private Integer ID;
	
	private String IDNumber;
	
	private String jiguan;
	
	private Person owner;
	//省略Getter&Setter方法
}

3.完成Mapper接口(简单写几个方法)

public interface PersonMapper {
	
	Person getPersonByID(Integer ID);
	
	List<Person> getAll();
	
	void CreateNewPerson(Person person);

}
public interface IDCardMapper {
	
	IDCard getIDCardByID(Integer ID);
	
	List<IDCard> getAllIDCard();
	
	void CreateIDCard(IDCard card);
}

4.完成XML映射配置

PersonMapper的配置文件

<?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="OneToOne.PersonMapper">
	<resultMap type="OneToOne.Person" id="PersonMap">
		<id column="p_id" property="PersonID"/>
		<result column="p_name" property="Name"/>
		<result column="p_birth" property="Birth"/>
		<association property="idcard" javaType="OneToOne.IDCard">
			<id column="c_id" property="ID"/>
			<result column="c_number" property="IDNumber"/>
			<result column="c_jiguan" property="jiguan"/>
		</association>
	</resultMap>
	<!-- 根据ID查找person,并带出对应的IDcard属性 -->
	<select id="getPersonByID"
			parameterType="integer"
			resultMap="PersonMap">
	SELECT * from t_person p left join  t_idcard id on p.p_id = id.c_p_id where p.p_id =#{ID}   		
	</select>
	<!-- 查找所有的用户和IDCard -->	
	<select id="getAll" resultMap="PersonMap">
		Select p.*,id.c_id,id.c_number,id.c_jiguan from t_person p,t_idcard id where p.p_id = id.c_p_id 
	</select>
	<!--插入新的Person对象-->
	<insert id="CreateNewPerson" parameterType="OneToOne.Person">
		insert into t_person values(#{Name},#{Birth})
	</insert>
	
</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="OneToOne.IDCardMapper">
 	<resultMap type="OneToOne.IDCard" id="IDCardMap">
 		<id column="c_id" property="ID"/>
 		<result column="c_number" property="IDNumber"/>
 		<result column="c_jiguan" property="jiguan"/>
 		<association property="owner" javaType="OneToOne.Person">
 			<id column="p_id" property="PersonID"/>
			<result column="p_name" property="Name"/>
			<result column="p_birth" property="Birth"/>
 		</association>
 	</resultMap>
 	<!--根据ID查找Card,注意这里不用左连接,是因为IDCard表是从表,一般都以从表来维护关联,
 	而左连接如果匹配不到也会至少有自身的信息,如果不想带出为null的关联对象,还是内连接比较好-->
 	<select id="getIDCardByID" 
 			resultMap="IDCardMap" 
 			parameterType="integer">
 	Select * from t_idcard id,t_person p where p.p_id = id.c_p_id and id.c_p_id = #{ID}		
 	</select>
 	<select id="getAllIDCard" resultMap="IDCardMap">
 		Select * from t_idcard id,t_person p where p.p_id = id.c_p_id;
 	</select>
 	<!--必须插入关联对象的ID来设置外键,用以维护一对一的关系-->
 	<insert id="CreateIDCard"
 			parameterType="OneToOne.IDCard">
 		insert into t_idcard values(#{IDNumber},#{jiguan},#{owner.PersonID})
 	</insert>
 </mapper> 

5.测试

先向主表插入一条数据

public static void main(String[] args) throws IOException {
		
		InputStream input = Resources.getResourceAsStream("MyBatisCFG.xml");
		
		SqlSessionFactory factory = (new SqlSessionFactoryBuilder()).build(input);
		
		SqlSession Session = factory.openSession();
		
		PersonMapper personmapper = Session.getMapper(PersonMapper.class);
		
		Person person = new Person();person.setName("HJXSB");
		
		person.setBirth(new Date(1999,6,8));
		//插入一条Person记录
		mapper.CreateNewPerson(person);
		
		Session.Commit();
		Session.Close();
}

请添加图片描述
再插入IDCard对象

public static void main(String[] args) throws IOException {
		
		InputStream input = Resources.getResourceAsStream("MyBatisCFG.xml");
		
		SqlSessionFactory factory = (new SqlSessionFactoryBuilder()).build(input);
		
		SqlSession Session = factory.openSession();
		
		PersonMapper personmapper = Session.getMapper(PersonMapper.class);
		IDCardMapper mapper = Session.getMapper(IDCardMapper.class);
		
		IDCard cardOne = new IDCard();
		cardOne.setIDNumber("6020182100");
		cardOne.setJiguan("JX fuzhuo nancheng");
		cardOne.setOwner(personmapper.getPersonByID(1));//把查找到的Person作为参数传入
		
		mapper.CreateIDCard(cardOne);
		
		Session.commit();
		Session.close();
	}
	

查看一下日志:

DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 635611994.
DEBUG [main] - Setting autocommit to false on JDBC Connection [ConnectionID:1 ClientConnectionId: 36df4f8f-e243-43ab-90cd-b28742d1beba]
DEBUG [main] - ==>  Preparing: SELECT * from t_person p left join t_idcard id on p.p_id = id.c_p_id where p.p_id =?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <==      Total: 1
DEBUG [main] - ==>  Preparing: insert into t_idcard values(?,?,?)
DEBUG [main] - ==> Parameters: 6020182199(String), JX nanchang(String), 1(Integer)

在这里插入图片描述
再单独查出来看看

System.out.println(mapper.getIDCardByID(1));

日志:

DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 635611994.
DEBUG [main] - Setting autocommit to false on JDBC Connection [ConnectionID:1 ClientConnectionId: 30529fe9-fe4b-4a6e-bba1-c61c85f15788]
DEBUG [main] - ==>  Preparing: Select * from t_idcard id,t_person p where p.p_id = id.c_p_id and id.c_p_id = ?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <==      Total: 1
IDCard [ID=1, IDNumber=6020182100, jiguan=JX fuzhuo nancheng, owner=Person [PersonID=1, Name=HJXSB, Birth=Sat Jul 08 00:00:00 CST 3899, idcard=null]]

当我们想再次关联已设置关联的对象时(破坏一对一时)

public static void main(String[] args) throws IOException {
		
		InputStream input = Resources.getResourceAsStream("MyBatisCFG.xml");
		
		SqlSessionFactory factory = (new SqlSessionFactoryBuilder()).build(input);
		
		SqlSession Session = factory.openSession();
		
		PersonMapper personmapper = Session.getMapper(PersonMapper.class);
		IDCardMapper mapper = Session.getMapper(IDCardMapper.class);
		
		//第二次,再设置一个关联
		IDCard cardOne = new IDCard();
		cardOne.setIDNumber("6020182199");
		cardOne.setJiguan("JX nanchang");
		cardOne.setOwner(personmapper.getPersonByID(1));
		
		mapper.CreateIDCard(cardOne);
		
		
		
		Session.commit();
		Session.close();
	}

显然会报错:

Error updating database.  Cause: com.microsoft.sqlserver.jdbc.SQLServerException: 違反 UNIQUE KEY 條件約束 'UQ__t_idcard__FFF1E039C1790658'。無法在物件 'dbo.t_idcard' 中插入重複的索引鍵。重複的索引鍵值是 (1)。
### The error may exist in Mappers/IDCardMapper.xml
### The error may involve OneToOne.IDCardMapper.CreateIDCard-Inline
### The error occurred while setting parameters
### SQL: insert into t_idcard values(?,?,?)
### Cause: com.microsoft.sqlserver.jdbc.SQLServerException: 違反 UNIQUE KEY 條件約束 'UQ__t_idcard__FFF1E039C1790658'。無法在物件 'dbo.t_idcard' 中插入重複的索引鍵。重複的索引鍵值是 (1)

PS:
当你引入日志框架设置了配置文件后就可以显示日志了,本例使用的是logback,配置文件
如下

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
	
  <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%5level [%thread] - %msg%n</pattern>
    </encoder>
  </appender>
  <root level="DEBUG">
    <appender-ref ref="stdout"/>
  </root>

</configuration>
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-12 17:18:07  更:2022-03-12 17:20:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:15:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码