实际的开发中,对数据库的操作常常会涉及到多张表,这在面向对象中就涉及到了对象与对象之间的关联关系。
针对多表之间的操作,MyBatis提供了关联映射,通过关联映射就可以很好的处理对象与对象之间的关联关系。
在关系型数据库中,多表之间存在着三种关联关系,分别为一对一、一对多和多对多
一对一:在本类中定义对方类型的对象,如A类中定义B类类型的属性b,B类中定义A类类型的属性a;(双向一对一)
一对多:一个A类类型对应多个B类类型的情况,需要在A类中以集合的方式引入B类类型的对象,在B类中定义A类类型的属性a;
多对多:在A类中定义B类类型的集合,在B类中定义A类类型的集合。
MyBatis加载关联关系对象主要通过两种方式:嵌套查询和嵌套结果。
项目目录如图,其中红色标注的为本次所需要的,本次主要讲解一对多关系映射,如果你对mybatis的xml版不熟悉的话请前往
数据层框架应用–Mybatis(一) 基于XML映射文件实现数据的CRUD
创建实体类:在com.lomtom.mybaris.entity
包中创建实体类Type.java
和ProductInfo.java
1、Type.java
/**
* @Author: LOMTOM
* @Date: 2020/4/26
* @Time: 17:48
* @Email: [email protected]
*/
@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: [email protected]
*/
@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;
}
}
创建SQL映射的XML文件typeMapper.xml
和productInfoMapper.xml
1、typeMapper.xml
<mapper namespace="com.lomtom.mybatis.mapper.typeMapper">
<insert id="addType" parameterType="Type">
<selectKey keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID() AS ID
selectKey>
insert into type(name) values(#{name})
insert>
<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"/>
<id property="id" column="id"/>
<result property="code" column="code"/>
<result property="name" column="name"/>
collection>
resultMap>
<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="id" 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>
在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>
创建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;
在测试类里加入以下,用于测试我们刚刚写的插入与查询
@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
创造空的构造函数
关注公众号:博奥思园 ,精彩内容不错失
你的支持是作者最大的动力