一,一对一
一对一映射是指一个对象与另一个对象具有一对一的关系
1.1 表关系
一对一映射是指一个对象与另一个对象具有一对一的关系。例如,一个用户(User)与一个地址(Address)之间的关系。假设我们有以下表结构:
用户表:
id (int)
name (varchar)
address_id (int)
地址表:
id (int)
street (varchar)
city (varchar)
首先,创建 User 和 Address 实体类:
User.class
public class User { private int id; private String name; private Address address; // getters and setters }
Address.class
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.city FROM user u INNER JOIN address a ON u.address_id = a.id WHERE u.id = #{id} </select>
最后实现接口findUserWithAddress方法测试即可,通过以上简单的案例,我相信你已经明白自定义关系映射了。往往实际开发中数据和表是要复杂的多,进阶用法请看以下示例:
二、一对多映射(One-to-Many)
一对多映射是指一个对象与多个对象具有一对多的关系。例如,一个订单(Oeder)与一个订单详情(OrderItem)之间的关系。假设我们有以下表结构:
2.1 创建实体
利用mybatis逆向工程(generatorConfig.xml)生成模型层代码 :
package com.xzs.model; import lombok.ToString; @ToString public class order { private Integer orderId; private String orderNo; public order(Integer orderId, String orderNo) { this.orderId = orderId; this.orderNo = orderNo; } public order() { super(); } public Integer getOrderId() { return orderId; } public void setOrderId(Integer orderId) { this.orderId = orderId; } public String getOrderNo() { return orderNo; } public void setOrderNo(String orderNo) { this.orderNo = orderNo; } }
package com.xzs.model; import lombok.ToString; @ToString public class orderItem { private Integer orderItemId; private Integer productId; private Integer quantity; private Integer oid; public orderItem(Integer orderItemId, Integer productId, Integer quantity, Integer oid) { this.orderItemId = orderItemId; this.productId = productId; this.quantity = quantity; this.oid = oid; } public orderItem() { super(); } public Integer getOrderItemId() { return orderItemId; } public void setOrderItemId(Integer orderItemId) { this.orderItemId = orderItemId; } public Integer getProductId() { return productId; } public void setProductId(Integer productId) { this.productId = productId; } public Integer getQuantity() { return quantity; } public void setQuantity(Integer quantity) { this.quantity = quantity; } public Integer getOid() { return oid; } public void setOid(Integer oid) { this.oid = oid; } }
创建 OrderVo
它是一个值对象(Value Object),继承 Order
类并添加了一个额外的属性 orderItems
。该类用于在应用程序的各个层之间传递数据,尤其是在表示层和业务逻辑层之间。在这个例子中,OrderVo
类用于表示一个订单及其关联的订单项。
package com.xzs.vo; import com.xzs.model.Order; import com.xzs.model.OrderItem; import lombok.Data; import java.util.ArrayList; import java.util.List; @Data public class OrderVo extends Order { private List<OrderItem> orderItems = new ArrayList<>(); }
2.2 级联方式处理映射关系
<resultMap id="OrderVoMap" type="com.xzs.vo.OrderVo"> <result column="order_id" property="orderId"></result> <result column="order_no" property="orderNo"></result> //多关系使用collection <collection property="orderItems" ofType="com.xzs.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 oi WHERE o.order_id = oi.oid AND o.order_id = #{oid} </select>
2.4 OrderMapper接口
package com.xzs.mapper; import com.xzs.model.Order; import com.xzs.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.xzs.biz; import com.xzs.vo.OrderItemVo; public interface OrderItmeBiz { OrderItemVo SelectByOitemId(Integer oid); }
OrderBizImpl 接口实现类
package com.xzs.biz.impl; import com.xzs.biz.OrderBiz; import com.xzs.mapper.OrderMapper; import com.xzs.vo.OrderVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class OrderBizImpl implements OrderBiz { @Autowired private OrderMapper orderMapper; @Override public OrderVo SelectByOid(Integer oid) { return orderMapper.SelectByOid(oid); } }
三、多对多映射(Many-to-Many)
3.1 表关系
多对多映射是指多个对象与多个对象具有多对多的关系。表之间的多对多关系稍微复杂,需要一个中间表来表示:
中间表有三个字段,其中两个字段分别作为外键指向各自一方的主键,由此通过中间表来表示多对多关系,通过一个表联合另一个中间表可以表示为一对多关系。
如:根据书籍id查找关联属性类别:
3.2 创建实体
利用mybatis逆向工程(generatorConfig.xml)生成模型层代码 :
package com.xzs.model; import lombok.ToString; @ToString public class HCategory { private Integer categoryId; private String categoryName; public HCategory(Integer categoryId, String categoryName) { this.categoryId = categoryId; this.categoryName = categoryName; } public HCategory() { super(); } public Integer getCategoryId() { return categoryId; } public void setCategoryId(Integer categoryId) { this.categoryId = categoryId; } public String getCategoryName() { return categoryName; } public void setCategoryName(String categoryName) { this.categoryName = categoryName; } }
package com.xzs.model; import lombok.ToString; @ToString public class HBookCategory { private Integer bcid; private Integer bid; private Integer cid; public HBookCategory(Integer bcid, Integer bid, Integer cid) { this.bcid = bcid; this.bid = bid; this.cid = cid; } public HBookCategory() { super(); } public Integer getBcid() { return bcid; } public void setBcid(Integer bcid) { this.bcid = bcid; } public Integer getBid() { return bid; } public void setBid(Integer bid) { this.bid = bid; } public Integer getCid() { return cid; } public void setCid(Integer cid) { this.cid = cid; } }
package com.xzs.model; import lombok.ToString; @ToString public class HBook { private Integer bookId; private String bookName; private Float price; public HBook(Integer bookId, String bookName, Float price) { this.bookId = bookId; this.bookName = bookName; this.price = price; } public HBook() { super(); } public Integer getBookId() { return bookId; } public void setBookId(Integer bookId) { this.bookId = bookId; } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public Float getPrice() { return price; } public void setPrice(Float price) { this.price = price; } }
创建 HBookVo 值对象(Value Object)
package com.xzs.vo; import com.xzs.model.BookCategory; import com.xzs.model.HBook; import lombok.Data; import java.util.List; @Data public class HBookVo extends HBook { private List<BookCategory> bookc = new ArrayList<>(); }
3.3 处理映射关系、定义sql
<resultMap id="HBookVoMap" type="com.xzs.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.xzs.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 * FROM t_hibernate_book b, t_hibernate_category c, t_hibernate_book_category bc WHERE b.book_id = bc.bid AND c.category_id = bc.bcid AND b.book_id = #{bid} </select>
3.4 HBookMapper 接口
HBookVo selectByBookId(@Param("bid") Integer bid);
3.5 编写业务逻辑层
HBookBiz 接口
package com.xzs.biz; import com.xzs.vo.HBookVo; public interface HBookBiz { HBookVo selectByBookId(Integer bid); }
HBookBizImpl 接口实现类
package com.xzs.biz.impl; import com.xzs.biz.HBookBiz; import com.xzs.mapper.HBookMapper; import com.xzs.vo.HBookVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class HBookBizImpl implements HBookBiz { @Autowired private HBookMapper hBookMapper; @Override public HBookVo selectByBookId(Integer bid) { return hBookMapper.selectByBookId(bid); } }