各地网站备案,seo岗位,网页设计基础试题及答案,wordpress分类没有文章本章概要
多表映射概念对一映射对多映射多表映射总结 多表映射优化多表映射总结
3.1 多表映射概念
多表查询结果映射思路 开发中有很多** 多表查询**需求#xff0c;这种情况如何让进行处理#xff1f; MyBatis 思想是#xff1a;数据库不可能永远是你所想或所需的那个样…本章概要
多表映射概念对一映射对多映射多表映射总结 多表映射优化多表映射总结
3.1 多表映射概念
多表查询结果映射思路 开发中有很多** 多表查询**需求这种情况如何让进行处理 MyBatis 思想是数据库不可能永远是你所想或所需的那个样子。 我们希望每个数据库都具备良好的第三范式或 BCNF 范式可惜它们并不都是那样。 如果能有一种数据库映射模式完美适配所有的应用程序查询需求那就太好了而 ResultMap 就是 MyBatis 就是完美答案。 官方例子如何映射下面这个语句 !-- 非常复杂的语句 --
select idselectBlogDetails resultMapdetailedBlogResultMapselectB.id as blog_id,B.title as blog_title,B.author_id as blog_author_id,A.id as author_id,A.username as author_username,A.password as author_password,A.email as author_email,A.bio as author_bio,A.favourite_section as author_favourite_section,P.id as post_id,P.blog_id as post_blog_id,P.author_id as post_author_id,P.created_on as post_created_on,P.section as post_section,P.subject as post_subject,P.draft as draft,P.body as post_body,C.id as comment_id,C.post_id as comment_post_id,C.name as comment_name,C.comment as comment_text,T.id as tag_id,T.name as tag_namefrom Blog Bleft outer join Author A on B.author_id A.idleft outer join Post P on B.id P.blog_idleft outer join Comment C on P.id C.post_idleft outer join Post_Tag PT on PT.post_id P.idleft outer join Tag T on PT.tag_id T.idwhere B.id #{id}
/select你可能想把它映射到一个智能的对象模型这个对象表示了一篇博客它由某位作者所写有很多的博文每篇博文有零或多条的评论和标签。 我们先来看看下面这个完整的例子它是一个非常复杂的结果映射假设作者博客博文评论和标签都是类型别名。 虽然它看起来令人望而生畏但其实非常简单。 !-- 非常复杂的结果映射 --
resultMap iddetailedBlogResultMap typeBlogconstructoridArg columnblog_id javaTypeint//constructorresult propertytitle columnblog_title/association propertyauthor javaTypeAuthorid propertyid columnauthor_id/result propertyusername columnauthor_username/result propertypassword columnauthor_password/result propertyemail columnauthor_email/result propertybio columnauthor_bio/result propertyfavouriteSection columnauthor_favourite_section//associationcollection propertyposts ofTypePostid propertyid columnpost_id/result propertysubject columnpost_subject/association propertyauthor javaTypeAuthor/collection propertycomments ofTypeCommentid propertyid columncomment_id//collectioncollection propertytags ofTypeTag id propertyid columntag_id//collection/collection
/resultMap现在可能看不懂接下来要学习将多表查询结果使用ResultMap标签映射到实体类对象上 学习目标
多表查询语句使用多表结果承接实体类设计使用ResultMap完成多表结果映射
实体类设计方案
多表关系回顾双向查看
一对一 夫妻关系人和身份证号 一对多| 多对一 用户和用户的订单锁和钥匙 多对多 老师和学生部门和员工 实体类设计关系(查询)单向查看 对一 夫妻一方对应另一方订单对应用户都是对一关系 实体类设计对一关系下类中只要包含单个对方对象类型属性即可 例如 public class Customer {private Integer customerId;private String customerName;}public class Order {private Integer orderId;private String orderName;private Customer customer;// 体现的是对一的关系}对多: 用户对应的订单讲师对应的学生或者学生对应的讲师都是对多关系 实体类设计 对多关系下类中只要包含对方类型集合属性即可 public class Customer {private Integer customerId;private String customerName;private ListOrder orderList;// 体现的是对多的关系
}public class Order {private Integer orderId;private String orderName;private Customer customer;// 体现的是对一的关系}//查询客户和客户对应的订单集合 不要管!多表结果实体类设计小技巧
对一属性中包含对方对象对多属性中包含对方对象集合 只有真实发生多表查询时才需要设计和修改实体类否则不提前设计和修改实体类 无论多少张表联查实体类设计都是两两考虑 在查询映射的时候只需要关注本次查询相关的属性例如查询订单和对应的客户就不要关注客户中的订单集合 多表映射案例准备 数据库 CREATE TABLE t_customer (customer_id INT NOT NULL AUTO_INCREMENT, customer_name CHAR(100), PRIMARY KEY (customer_id) );CREATE TABLE t_order ( order_id INT NOT NULL AUTO_INCREMENT, order_name CHAR(100), customer_id INT, PRIMARY KEY (order_id) ); INSERT INTO t_customer (customer_name) VALUES (c01);INSERT INTO t_order (order_name, customer_id) VALUES (o1, 1);
INSERT INTO t_order (order_name, customer_id) VALUES (o2, 1);
INSERT INTO t_order (order_name, customer_id) VALUES (o3, 1);实际开发时一般在开发过程中不给数据库表设置外键约束。 原因是避免调试不方便。 一般是功能开发完成再加外键约束检查是否有bug。 实体类设计 稍后会进行订单关联客户查询也会进行客户关联订单查询所以在这先练习设计 Data
public class Customer {private Integer customerId;private String customerName;private ListOrder orderList;// 体现的是对多的关系}
Data
public class Order {private Integer orderId;private String orderName;private Customer customer;// 体现的是对一的关系}相关依赖 dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.28/version
/dependency3.2 对一映射
需求说明
根据ID查询订单以及订单关联的用户的信息
OrderMapper接口
public interface OrderMapper {Order selectOrderWithCustomer(Integer orderId);
}OrderMapper.xml 配置文件
!-- 创建resultMap实现“对一”关联关系映射 --
!-- id属性通常设置为这个resultMap所服务的那条SQL语句的id加上“ResultMap” --
!-- type属性要设置为这个resultMap所服务的那条SQL语句最终要返回的类型 --
resultMap idselectOrderWithCustomerResultMap typeorder!-- 先设置Order自身属性和字段的对应关系 --id columnorder_id propertyorderId/result columnorder_name propertyorderName/!-- 使用association标签配置“对一”关联关系 --!-- property属性在Order类中对一的一端进行引用时使用的属性名 --!-- javaType属性一的一端类的全类名 --association propertycustomer javaTypecustomer!-- 配置Customer类的属性和字段名之间的对应关系 --id columncustomer_id propertycustomerId/result columncustomer_name propertycustomerName//association/resultMap!-- Order selectOrderWithCustomer(Integer orderId); --
select idselectOrderWithCustomer resultMapselectOrderWithCustomerResultMapSELECT order_id,order_name,c.customer_id,customer_nameFROM t_order oLEFT JOIN t_customer cON o.customer_idc.customer_idWHERE o.order_id#{orderId}/select对应关系可以参考下图 Mybatis全局注册mybatis-config.xml文件
?xml version1.0 encodingUTF-8 ?
!DOCTYPE configurationPUBLIC -//mybatis.org//DTD Config 3.0//ENhttp://mybatis.org/dtd/mybatis-3-config.dtd
configurationsettings!-- 开启驼峰式映射--setting namemapUnderscoreToCamelCase valuetrue/!-- 开启logback日志输出--
!-- setting namelogImpl valueSLF4J/--/settingstypeAliases!-- 给实体类起别名 --package namecom.atguigu.entity//typeAliases!-- environments表示配置Mybatis的开发环境可以配置多个环境在众多具体环境中使用default属性指定实际运行时使用的环境。default属性的取值是environment标签的id属性的值。 --environments defaultdevelopment!-- environment表示配置Mybatis的一个具体的环境 --environment iddevelopment!-- Mybatis的内置的事务管理器 --transactionManager typeJDBC/!-- 配置数据源 --dataSource typePOOLED!-- 建立数据库连接的具体信息 --property namedriver valuecom.mysql.cj.jdbc.Driver/property nameurl valuejdbc:mysql://localhost:3306/mybatis-example/property nameusername valueroot/property namepassword valueroot//dataSource/environment/environmentsmappers!-- Mapper注册指定Mybatis映射文件的具体位置 --!-- mapper标签配置一个具体的Mapper映射文件 --!-- resource属性指定Mapper映射文件的实际存储位置这里需要使用一个以类路径根目录为基准的相对路径 --!-- 对Maven工程的目录结构来说resources目录下的内容会直接放入类路径所以这里我们可以以resources目录为基准 --mapper resourcemappers/OrderMapper.xml//mappers/configurationjunit测试程序
public class MyBatisTest {private SqlSession session;// junit会在每一个Test方法前执行BeforeEach方法BeforeEachpublic void init() throws IOException {session new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream(mybatis-config.xml)).openSession();}Testpublic void testRelationshipToOne() {OrderMapper orderMapper session.getMapper(OrderMapper.class);// 查询Order对象检查是否同时查询了关联的Customer对象Order order orderMapper.selectOrderWithCustomer(2);System.out.println(order);}// junit会在每一个Test方法后执行AfterEach方法AfterEachpublic void clear() {session.commit();session.close();}
}关键词
在“对一”关联关系中配置比较多但是关键词就只有association和javaType
3.3 对多映射
需求说明
查询客户和客户关联的订单信息
CustomerMapper接口
public interface CustomerMapper {Customer selectCustomerWithOrderList(Integer customerId);}CustomerMapper.xml文件
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttps://mybatis.org/dtd/mybatis-3-mapper.dtd
!-- namespace等于mapper接口类的全限定名,这样实现对应 --
mapper namespacecom.atguigu.mapper.CustomerMapper!-- 配置resultMap实现从Customer到OrderList的“对多”关联关系 --resultMap idselectCustomerWithOrderListResultMap typecustomer!-- 映射Customer本身的属性 --id columncustomer_id propertycustomerId/result columncustomer_name propertycustomerName/!-- collection标签映射“对多”的关联关系 --!-- property属性在Customer类中关联“多”的一端的属性名 --!-- ofType属性集合属性中元素的类型 --collection propertyorderList ofTypeorder!-- 映射Order的属性 --id columnorder_id propertyorderId/result columnorder_name propertyorderName//collection/resultMap!-- Customer selectCustomerWithOrderList(Integer customerId); --select idselectCustomerWithOrderList resultMapselectCustomerWithOrderListResultMapSELECT c.customer_id,c.customer_name,o.order_id,o.order_nameFROM t_customer cLEFT JOIN t_order oON c.customer_ido.customer_idWHERE c.customer_id#{customerId}/select
/mapper对应关系可以参考下图 Mybatis全局注册mybatis-config.xml文件
?xml version1.0 encodingUTF-8 ?
!DOCTYPE configurationPUBLIC -//mybatis.org//DTD Config 3.0//ENhttp://mybatis.org/dtd/mybatis-3-config.dtd
configurationsettings!-- 开启驼峰式映射--setting namemapUnderscoreToCamelCase valuetrue/!-- 开启logback日志输出--!-- setting namelogImpl valueSLF4J/--/settingstypeAliases!-- 给实体类起别名 --package namecom.atguigu.entity//typeAliases!-- environments表示配置Mybatis的开发环境可以配置多个环境在众多具体环境中使用default属性指定实际运行时使用的环境。default属性的取值是environment标签的id属性的值。 --environments defaultdevelopment!-- environment表示配置Mybatis的一个具体的环境 --environment iddevelopment!-- Mybatis的内置的事务管理器 --transactionManager typeJDBC/!-- 配置数据源 --dataSource typePOOLED!-- 建立数据库连接的具体信息 --property namedriver valuecom.mysql.cj.jdbc.Driver/property nameurl valuejdbc:mysql://localhost:3306/mybatis-example/property nameusername valueroot/property namepassword valueroot//dataSource/environment/environmentsmappers!-- Mapper注册指定Mybatis映射文件的具体位置 --!-- mapper标签配置一个具体的Mapper映射文件 --!-- resource属性指定Mapper映射文件的实际存储位置这里需要使用一个以类路径根目录为基准的相对路径 --!-- 对Maven工程的目录结构来说resources目录下的内容会直接放入类路径所以这里我们可以以resources目录为基准 --mapper resourcemappers/OrderMapper.xml/mapper resourcemappers/CustomerMapper.xml//mappers/configurationjunit测试程序
Test
public void testRelationshipToMulti() {CustomerMapper customerMapper session.getMapper(CustomerMapper.class);// 查询Customer对象同时将关联的Order集合查询出来Customer customer customerMapper.selectCustomerWithOrderList(1);System.out.println(customer.getCustomerId() customer.getCustomerId());System.out.println(customer.getCustomerName() customer.getCustomerName());ListOrder orderList customer.getOrderList();for (Order order : orderList) {System.out.println(order order);}
}关键词
在“对多”关联关系中同样有很多配置但是提炼出来最关键的就是“collection”和“ofType”
3.4 多表映射总结
3.4.1 多表映射优化
setting属性属性含义可选值默认值autoMappingBehavior指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示关闭自动映射PARTIAL 只会自动映射没有定义嵌套结果映射的字段。 FULL 会自动映射任何复杂的结果集无论是否嵌套。NONE, PARTIAL, FULLPARTIAL
我们可以将autoMappingBehavior设置为full进行多表resultMap映射的时候可以省略符合列和属性命名映射规则列名属性名或者开启驼峰映射也可以自定映射的result标签 修改mybati-sconfig.xml !--开启resultMap自动映射 --
setting nameautoMappingBehavior valueFULL/修改CustomerMapper.xml resultMap idcustomerMap typecustomerid propertycustomerId columncustomer_id /!-- 开启自动映射,并且开启驼峰式支持!可以省略 result!--!-- result propertycustomerName columncustomer_name /--collection propertyorderList ofTypeorder id propertyorderId columnorder_id /!-- result propertyorderName columnorder_name /--/collection
/resultMap
select idselectCustomerWithOrderList resultMapcustomerMapSELECT c.customer_id,c.customer_name,o.order_id,o.order_nameFROM t_customer cLEFT JOIN t_order oON c.customer_ido.customer_idWHERE c.customer_id#{customerId}
/select测试 Testpublic void testRelationshipToMulti() {CustomerMapper customerMapper session.getMapper(CustomerMapper.class);// 查询Customer对象同时将关联的Order集合查询出来Customer customer customerMapper.selectCustomerWithOrderList(1);System.out.println(customer.getCustomerId() customer.getCustomerId());System.out.println(customer.getCustomerName() customer.getCustomerName());ListOrder orderList customer.getOrderList();for (Order order : orderList) {System.out.println(order order);}}3.4.2 多表映射总结
关联关系配置项关键词所在配置文件和具体位置对一association标签、javaType属性、property属性Mapper配置文件中的resultMap标签内对多collection标签、ofType属性、property属性Mapper配置文件中的resultMap标签内