【mybatis学习记录】mybatis的各种查询 一对一关联查询(4种方式) 一对多(2种方式)
文章目錄
- 一對一
- 方式一:
- 方式2
- 方式3
- 方式4
- 一對多查詢(2種方式)
- 方式2
一對一
如:通過訂單id查詢訂單的時候,將訂單關聯的用戶信息也返回。
首先建庫建表:
新建實體類:
mybatis全局配置:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration><properties><property name="jdbc.driver" value="com.mysql.cj.jdbc.Driver"/><property name="jdbc.url"value="jdbc:mysql://localhost:3308/data1?characterEncoding=UTF-8"/><property name="jdbc.username" value="heziyi"/><property name="jdbc.password" value="123456"/></properties><!-- 環境配置,可以配置多個環境 --><environments default="test"><!--environment用來對某個環境進行配置id:環境標識,唯一--><environment id="test"><!-- 事務管理器工廠配置 --><transactionManager type="JDBC"/><!-- 數據源工廠配置,使用工廠來創建數據源 --><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments><mappers><package name="com.example.demomybatis.mapper"/></mappers> </configuration>pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.1</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>demomybatis</artifactId><version>0.0.1-SNAPSHOT</version><name>demomybatis</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.0</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins><resources><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes><filtering>false</filtering></resource></resources></build> </project>方式一:
@Mapper public interface OrderMapper {OrderModel getById(int id);OrderModel getById1(int id); }OrderMapper.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.demomybatis.mapper.OrderMapper"> <select id="getById"resultType="com.example.demomybatis.model.OrderModel"><![CDATA[ SELECT a.id,a.user_id as userId,a.create_time createTime,a.up_time upTime FROM t_order a WHERE a.id = #{value} ]]> </select><resultMap id="orderModelMap1"type="com.example.demomybatis.model.OrderModel"><id column="id" property="id" /><result column="user_id" property="userId"/><result column="create_time" property="createTime"/><result column="up_time" property="upTime"/><result column="user_id" property="userModel.id"/><result column="name" property="userModel.name"/></resultMap><select id="getById1" resultMap="orderModelMap1"> <![CDATA[SELECTa.id,a.user_id,a.create_time,a.up_time,b.name,b.sex,b.salary,b.ageFROMt_order a,t_user bWHEREa.user_id = b.idAND a.id = #{value}]]> </select> </mapper>運行啟動類:
@Slf4j public class Demo3Test {private SqlSessionFactory sqlSessionFactory;@Beforepublic void before() throws IOException { //指定mybatis全局配置文件String resource = "mybatis-config.xml"; //讀取全局配置文件InputStream inputStream =Resources.getResourceAsStream(resource); //構建SqlSessionFactory對象SqlSessionFactory sqlSessionFactory = newSqlSessionFactoryBuilder().build(inputStream);this.sqlSessionFactory = sqlSessionFactory;}@Testpublic void test() {try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) {OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);OrderModel orderModel = mapper.getById1(1);log.info("{}", orderModel);}} }結果:
方式2
方式2
這次我們需要使用mapper xml中另外一個元素association ,這個元素可以配置關聯對象的映射關系
添加接口:
OrderModel getById2(int id);測試類修改:
OrderModel orderModel = mapper.getById2(1);運行:
方式3
先按照訂單id查詢訂單數據,然后在通過訂單中user_id 去用戶表查詢用戶數據,通過兩次查詢,組合成目標結果,mybatis已經內置了這種操作
我們先定義一個通過用戶id查詢用戶信息的select元素,如下
OrderMapper.xml
<mapper namespace="com.example.demomybatis.mapper.OrderMapper"><resultMap id="orderModelMap3"type="com.example.demomybatis.model.OrderModel"><id column="id" property="id" /><result column="user_id" property="userId"/><result column="create_time" property="createTime"/><result column="up_time" property="upTime"/><association property="userModel"select="com.example.demomybatis.mapper.UserMapper.getById"column="user_id" /></resultMap><select id="getById3" resultMap="orderModelMap3"> <![CDATA[SELECTa.id,a.user_id,a.create_time,a.up_timeFROMt_order aWHEREa.id = #{value}]]> </select> </mapper>運行:
方式4
方式3中給第二個查詢傳遞了一個參數,如果需要給第二個查詢傳遞多個參數怎么辦呢?可以這么寫
<association property="屬性" select="查詢對應的select的id" column="{key1=父查詢字段 1,key2=父查詢字段2,key3=父查詢字段3}" />這種相當于給子查詢傳遞了一個map,子查詢中 需要用過map的key獲取對應的條件,:
OrderMapper.xml:
<resultMap id="orderModelMap4"type="com.example.demomybatis.model.OrderModel"><!-- property:主鍵在pojo中的屬性名 --><!-- column:主鍵在數據庫中的列名 --><id column="id" property="id" /><result column="user_id" property="userId"/><result column="create_time" property="createTime"/><result column="up_time" property="upTime"/><association property="userModel"select="com.example.demomybatis.mapper.UserMapper.getById1" column=" {uid1=user_id,uid2=create_time}" /></resultMap><select id="getById4" resultMap="orderModelMap4"> <![CDATA[SELECTa.id,a.user_id,a.create_time,a.up_timeFROMt_order aWHEREa.id = #{value}]]> </select> OrderModel getById4(int id);UserMapper.xml
<select id="getById1"resultType="com.example.demomybatis.model.UserModel"> <![CDATA[SELECT id,name FROM t_user where id = #{uid1} and id = #{uid2}]]> </select> UserModel getById1(int id);結果:
傳過來的是第一個查詢的user_id和create_time
關于resultmap resulttype:
resultType可以把查詢結果封裝到pojo類型中,但必須pojo類的屬性名和查詢到的數據庫表的字段名一致。
如果sql查詢到的字段與pojo的屬性名不一致,則需要使用resultMap將字段名和屬性名對應起來,進行手動配置封裝,將結果映射到pojo中
一對多查詢(2種方式)
根據訂單id查詢出訂單信息,并且查詢出訂單明細列表。
一對多關系:collection標簽
這個sql中使用到了t_order和t_order_detail 連接查詢,這個查詢會返回多條結果,但是最后結果按照orderModelMap1 進行映射,最后只會返回一個OrderModel 對象,關鍵在于collection 元素,這個元素用來定義集合中元素的映射關系,有2個屬性需要注意
property:對應的屬性名稱
ofType:集合中元素的類型,此處是OrderDetailModel
注意這個:
查詢出來的結果會按照這個配置中指定的column 進行分組,即按照訂單id 進行分組,每個訂單對應多個訂單明細,訂單明細會按照collection 的配置映射為ofType元素指定的對象。
實際resultMap元素中的id元素可以使用result 元素代替,只是用id 可以提升性能,mybatis可以通過id元素配置的列的值判斷唯一一條記錄,如果我們使用result 元素,那么判斷是否是同一條記錄的時候,需要通過所有列去判斷了,所以通過id 可以提升性能,使用id元素在一對多中可以提升性能,在單表查詢中使用id元素還是result元素,性能都是一樣的。
結果:
20:13:12.153 [main] DEBUG
com.example.demomybatis.mapper.OrderMapper.getById1 - ==> Preparing:
SELECT a.id , a.user_id, a.create_time, a.up_time, b.id orderDetailId,
b.order_id, b.goods_id, b.num, b.total_price FROM t_order a,
t_order_detail b WHERE a.id = b.order_id AND a.id = ? 20:13:12.181
[main] DEBUG com.example.demomybatis.mapper.OrderMapper.getById1 - >
Parameters: 1(Integer) 20:13:12.205 [main] DEBUG
com.example.demomybatis.mapper.OrderMapper.getById1 - < Total:
2 20:13:12.205 [main] INFO com.example.demomybatis.Demo3Test -
OrderModel(id=1, userId=1, createTime=1624088102, upTime=1624088102,
userModel=null, orderDetailModelList=[OrderDetailModel(id=1,
goodsId=1, num=2, orderId=1, totalPrice=17.76), OrderDetailModel(id=2,
goodsId=1, num=1, orderId=1, totalPrice=16.66)])
方式2
通過2次查詢,然后對結果進行分裝,先通過訂單id查詢訂單信息,然后通過訂單id查詢訂單明細列表,
然后封裝結果。mybatis中默認支持這樣,還是通過collection 元素來實現的。
OrderDetailMapper.xml
Ordermapper.xml
<resultMap id="orderModelMap2"type="com.example.demomybatis.model.OrderModel"><id column="id" property="id"/><result column="user_id" property="userId"/><result column="create_time" property="createTime"/><result column="up_time" property="upTime"/><collection property="orderDetailModelList"select="com.example.demomybatis.mapper.OrderDetailMapper.getListByOrderId1 " column="id"/></resultMap><select id="getById2" resultMap="orderModelMap2"> <![CDATA[SELECTa.id ,a.user_id,a.create_time,a.up_timeFROMt_order aWHEREa.id = #{value}]]> </select>重點:
<collection property="orderDetailModelList"select="com.example.demomybatis.mapper.OrderDetailMapper.getListByOrderId1 " column="id"/>表示orderDetailModelList 屬性的值通過select 屬性指定的查詢獲取,查詢參數是通過column 屬性指定的,此處使用getById2 sql中的id 作為條件,即訂單id
總結
以上是生活随笔為你收集整理的【mybatis学习记录】mybatis的各种查询 一对一关联查询(4种方式) 一对多(2种方式)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【问题记录】进行mybatis实例查询测
- 下一篇: 【算法学习笔记】堆排序和归并排序、其他几