public interface OrderMapper {
Order selectOrderWithCustomer(Integer orderId);
}
<resultMap id="selectOrderWithCustomerResultMap" type="order">
<id column="order_id" property="orderId"/>
<result column="order_name" property="orderName"/>
<association property="customer" javaType="customer">
<id column="customer_id" property="customerId"/>
<result column="customer_name" property="customerName"/>
association>
resultMap>
<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>
<mappers>
<mapper resource="mappers/OrderMapper.xml"/>
mappers>
@Slf4j
public class MyBatisTest {
private SqlSession session;
// junit会在每一个@Test方法前执行@BeforeEach方法
@BeforeEach
public void init() throws IOException {
session = new SqlSessionFactoryBuilder()
.build(
Resources.getResourceAsStream("mybatis-config.xml"))
.openSession();
}
@Test
public void testRelationshipToOne() {
OrderMapper orderMapper = session.getMapper(OrderMapper.class);
// 查询Order对象,检查是否同时查询了关联的Customer对象
Order order = orderMapper.selectOrderWithCustomer(2);
log.info("order = " + order);
}
// junit会在每一个@Test方法后执行@@AfterEach方法
@AfterEach
public void clear() {
session.commit();
session.close();
}
}
public interface CustomerMapper {
Customer selectCustomerWithOrderList(Integer customerId);
}
<!-- 配置resultMap实现从Customer到OrderList的“对多”关联关系 -->
<resultMap id="selectCustomerWithOrderListResultMap"
type="customer">
<!-- 映射Customer本身的属性 -->
<id column="customer_id" property="customerId"/>
<result column="customer_name" property="customerName"/>
<!-- collection标签:映射“对多”的关联关系 -->
<!-- property属性:在Customer类中,关联“多”的一端的属性名 -->
<!-- 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>
<mappers>
<mapper resource="mappers/OrderMapper.xml"/>
<mapper resource="mappers/CustomerMapper.xml"/>
mappers>
@Test
public void testRelationshipToMulti() {
CustomerMapper customerMapper = session.getMapper(CustomerMapper.class);
// 查询Customer对象同时将关联的Order集合查询出来
Customer customer = customerMapper.selectCustomerWithOrderList(1);
log.info("customer.getCustomerId() = " + customer.getCustomerId());
log.info("customer.getCustomerName() = " + customer.getCustomerName());
List<Order> orderList = customer.getOrderList();
for (Order order : orderList) {
log.info("order = " + order);
}
}
setting 属性 | 属性含义 | 可选值 | 默认值 |
---|---|---|---|
autoMappingBehavior | 指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示关闭自动映射;PARTIAL 只会自动映射没有定义嵌套结果映射的字段。 FULL 会自动映射任何复杂的结果集(无论是否嵌套)。 | NONE, PARTIAL, FULL | PARTIAL |
我们可以将 autoMappingBehavior 设置为 full,进行多表 resultMap 映射的时候,可以省略符合列和属性命名映射规则(列名=属性名,或者开启驼峰映射也可以自定映射)的 result 标签!
修改 mybatis-sconfig.xml:
<setting name="autoMappingBehavior" value="FULL"/>
<resultMap id="teacherMap" type="teacher">
<id property="tId" column="t_id" />
<collection property="students" ofType="student" >
<id property="sId" column="s_id" />
collection>
resultMap>
关联关系 | 配置项关键词 | 所在配置文件和具体位置 |
---|---|---|
对一 | association 标签/javaType 属性/property 属性 | Mapper 配置文件中的 resultMap 标签内 |
对多 | collection 标签/ofType 属性/property 属性 | Mapper 配置文件中的 resultMap 标签内 |
<select id="selectEmployeeByCondition" resultType="employee">
select emp_id,emp_name,emp_salary from t_emp
<where>
<if test="empName != null">
or emp_name=#{empName}
if>
<if test="empSalary > 2000">
or emp_salary>#{empSalary}
if>
where>
select>
<update id="updateEmployeeDynamic">
update t_emp
<set>
<if test="empName != null">
emp_name=#{empName},
if>
<if test="empSalary < 3000">
emp_salary=#{empSalary},
if>
set>
where emp_id=#{empId}
update>
使用 trim 标签控制条件部分两端是否包含某些字符
<select id="selectEmployeeByConditionByTrim" resultType="com.atguigu.mybatis.entity.Employee">
select emp_id,emp_name,emp_age,emp_salary,emp_gender
from t_emp
<trim prefix="where" suffixOverrides="and|or">
<if test="empName != null">
emp_name=#{empName} and
if>
<if test="empSalary > 3000">
emp_salary>#{empSalary} and
if>
<if test="empAge <= 20">
emp_age=#{empAge} or
if>
<if test="empGender=='male'">
emp_gender=#{empGender}
if>
trim>
select>
在多个分支条件中,仅执行一个。
<select id="selectEmployeeByConditionByChoose" resultType="com.atguigu.mybatis.entity.Employee">
select emp_id,emp_name,emp_salary from t_emp
where
<choose>
<when test="empName != null">emp_name=#{empName}when>
<when test="empSalary < 3000">emp_salary < 3000when>
<otherwise>1=1otherwise>
choose>
select>
<foreach collection="empList" item="emp" separator="," open="values" index="myIndex">
(#{emp.empName},#{myIndex},#{emp.empSalary},#{emp.empGender})
foreach>
alex.dev.url=jdbc:mysql:///mybatis-example?allowMultiQueries=true
<update id="updateEmployeeBatch">
<foreach collection="empList" item="emp" separator=";">
update t_emp set emp_name=#{emp.empName} where emp_id=#{emp.empId}
foreach>
update>
Parameter 'empList' not found. Available parameters are [arg0, collection, list]
<sql id="mySelectSql">
select emp_id,emp_name,emp_age,emp_salary,emp_gender from t_emp
sql>
<include refid="mySelectSql"/>