ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

8.MyBatis 的关联映射

2021-02-08 13:03:14  阅读:229  来源: 互联网

标签:ParentRunner java 映射 junit private 关联 MyBatis org id


8.1关联映射的概念

在关系型数据库中,多表之间存在三种关联关系,分别为一对一,一对多,多对多。
在数据库中的表现:

  • 一对一:在任意一方引入对方主键作为外键

  • 一对多:在“多”的一方引入“一”的一方作为主键

  • 多对多:产生中间关系表,引入两个表的主键作为外键,两个主键成为联合 主键或使用新的字段作为主键。
    在Java实现时的表现:

  • 一对一:在本类中定义对方类型的对象

  • 一对多:一个A类型对应多个B类型,在A类中以集合的方式引入B类型,在B类中定义A类型的属性a

  • 多对多:均定义对方类型的集合

8.2一对一

案例:每个人都有唯一的身份证
创建好对应的数据库,然后创建对应的实体类,以及对应的get和set方法

public class IdCard {
	private Integer id;
	private String code;
}
public class Person {
	private Integer id;
	private String name;
	private Integer age;
	private String sex;
	private IdCard card;
}

为了实现一对一查询,总共有两种方法,一个是嵌套查询,一个是嵌套结果
方法一:嵌套查询
相当于需要编写两个SQl语句,首先创建IdCardMapper,编写findCardById

<mapper namespace="com.itheima.mapper.IdCardMapper">
	<!-- 根据卡号查询-->
	<select id="findCardById" parameterType="Integer"
		resultType="com.itheima.po.IdCard">
		select * from tb_idcard where id = #{id}
	</select>
</mapper>

然后编写

<mapper namespace="com.itheima.mapper.PersonMapper">
	<!-- 根据卡号查询-->
	<select id="findPersonById" parameterType="Integer"
		resultMap="IdCardWithPersonResult">
		select * from tb_person where id = #{id}
	</select>
	<resultMap type="Person" id="IdCardWithPersonResult">
		<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="IdCard"
					 select="com.itheima.mapper.IdCardMapper.findCardById"></association>
	</resultMap>
</mapper>

在association元素中,
property对应实体类对象属性
column对应表中的字段
javaType对应实体类的类型
select对应嵌套的子查询语句
方法二:嵌套结果

<select id="findPersonById2" parameterType="Integer"
		resultMap="IdCardWithPersonResult2">
		select p.*,idcard.code
		from tb_person p,tb_idcard idcard
		where p.card_id=idcard.id and p.id = #{id}
	</select>
	<resultMap type="Person" id="IdCardWithPersonResult2">
	<id property="id" column="id"/>
		<result property="name" column="name"/>
		<result property="age" column="age"/>
		<result property="sex" column="sex"/>
		<association property="card" javaType="IdCard">
			<id property="id" column="card_id" />
			<result property="code" column="code"/>
		</association>
	</resultMap>

编写测试方法,运行
方法一在这里插入图片描述

方法二
在这里插入图片描述

8.3一对多

案列:一个顾客有多个订单
编写测试数据库,编写实体类,并在顾客实体类中定义订单列表

public class Orders {
	private Integer id;
	private String number;
	}
public class User {
	private Integer id;
	private String username;
	private String address;
	private List<Orders> orderlist;
}

编写查询方法

<mapper namespace="com.itheima.mapper.UserMapper">
	<select id="findUserWithOrders" parameterType="Integer"
		resultMap="UserWithOrderResult">
		select u.*,o.id as orders_id,o.number
		from tb_user u,tb_orders o
		where u.id=o.user_id and u.id = #{id}
	</select>
	<resultMap type="User" id="UserWithOrderResult">
		<id property="id" column="id"/>
		<result property="username" column="username"/>
		<result property="address" column="address"/>
		<collection property="orderlist" ofType="Orders">
			<id property="id" column="orders_id" />
			<result property="number" column="number"/>
		</collection>
	</resultMap>

这里与上一个不同的属性时ofType
编写测试方法测试
在这里插入图片描述
在测试过程中,出现错误

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.itheima.mapper.PersonMapper.UserMapper.findUserWithOrders
### Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.itheima.mapper.PersonMapper.UserMapper.findUserWithOrders
	at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:150)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:77)
	at com.itheima.test.MyBatisAssTest.findUser(MyBatisAssTest.java:39)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12).
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.itheima.mapper.PersonMapper.UserMapper.findUserWithOrders
	at org.apache.ibatis.session.Configuration$StrictMap.get(Configuration.java:875)
	at org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:708)
	at org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:701)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147)
	... 26 more

这种情况有四种可能性;

1、mapper.xml中没有加入namespace
2、mapper.xml中的方法和接口mapper的方法不对应
3、mapper.xml没有加入到mybatis-config.xml中(即总的配置文件),例外:配置了mapper文件的包路径的除外
4、mapper.xml文件名和所写的mapper名称不相同
但是我的问题是,com.itheima.mapper.UserMapper.findUserWithOrders路径写错了。
所以大家一定要仔细。

8.4多对多

案例:一个商品对应多个订单,一个订单包含多个商品

编写测试数据库,编写实体类,两个实体类中都需要添加列表

public class Orders {
	private Integer id;
	private String number;
	private List<Product> productList;
}
public class Product {
	private Integer id;
	private String name;
	private Double price;
	private List<Orders> orders;
}

编写多表查询的语句

<mapper namespace="com.itheima.mapper.OrdersMapper">
	<select id="findProductWithOrders" parameterType="Integer"
		resultMap="ProductWithOrderResult">
		select o.*,p.id as pid,p.name,p.price
		from tb_orders o,tb_product p,tb_ordersitem oi
		where o.id=oi.orders_id
		and p.id=oi.product_id
		and o.id = #{id}
	</select>
	<resultMap type="Orders" id="ProductWithOrderResult">
		<id property="id" column="id"/>
		<result property="number" column="number"/>
		<collection property="productList" ofType="Product">
			<id property="id" column="pid" />
			<result property="name" column="name"/>
			<result property="price" column="price"/>
		</collection>
	</resultMap>
</mapper>

运行测试如下:
在这里插入图片描述

标签:ParentRunner,java,映射,junit,private,关联,MyBatis,org,id
来源: https://www.cnblogs.com/weilongZhang/p/14388421.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有