技术驱动人生 2020-05-03
实际的开发中,对数据库的操作常常会涉及到多张表,这在面向对象中就涉及到了对象与对象之间的关联关系。
针对多表之间的操作,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
包中创建实体类AdminDetail.java
和AdminInfo.java
1、AdminDetail.java /** * @Author: LOMTOM * @Date: 2020/4/26 * @Time: 16:43 * @Email: */ @Data public class AdminInfo { private int id; private String name; private String pwd; private AdminDetail ad; public AdminInfo() { } public AdminInfo(String name, String pwd) { this.name = name; this.pwd = pwd; } } 2、AdminInfo.java /** * @Author: LOMTOM * @Date: 2020/4/26 * @Time: 16:42 * @Email: */ @Data public class AdminDetail { private int id; private String address; private String realName; public AdminDetail() { } public AdminDetail(String address, String realName) { this.address = address; this.realName = realName; } }
在com.lomtom.mybaris.mapper
包中创建SQL映射的XML文件adminDetailMapper.xml
及adminInfoMapper.xml
,
<insert>
元素向数据表中插入记录。<select>
元素向数据表中插入记录。1、adminDetailMapper.xml <mapper namespace="com.lomtom.mybatis.mapper.adminDetailMapper"> <insert id="addAdminDetail" parameterType="AdminDetail" keyProperty="id" useGeneratedKeys="true"> insert into admin_detail(address ,realName) values (#{address},#{realName}) </insert> </mapper> 2、adminInfoMapper.xml <mapper namespace="com.lomtom.mybatis.mapper.adminInfoMapper"> <insert id="addAdminInfo" parameterType="AdminInfo"> insert into admin_info(id, name, pwd) values( #{ad.id}, #{name}, #{pwd}) </insert> <select id="getAdminInfo" parameterType="int" resultMap="getAdminInfoMap"> select ai.id, name, pwd, address, realName from admin_info ai, admin_detail ad where ai.id=ad.id and ai.id=#{id} </select> <!--嵌套结果映射,最后返回的结果,见 select元素的 resultMap属性--> <resultMap type="com.lomtom.mybatis.entity.AdminInfo" id="getAdminInfoMap"> <id property="id" column="id" /> <result property="name" column="name"/> <result property="pwd" column="pwd"/> <association property="ad" javaType="com.lomtom.mybatis.entity.AdminDetail"> <id property="id" column="id"/> <result property="address" column="address"/> <result property="realName" column="realName"/> </association> </resultMap> <select id="getAdminInfo2" parameterType="int" resultMap="getAdminInfo2Map"> select * from admin_info where id=#{id} </select> <select id="getAdminDetail" parameterType="int" resultType="AdminDetail"> select * from admin_detail where id=#{id} </select> <resultMap type="AdminInfo" id="getAdminInfo2Map"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="pwd" column="pwd"/> <association property="ad" column="id" select="getAdminDetail"/> </resultMap> </mapper>
其中,插入keyProperty="id" useGeneratedKeys="true"
实现自增,以上有两种查询方式分别为嵌套查询与嵌套结果
在XML配置文件mybatis-config.xml
中注册adminDetailMapper.xml
和adminInfoMapper.xml。
<mappers> <mapper resource="com/lomtom/mybatis/mapper/adminDetailMapper.xml"/> <mapper resource="com/lomtom/mybatis/mapper/adminInfoMapper.xml"/> </mappers>
创建两个表admin_detail和admin_info,注意两个表之间的依赖关系,可以先创建好两个表,在关联两个表
1、admin_detail SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for admin_detail -- ---------------------------- DROP TABLE IF EXISTS `admin_detail`; CREATE TABLE `admin_detail` ( `id` int(0) NOT NULL AUTO_INCREMENT, `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, `realName` 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、admin_info SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for admin_info -- ---------------------------- DROP TABLE IF EXISTS `admin_info`; CREATE TABLE `admin_info` ( `id` int(0) NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, `pwd` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE, CONSTRAINT `admin_info_ibfk_1` FOREIGN KEY (`id`) REFERENCES `admin_detail` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1;
在测试类里加入以下,用于测试我们刚刚写的插入与查询
@Test public void testAddAdminInfo() { SqlSession sqlSession= MybatisUtils.getSession(); //创建 AdminDetail对象 AdminDetail adminDetail = new AdminDetail("湖南长沙", "杨二蛋子"); //创建 AdminInfo对象 AdminInfo adminInfo = new AdminInfo("杨二蛋子", "123456"); //向数据表 admin_detail插入记录 sqlSession.insert("addAdminDetail", adminDetail); //设置 AdminInfo对象关联的 AdminDetail对象 adminInfo.setAd(adminDetail); //向数据表 admin_info插入记录 sqlSession.insert("addAdminInfo", adminInfo); sqlSession.commit(); sqlSession.close(); } @Test public void testGetAdminInfoById(){ SqlSession sqlSession= MybatisUtils.getSession(); AdminInfo adminInfo = sqlSession.selectOne("getAdminInfo",4); System.out.println(adminInfo); sqlSession.commit(); sqlSession.close(); } @Test public void testGetAdminInfoById2(){ SqlSession sqlSession= MybatisUtils.getSession(); AdminInfo adminInfo = sqlSession.selectOne("getAdminInfo2",4); System.out.println(adminInfo); 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
创造空的构造函数
关注公众号:博奥思园 ,精彩内容不错失
你的支持是作者最大的动力