文章目录
-
- 实体类设计
- 例子
-
- [Order 实体类 及其mapper接口](#Order 实体类 及其mapper接口)
- [Customer 实体类 及其mapper接口](#Customer 实体类 及其mapper接口)
- [OrderMapper.xml 映射文件](#OrderMapper.xml 映射文件)
- [CustomerMapper.xml 映射文件](#CustomerMapper.xml 映射文件)
- mybatis-config.xml
- 测试文件
- [需要的依赖 pom.xml](#需要的依赖 pom.xml)
实体类设计
对一关系
- 对一关系:
类中只要包含单个对方对象类型属性,即可
如:夫妻一方对应另一方,一个订单对应一个用户,都是对一关系
java
public class Customer {
private Integer customerId;
private String customerName;
}
public class Order {
private Integer orderId;
private String orderName;
private Customer customer; "对一关系(一个订单,对应,一个客户)"
}
对多关系
- 对多关系:
类中只要包含对方类型的集合属性,即可
java
public class Customer {
private Integer customerId;
private String customerName;
private List<Order> orderList; "对多关系(一个客户,有,多个订单)"
}
public class Order {
private Integer orderId;
private String orderName;
private Customer customer; "对一关系(一个订单,对应,一个客户)"
}
多表结果实体类,设计小技巧
-
对一,属性中包含
对方对象 -
对多,属性中包含
对方对象的集合 -
无论多少张表联查,实体类设计都是两两考虑!
-
只有真实发生多表查询时,才需要设计和修改实体类,否则,不提前设计和修改实体类!
-
在查询映射的时候,只需要关注本次查询相关的属性!
如:查询订单和对应的客户,就不要关注客户中的订单集合!
例子
Order 实体类 及其mapper接口
java
"Order - 实体类"
package com.english.pojo;
import lombok.Data;
@Data
public class Order {
private Integer orderId;
private String orderName;
private Customer customer; // 对一关系(一个订单,只能对应,一个客户)
}
"Order - mapper接口"
package com.english.mapper;
import com.english.pojo.Order;
public interface OrderMapper {
// 根据ID,查询订单,以及订单关联的用户的信息
Order selectOrderWithCustomer(Integer orderId);
}
Customer 实体类 及其mapper接口
java
"Customer - 实体类"
package com.english.pojo;
import lombok.Data;
import java.util.List;
@Data
public class Customer {
private Integer customerId;
private String customerName;
private List<Order> orderList; // 对多关系(一个客户,有,多个订单)
}
"Customer- mapper接口"
package com.english.mapper;
import com.english.pojo.Customer;
public interface CustomerMapper {
// 查询客户,以及客户关联的订单信息
Customer selectCustomerWithOrderList(Integer customerId);
}
OrderMapper.xml 映射文件
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 声明XML文档类型为mapper,它告诉解析器该文档应该符合 MyBatis 的 mapper DTD -->
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTO Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- mapper:namespace:指定,与之关联的Java接口的权限定符-->
<mapper namespace="com.english.mapper.OrderMapper">
<!-- 创建resultMap实现"对一"关联关系映射 -->
<!-- id: 设置为这个resultMap所服务的那条SQL语句的id加上"ResultMap" -->
<!-- type:设置为这个resultMap所服务的那条SQL语句最终要返回的类型 -->
<resultMap id="selectOrderWithCustomerResultMap" type="order">
<id column="order_id" property="orderId"/>
<result column="order_name" property="orderName"/>
<!-- association标签:配置"对一"关联关系 -->
<!-- property:Order类中的 private Customer customer 这个属性 -->
<!-- javaType:property="customer"是什么类型数据 -->
<association property="customer" javaType="com.english.pojo.Customer">
<!-- <association property="customer" javaType="customer"> -->
<!-- 配置Customer类的属性和字段名之间的对应关系 -->
<id column="customer_id" property="customerId"/>
<result column="customer_name" property="customerName"/>
</association>
</resultMap>
<!-- Order selectOrderWithCustomer(Integer orderId); -->
<select id="selectOrderWithCustomer" resultMap="selectOrderWithCustomerResultMap">
select order_id, order_name, c.customer_id, customer_name
from t_order o
left join t_customer c
on o.customer_id=c.customer_id
where o.order_id=#{orderId}
</select>
</mapper>
CustomerMapper.xml 映射文件
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTO Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.english.mapper.CustomerMapper">
<resultMap id="selectCustomerWithOrderListResultMap" type="customer">
<id column="customer_id" property="customerId"/>
<result column="customer_name" property="customerName"/>
<!-- collection:映射 "对多" 的关联关系 -->
<!-- property:Customer类中的 private List<Order> orderList 这个属性 -->
<!-- ofType:集合中元素的类型 -->
<collection property="orderList" ofType="order">
<!-- 映射 Order类的属性 -->
<id column="order_id" property="orderId"/>
<result column="order_name" property="orderName"/>
</collection>
</resultMap>
<!-- 查询客户,以及客户关联的订单信息 -->
<!-- Customer selectCustomerWithOrderList(Integer customerId); -->
<select id="selectCustomerWithOrderList" resultMap="selectCustomerWithOrderListResultMap">
select c.customer_id, c.customer_name, o.order_id, o.order_name
from t_customer c
left join t_order o
on c.customer_id = o.customer_id
where c.customer_id = #{customerId}
</select>
</mapper>
mybatis-config.xml
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTO Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- 开启mybatis的日志输出,使用system进行控制台输出 -->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!-- 开启,驼峰式自动映射(数据库表中某列是a_col,映射到java中就成了aCol) -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<!-- 方式1:单独定义-->
<!-- <typeAlias type="com.atguigu.pojo.Employee" alias="ergouzi"/> -->
<!-- 方式2:批量将包下的类,给与别名,别名就是类的首字母小写 -->
<package name="com.english.pojo" />
<!-- 在方式2的情况下,如果某个文件需要单独设置别名,将注解@Alias("ergouzi")加到这个类上即可 -->
</typeAliases>
<!-- 配置mybatis的开发环境,使用 default 指定实际运行时使用的环境 -->
<environments default="development">
<environment id="development">
<!-- transactionManager:配置 Mybatis 的 内置事务管理器,type设置为JDBC,表示,使用MyBatis内置的JDBC事务管理器 -->
<transactionManager type="JDBC"></transactionManager>
<!-- dataSource:配置数据源,type属性设置为POOLED,表示使用连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///my_study_db"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- mappers:用于配置Mapper映射文件,这里注册了一个位于mappers目录下的EmployeeMapper.xml文件。-->
<mappers>
<mapper resource="mappers/OrderMapper.xml"/>
<mapper resource="mappers/CustomerMapper.xml"/>
</mappers>
</configuration>
测试文件
java
import com.english.mapper.CustomerMapper;
import com.english.mapper.OrderMapper;
import com.english.pojo.Customer;
import com.english.pojo.Order;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
@Slf4j
public class MyTest {
private SqlSession sqlSession;
// junit 会在每一个 @Test方法 前,执行 @BeforeEach方法
@BeforeEach
public void init() throws IOException {
InputStream ipt = Resources.getResourceAsStream("mybatis-config.xml");
sqlSession = new SqlSessionFactoryBuilder().build(ipt).openSession();
}
@Test
public void test1(){
OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
Order order = orderMapper.selectOrderWithCustomer(2);
log.info("order=" + order);
}
@Test
public void test2(){
CustomerMapper customerMapper = sqlSession.getMapper(CustomerMapper.class);
Customer customer = customerMapper.selectCustomerWithOrderList(1);
log.info("customer - id=" + customer.getCustomerId());
log.info("customer - name=" + customer.getCustomerName());
List<Order> orderList = customer.getOrderList();
for (Order order : orderList) {
log.info("order - =" + order);
}
}
// junit 会在每一个 @Test方法 后,执行 @AfterEach方法
@AfterEach
public void clear(){
sqlSession.commit();
sqlSession.close();
}
}
需要的依赖 pom.xml
xml
<dependencies>
<!-- mybatis依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<!-- 数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--junit5测试-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- SLF4J API(日志门面) -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<!-- 具体日志实现(如 Logback) -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
</dependencies>