前言
MyBatis是一个Java持久化框架,它提供了一种将数据库表和Java对象之间进行关系映射的方式。这种关系映射可以通过XML配置文件或注解来定义。
在MyBatis中,关系映射是通过Mapper接口和SQL语句来实现的。Mapper接口定义了数据库操作的方法,而SQL语句则定义了具体的数据库操作。
在关系映射中,MyBatis提供了一些注解和XML配置来实现对象和数据库表之间的映射关系。例如,@Table注解可以用于指定Java对象对应的数据库表,@Column注解可以用于指定Java对象属性对应的数据库字段。
此外,MyBatis还支持一对一、一对多、多对一和多对多等复杂的关系映射。通过配置关联关系,可以在查询时自动加载相关联的对象。
一、一对一映射
一对一映射是指数据库中的两个表之间存在一对一的关系,即一个记录在一个表中只对应一个记录在另一个表中的情况。
1.1 创建实体
假设我们有两个表:student(学生表)和 id_card(身份证表)。每个学生只有一个身份证,而每个身份证只属于一个学生。
public class Student { private int id; private String name; private IdCard idCard; // 省略构造函数和getter/setter方法 } public class IdCard { private int id; private String number; private Student student; // 省略构造函数和getter/setter方法 }
1.2 xml配置
使用XML配置的方式,可以在Student类对应的中使用标签来定义关联关系:
<resultMap id="studentResultMap" type="com.xqx.model.Student"> <!-- 省略其他映射配置 --> <association property="idCard" javaType="com.xqx.model.IdCard"> <id property="id" column="id_card_id"/> <result property="number" column="id_card_number"/> </association> </resultMap>
通过以上配置,我们可以在查询学生信息时,自动加载关联的身份证信息。
二、一对多映射
一对多映射是指数据库中的两个表之间存在一对多的关系,即一个记录在一个表中对应多个记录在另一个表中的情况。例如,一个订单(Oeder)与一个订单详情(OrderItem)之间的关系。假设我们有以下表结构:
2.1 创建实体
建立一个OrderVo。OrderVo 类用于表示一个订单及其关联的订单项。
package com.xqx.vo; import com.xqx.model.Order; import com.xqx.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配置
<resultMap id="OrderVoMap" type="com.xqx.vo.OrderVo"> <result column="order_id" property="orderId"></result> <result column="order_no" property="orderNo"></result> //多关系使用collection <collection property="orderItems" ofType="com.xqx.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 测试
OrderMapper
package com.xqx.mapper; import com.xqx.model.Order; import com.xqx.vo.OrderVo; import org.springframework.stereotype.Repository; @Repository public interface OrderMapper { OrderVo selectbyOid(Integer boid); }
OrderBiz
package com.xqx.biz; import com.xqx.vo.OrderVo; public interface OrderBiz { OrderVo selectbyOid(Integer boid); }
OrderBizImpl
package com.xqx.biz; import com.xqx.mapper.OrderMapper; import com.xqx.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 boid) { return OrderMapper.selectbyOid(boid); } }
Junit测试
package com.xqx.biz; import com.xqx.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; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"classpath:Spring-context.xml"}) public class OrderBizImplTest { @Autowired private OrderBiz OrderBiz; @Test public void selectbyOid() { OrderVo orderVO = OrderBiz.selectbyOid(7); System.out.println(orderVO); orderVO.getOrderItems().forEach(System.out::println); } }
测试结果
三、 多对多映射
多对多映射是指多个对象与多个对象具有多对多的关系。以根据书籍id查找关联属性类别为例
3.1 创建实体
vo对象
package com.xqx.vo; import com.xqx.model.BookCategory; import com.xqx.model.Book; import lombok.Data; import java.util.List; @Data public class BookVo extends Book { private List<BookCategory> bookc = new ArrayList<>(); }
3.2 resultMap配置
<resultMap id="BookVoMap" type="com.xqx.vo.BookVo" > <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.xqx.model.Category"> <result column="category_id" property="categoryId"></result> <result column="category_name" property="categoryName"></result> </collection> </resultMap> <!--根据书籍的id查询书籍的信息及所属属性--> <select id="selectByBookId" resultMap="BookVoMap" 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.3 测试
BookMapper
package com.xqx.mapper; import com.xqx.model.Book; import com.xqx.vo.BookVo; import org.springframework.stereotype.Repository; @Repository public interface BookMapper { HbookVo selectByBid(Integer bid); }
BookBiz
package com.xqx.biz; import com.xqx.vo.BookVo; public interface BookBiz { HbookVo selectByBid(Integer bid); }
BookBizImpl
package com.xqx.biz; import com.xqx.mapper.BookMapper; import com.xqx.vo.BookVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class BookBizImpl implements BookBiz { @Autowired private BookMapper BookMapper; @Override public BookVo selectByBid(Integer bid) { return BookMapper.selectByBid(bid); } }
junit测试
package com.xqx.biz; import com.xqx.vo.BookVo; 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; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"classpath:Spring-context.xml"}) public class BookBizImplTest { @Autowired private BookBiz BookBiz; @Test public void selectByBid() { BookVo bookVo = BookBiz.selectByBid(8); System.out.println(bookVo); BookVo.getHcategory().forEach(System.out::println); } }