【mybatis xml】数据层框架应用--Mybatis(四)关系映射之一对多关系映射
实际的开发中,对数据库的操作常常会涉及到多张表,这在面向对象中就涉及到了对象与对象之间的关联关系。
针对多表之间的操作,MyBatis提供了关联映射,通过关联映射就可以很好的处理对象与对象之间的关联关系。
你需要了解的知识点
1、关联关系种类
数据库:
在关系型数据库中,多表之间存在着三种关联关系,分别为一对一、一对多和多对多
- 一对一:在任意一方引入对方主键作为外键;
- 一对多:在“多”的一方,添加“一”的一方的主键作为外键;
- 多对多:产生中间关系表,引入两张表的主键作为外键,两个主键成为联合主键或使用新的字段作为主键。
java
一对一:在本类中定义对方类型的对象,如A类中定义B类类型的属性b,B类中定义A类类型的属性a;(双向一对一)
一对多:一个A类类型对应多个B类类型的情况,需要在A类中以集合的方式引入B类类型的对象,在B类中定义A类类型的属性a;
多对多:在A类中定义B类类型的集合,在B类中定义A类类型的集合。
2、关联查询方式
MyBatis加载关联关系对象主要通过两种方式:嵌套查询和嵌套结果。
使用
项目目录如图,其中红色标注的为本次所需要的,本次主要讲解一对多关系映射,如果你对mybatis的xml版不熟悉的话请前往
数据层框架应用--Mybatis(一) 基于XML映射文件实现数据的CRUD
1、创建实体类
创建实体类:在com.lomtom.mybaris.entity
包中创建实体类Type.java
和ProductInfo.java
1、Type.java /** * @Author: LOMTOM * @Date: 2020/4/26 * @Time: 17:48 * @Email: */ @Data public class Type { private int id; private String name; private List<ProductInfo> pis; public Type() { } public Type(String name) { this.name = name; } } 2、ProductInfo.java /** * @Author: LOMTOM * @Date: 2020/4/26 * @Time: 17:48 * @Email: */ @Data public class ProductInfo { private int id; private String code; private String name; private Type t; public ProductInfo() { } public ProductInfo(String code, String name) { this.code = code; this.name = name; } }
2、创建SQL映射的XML文件
创建SQL映射的XML文件typeMapper.xml
和productInfoMapper.xml
1、typeMapper.xml <mapper namespace="com.lomtom.mybatis.mapper.typeMapper"> <!--插入数据--> <insert id="addType" parameterType="Type"> <!--获得刚插入数据表type的记录id--> <selectKey keyProperty="id" resultType="int" order="AFTER"> SELECT LAST_INSERT_ID() AS ID </selectKey> insert into type(name) values(#{name}) </insert> <!--加载数据(方式1)--> <select id="getType" parameterType="int" resultMap="getTypeMap"> select t.id tid, t.name tname, pi.* from type t, product_info pi where pi.tid=t.id and t.id=#{id} </select> <resultMap type="Type" id="getTypeMap"> <id property="id" column="tid"/> <result property="name" column="tname"/> <collection property="pis" ofType= "ProductInfo"> <id property="id" column="id"/> <result property="code" column="code"/> <result property="name" column="name"/> </collection> </resultMap> <!--加载数据(方式2)--> <select id="getType2" resultMap="getType2Map"> select * from type where id=#{id} </select> <resultMap type="Type" id="getType2Map"> <id property="id" column="id"/> <result property="name" column="name"/> <collection property="pis" column="id" select="getProductInfo"/> </resultMap> <select id="getProductInfo" resultMap="getProductInfoMap"> select from product info where tid=#{id} </select> <resultMap type="ProductInfo" id="getProductInfoMap"> <id property="id" column="id"/> <result property="code" column="code"/> <result property="name" column="name"/> </resultMap> </mapper> 2、productInfoMapper.xml <mapper namespace="com.lomtom.mybatis.mapper.productInfoMapper"> <insert id="addProductInfo" parameterMap="addProductInfoPMap"> insert into product_info(code, name, tid) values(#{code}, #{name}, #{t.id}) </insert> <parameterMap type="ProductInfo" id="addProductInfoPMap"> <parameter property="code"/> <parameter property="name"/> <parameter property="t.id"/> </parameterMap> </mapper>
3、注册SQL映射的XML文件
在XML配置文件mybatis-config.xml中注册typeMapper.xml和productInfoMapper.xml。
<mappers> <mapper resource="com/lomtom/mybatis/mapper/productInfoMapper.xml"/> <mapper resource="com/lomtom/mybatis/mapper/typeMapper.xml"/> </mappers>
4、创建表格
创建type
与product_info
两个表
1、type SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for type -- ---------------------------- DROP TABLE IF EXISTS `type`; CREATE TABLE `type` ( `id` int(0) NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1; 2、product_info SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for product_info -- ---------------------------- DROP TABLE IF EXISTS `product_info`; CREATE TABLE `product_info` ( `id` int(0) NOT NULL AUTO_INCREMENT, `code` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `name` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `tid` int(0) NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE, INDEX `fk_product_type_idx`(`tid`) USING BTREE, CONSTRAINT `product_info_ibfk_1` FOREIGN KEY (`tid`) REFERENCES `type` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1;
5、测试一对一关联映射
在测试类里加入以下,用于测试我们刚刚写的插入与查询
@Test public void testAddType(){ SqlSession sqlSession= MybatisUtils.getSession(); //创建Type对象 Type type = new Type("打印机"); //保存Type对象 sqlSession.insert("addType", type); //创建两个 ProductInfo对象 ProductInfo productInfo1=new ProductInfo( "111111", "HP1306"); ProductInfo productInfo2=new ProductInfo( "222222","HP11103"); //设置 ProductInfo对象与Type的关联 productInfo1.setT(type); productInfo2.setT(type); //保存两个 ProductInfo对象 sqlSession.insert("addProductInfo", productInfo1); sqlSession.insert("addProductInfo", productInfo2); sqlSession.commit(); sqlSession.close(); } @Test public void testGetTypeById() { SqlSession sqlSession= MybatisUtils.getSession(); Type t = sqlSession.selectOne("getType", 1); System.out.println(t); sqlSession.commit(); sqlSession.close(); } @Test public void testGetTypeById2() { SqlSession sqlSession= MybatisUtils.getSession(); Type t = sqlSession.selectOne(" getType2", 1); System.out.println(t); sqlSession.commit(); sqlSession.close(); }
你可能会出现的问题
问题一:提示缺少构造函数
描述:
Cause: org.apache.ibatis.executor.ExecutorException: No constructor found in com.lomtom.mybatis.entity.AdminInfo matching [java.lang.Integer, java.lang.String, java.lang.String, java.lang.String, java.lang.String]
分析:我们明明使用了lombok,为啥还会提示缺少构造函数,那是因为我们这里使用复杂的bean,lombok自己识别不出来
解决: 为AdminDetail.java
和AdminInfo.java
创造空的构造函数
写在最后
关注公众号:博奥思园 ,精彩内容不错失
你的支持是作者最大的动力