目录
拥有Mybatis框架结构

准备相应的结构
我们以bill表和provider表为例
在com.hz.pojo创建相应的实体类
User类:
java
import java.math.BigDecimal;
import java.util.Date;
@Data
@ToString
public class Bill {
private Integer id;
private String billCode;
private String productName;
private String productDesc;
private String productUnit;
private BigDecimal productCount;
private BigDecimal totalPrice;
private Integer isPayment;
private Integer providerId;
private Integer createdBy;
private Date creationDate;
private Integer modifyBy;
private Date modifyDate;
}
Provider类:
java
package com.hz.pojo;
import lombok.Data;
import lombok.ToString;
import java.util.List;
@Data
@ToString
public class Provider {
private Integer id; // 主键ID
private String proCode;//供应商编码
private String proName;//供应商名称
private String proDesc;//供应商描述
private String proContact;//供应商联系人
private String proPhone;//供应商电话
private String proAddress;//供应商地址
private String proFax;//供应商传真
private Integer createdBy;//创建者
private String creationDate;//创建时间
private Integer modifyBy;//修改者
private String modifyDate;//修改时间
}
在com.hz.dao下建立相应的BillDao接口类和ProviderDao接口类
在resource.mappers建立相应的BillDao.xml 和ProviderDao.xml文件
在mybatis-config.xml里面的扫描相应的xml文件
一对一
表连接,Bill表为主表,provider表为子表
Bill表的providerId对应Provider表id
BillDao接口类:
public List<Bill> findBillList();
Bill类中添加相关子类provider的属性
private Integer providerId;
BillDao.xml:
java
<!-- 一对一 -->
<select id="findBillList" resultMap="resultBill">
select a.id,a.billCode,a.productName,a.productDesc,a.creationDate,b.id as bid,b.proCode ,b.proName
from smbms_bill a
left join smbms_provider b on a.providerId=b.id
</select>
<resultMap id="resultBill" type="Bill">
<id property="id" column="id"/>
<!-- property里面的是Bill类的 column里面是sql语句的 -->
<result property="billCode" column="billCode"/>
<result property="productName" column="productName"/>
<result property="productDesc" column="productDesc"/>
<result property="creationDate" column="creationDate"/>
<!-- property是当前对象(通常是主表对应的实体类)中用来关联另一个对象(外键关系)的属性
javaType是property对象的类型 -->
<association property="provider" javaType="Provider" > <!-- resultMap="resultProvider" 可用于重复使用-->
<id property="id" column="bid"/>
<result property="proCode" column="proCode"/>
<result property="proName" column="proName"/>
</association>
</resultMap>
测试代码:
java
@Test
public void findBillList() {
//读取mybatis主配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//获得sqlSession工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//通过sqlSessionFactory获得数据库连接对象SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession(true);//默认true 自动提交
//获得dao实例
BillDao billDao = sqlSession.getMapper(BillDao.class);
List<Bill> list = billDao.findBillList();
list.forEach(s ->{
System.out.println(s.toString());
});
}
一对多
表连接,provider表为主表,Bill表为子表
Provider表id对应Bill表的多个providerId
ProviderDao接口类:
public List<Provider> findProviderBillList( );
provider类中添加相关子类Bill的属性(一个provider数据对应多个bill数据,故bill为List):
private List<Bill> billList;
ProviderDao.xml:
java
<select id="findProviderBillList" resultMap="ResultProviderBill">
select a.id,a.proCode,a.proName,b.id as bid,b.billCode ,b.productName
from smbms_provider a
left join smbms_bill b on a.id=b.providerId
</select>
<resultMap id="ResultProviderBill" type="Provider">
<id property="id" column="id"/>
<result property="proCode" column="proCode"/>
<result property="proName" column="proName"/>
<!-- 一对多 -->
<!-- property里面是Provider类中一对多设置的集合billList
ofType是property里面属性的类型 -->
<collection property="billList" ofType="Bill">
<id property="id" column="bid"/>
<result property="billCode" column="billCode"/>
<result property="productName" column="productName"/>
</collection>
</resultMap>
测试代码:
java
@Test
public void findProviderBillList(){
//读取mybatis主配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//获得sqlSession工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//通过sqlSessionFactory获得数据库连接对象SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession(true);//默认true 自动提交
//获得dao实例
ProviderDao providerDao = sqlSession.getMapper(ProviderDao.class);
List<Provider> list = providerDao.findProviderBillList();
list.forEach(s ->{
System.out.println(s.toString());
s.getBillList().forEach(b ->{
System.out.println(b.toString());
});
});
}
resultMap和resultType
在xml文件中的sql语句中有resultMap和resultType两种选择,接下来我们将介绍两种的特点和不同。
resultType
定义:
resultType
是一个简单的配置项,用于指定查询结果直接映射到的 Java 类的全限定名(或别名) 。MyBatis 会 自动将查询结果的列名与 Java 对象的属性名进行匹配(要求列名和属性名一致,或者通过开启驼峰命名等配置进行自动转换)。
特点:
-
适用于 简单的POJO对象映射 ,即数据库字段名与Java对象的属性名完全一致或可通过配置匹配。
-
不能处理复杂的映射关系,比如:
-
数据库字段名与Java属性名不一致(除非开启驼峰命名等自动映射)
-
一对一、一对多等关联查询的复杂对象组装
-
需要自定义类型处理的情况
-
resultMap
定义:
resultMap
是 MyBatis 提供的一种 更加强大、灵活的映射机制 ,允许开发者 手动指定数据库的列与 Java 对象的属性之间的映射关系,支持复杂的映射,例如:
-
列名与属性名不一致时进行显式映射
-
嵌套结果映射(一对一、一对多关联)
-
构造方法映射
-
自动类型处理器、鉴别器(discriminator)等高级功能
特点:
-
更加灵活,适合 复杂查询和对象关系映射
-
可读性更高,特别是对于复杂SQL结果映射
-
需要在XML中预先定义
<resultMap>
,然后在查询中引用它
对比总结
对比维度 | resultType | resultMap |
---|---|---|
映射方式 | 自动映射(根据列名与属性名匹配) | 手动指定列与属性的映射关系 |
灵活性 | 低,适用于简单对象 | 高,适用于复杂对象和关联查询 |
列名与属性名 | 必须一致(或通过配置如驼峰命名自动转换) | 可以不一致,可手动指定 <result> 或 <id> |
支持复杂映射 | 不支持(如一对一、一对多) | 支持(通过 association、collection 等标签) |
使用场景 | 简单查询,字段与属性名一致 | 复杂查询,字段与属性名不一致,有关联对象等 |
是否需要定义 | 否,直接写类全名 | 是,需要先定义 <resultMap> ,再引用 |
使用情景
-
使用 resultType 的情况:
-
查询返回的是简单对象(如单个POJO)
-
数据库的列名与Java对象的属性名完全一致,或可通过配置(如驼峰命名)自动匹配
-
不需要处理复杂的对象关联(如一对一、一对多)
-
-
使用 resultMap 的情况:
-
数据库字段名与Java属性名不一致,且你不想或不能修改SQL或字段名
-
查询涉及 复杂的对象关系(如一个用户有多个订单,或者包含部门信息等)
-
你希望更 精确地控制映射逻辑
-
你可能需要用到 MyBatis 的一些高级特性(如鉴别器、构造器映射等)
-