目录
一、一对一映射(One-to-One)
1.1 表关系
1.2 resultMap设置自定义映射
二、一对多映射(One-to-Many)
2.1 创建实体
2.2 级联方式处理映射关系
2.3 定义SQL
2.4 OrderMapper接口
2.5 编写业务逻辑层
2.6 Junit测试
三、多对多映射(Many-to-Many)
3.1 表关系
3.2 创建实体
3.3 处理映射关系、定义sql
3.4 HBookMapper 接口
3.5 编写业务逻辑层
3.6 Junit测试
一、一对一映射(One-to-One)
1.1 表关系
一对一映射是指一个对象与另一个对象具有一对一的关系。例如,一个用户(User)与一个地址(Address)之间的关系。假设我们有以下表结构:
user 表:
id (int)
name (varchar)
address_id (int)
address 表:
id (int)
street (varchar)
city (varchar)
首先,创建 User 和 Address 实体类:
User.java
public class User {private int id;private String name;private Address address;// getters and setters
}
Address.java
public class Address {private int id;private String street;private String city;// getters and setters
}
接下来,创建一个 resultMap 进行一对一映射:
1.2 resultMap设置自定义映射
UserMapper.xml
<resultMap id="UserAddressResultMap" type="User"><id property="id" column="id"/><result property="name" column="name"/>//一对一关系使用association<association property="address" javaType="Address"><id property="id" column="address_id"/><result property="street" column="street"/><result property="city" column="city"/></association>
</resultMap>
属性:
- id:表示自定义映射的唯一标识
- type:查询的数据要映射的实体类的类型
子标签:
- id:设置主键的映射关系
- result:设置普通字段的映射关系
- association :设置多对一的映射关系
- collection:设置一对多的映射关系
子标签属性:
- property:设置映射关系中实体类中的属性名
- column:设置映射关系中表中的字段名
最后,编写一个查询方法来使用这个 resultMap:
UserMapper.xml
<select id="findUserWithAddress" resultMap="UserAddressResultMap">SELECT u.id, u.name, a.id as address_id, a.street, a.cityFROM user uINNER JOIN address a ON u.address_id = a.idWHERE u.id = #{id}
</select>
最后实现接口findUserWithAddress方法测试即可,通过以上简单的案例,我相信你已经明白自定义关系映射了。往往实际开发中数据和表是要复杂的多,进阶用法请看以下示例:
二、一对多映射(One-to-Many)
一对多映射是指一个对象与多个对象具有一对多的关系。例如,一个订单(Oeder)与一个订单详情(OrderItem)之间的关系。假设我们有以下表结构:
2.1 创建实体
利用mybatis逆向工程(generatorConfig.xml)生成模型层代码 :
创建 OrderVo
它是一个值对象(Value Object),继承 Order
类并添加了一个额外的属性 orderItems
。该类用于在应用程序的各个层之间传递数据,尤其是在表示层和业务逻辑层之间。在这个例子中,OrderVo
类用于表示一个订单及其关联的订单项。
package com.ycxw.vo;import com.ycxw.model.Order;
import com.ycxw.model.OrderItem;
import lombok.Data;import java.util.ArrayList;
import java.util.List;/*** @author 云村小威* @site blog.csdn.net/Justw320* @create 2023-08-26 16:30*/
@Data
public class OrderVo extends Order {private List<OrderItem> orderItems = new ArrayList<>();
}
2.2 级联方式处理映射关系
<resultMap id="OrderVoMap" type="com.ycxw.vo.OrderVo"><result column="order_id" property="orderId"></result><result column="order_no" property="orderNo"></result>//多关系使用collection<collection property="orderItems" ofType="com.ycxw.model.OrderItem"><result column="order_item_id" property="orderItemId"></result><result column="product_id" property="productId"></result><result column="quantity" property="quantity"></result><result column="oid" property="oid"></result></collection></resultMap>
2.3 定义SQL
<select id="SelectByOid" resultMap="OrderVoMap" parameterType="java.lang.Integer">SELECT *FROM t_hibernate_order o,t_hibernate_order_item oiWHERE o.order_id = oi.oidAND o.order_id = #{oid}</select>
2.4 OrderMapper接口
package com.ycxw.mapper;import com.ycxw.model.Order;
import com.ycxw.vo.OrderVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;@Repository
public interface OrderMapper {OrderVo SelectByOid(@Param("oid") Integer oid);
}
2.5 编写业务逻辑层
OrderItmeBiz 接口
package com.ycxw.biz;import com.ycxw.vo.OrderItemVo;/*** @author 云村小威* @site blog.csdn.net/Justw320* @create 2023-08-26 21:48*/
public interface OrderItmeBiz {OrderItemVo SelectByOitemId(Integer oiid);
}
OrderBizImpl 接口实现类
package com.ycxw.biz.impl;import com.ycxw.biz.OrderBiz;
import com.ycxw.mapper.OrderMapper;
import com.ycxw.vo.OrderVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** @author 云村小威* @site blog.csdn.net/Justw320* @create 2023-08-26 16:46*/
@Service
public class OrderBizImpl implements OrderBiz {@Autowiredprivate OrderMapper orderMapper;@Overridepublic OrderVo SelectByOid(Integer oid) {return orderMapper.SelectByOid(oid);}
}
2.6 Junit测试
package com.ycxw.biz.impl;import com.ycxw.biz.OrderBiz;
import com.ycxw.vo.OrderVo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;/*** @author 云村小威* @site blog.csdn.net/Justw320* @create 2023-08-26 16:48*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-mybatis.xml"})
public class OrderBizImplTest {@Autowiredprivate OrderBiz orderBiz;@Testpublic void selectByOid() {OrderVo orderVo = orderBiz.SelectByOid(8);//获取订单System.out.println(orderVo);//获取订单项信息orderVo.getOrderItems().forEach(System.out::println);}}
运行结果:
三、多对多映射(Many-to-Many)
3.1 表关系
多对多映射是指多个对象与多个对象具有多对多的关系。表之间的多对多关系稍微复杂,需要一个中间表来表示:
中间表有三个字段,其中两个字段分别作为外键指向各自一方的主键,由此通过中间表来表示多对多关系,通过一个表联合另一个中间表可以表示为一对多关系。
如:根据书籍id查找关联属性类别:
3.2 创建实体
利用mybatis逆向工程(generatorConfig.xml)生成模型层代码 :
创建 HBookVo 值对象(Value Object)
package com.ycxw.vo;import com.ycxw.model.BookCategory;
import com.ycxw.model.HBook;
import lombok.Data;import java.util.List;/*** @author 云村小威* @site blog.csdn.net/Justw320* @create 2023-08-27 21:03*/
@Data
public class HBookVo extends HBook {private List<BookCategory> bookc = new ArrayList<>();
}
3.3 处理映射关系、定义sql
<resultMap id="HBookVoMap" type="com.ycxw.vo.HBookVo" ><result column="book_id" property="bookId"></result><result column="book_name" property="bookName"></result><result column="price" property="price"></result><collection property="bookc" ofType="com.ycxw.model.Category"><result column="category_id" property="categoryId"></result><result column="category_name" property="categoryName"></result></collection></resultMap><!--根据书籍的id查询书籍的信息及所属属性--><select id="selectByBookId" resultMap="HBookVoMap" parameterType="java.lang.Integer">SELECT*FROMt_hibernate_book b,t_hibernate_category c,t_hibernate_book_category bcWHEREb.book_id = bc.bidAND c.category_id = bc.bcidAND b.book_id = #{bid}</select>
3.4 HBookMapper 接口
HBookVo selectByBookId(@Param("bid") Integer bid);
3.5 编写业务逻辑层
HBookBiz 接口
package com.ycxw.biz;import com.ycxw.vo.HBookVo;/*** @author 云村小威* @site blog.csdn.net/Justw320* @create 2023-08-29 12:47*/
public interface HBookBiz {HBookVo selectByBookId(Integer bid);
}
HBookBizImpl 接口实现类
package com.ycxw.biz.impl;import com.ycxw.biz.HBookBiz;
import com.ycxw.mapper.HBookMapper;
import com.ycxw.vo.HBookVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** @author 云村小威* @site blog.csdn.net/Justw320* @create 2023-08-29 12:48*/
@Service
public class HBookBizImpl implements HBookBiz {@Autowiredprivate HBookMapper hBookMapper;@Overridepublic HBookVo selectByBookId(Integer bid) {return hBookMapper.selectByBookId(bid);}
}
3.6 Junit测试
package com.ycxw.biz.impl;import com.ycxw.biz.HBookBiz;
import com.ycxw.vo.HBookVo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;/*** @author 云村小威* @site blog.csdn.net/Justw320* @create 2023-08-26 16:48*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-mybatis.xml"})
public class OrderBizImplTest {@Autowiredprivate HBookBiz hBookBiz;@Testpublic void selectByBookId(){HBookVo hBookVo = hBookBiz.selectByBookId(22);//数据所有信息System.out.println(hBookVo);//书籍有关的类别System.out.println(hBookVo.getBookc());}
}
反之亦然,如:根据类别id查找书籍信息
<resultMap id="CategotyVoMap" type="com.ycxw.vo.CategoryVo"><result column="category_id" property="categoryId"></result><result column="category_name" property="categoryName"></result><collection property="books" ofType="com.ycxw.model.HBook"><result column="book_id" property="bookId"></result><result column="book_name" property="bookName"></result><result column="price" property="price"></result></collection></resultMap><select id="selectCategoryId" resultMap="CategotyVoMap" parameterType="java.lang.Integer">SELECT*FROMt_hibernate_book b,t_hibernate_category c,t_hibernate_book_category bcWHEREb.book_id = bc.bidAND c.category_id = bc.bcidAND c.category_id = #{cid}</select>
测试运行: