Mybatis collection
需求
查询所有用户信息及用户关联的订单信息。
主信息:用户信息
从信息:订单信息
分析
在一对多关联查询时,只能使用resultMap进行结果映射。 1、一对多关联查询时,sql查询结果有多条,而映射对象是一个。 2、resultType完成结果映射的方式的一条记录映射一个对象。 3、resultMap完成结果映射的方式是以[主信息]为主对象,[从信息]映射为集合或者对象,然后封装到主对象中。
po类
PO 用户订单列表
@Data
public class UserOrderList {
/**
* 用户ID
*/
private int id;
/**
* 用户名称
*/
private String username;
/**
* 生日
*/
private Date birthday;
/**
* 性别
*/
private String sex;
/**
* 地址
*/
private String address;
/**
* 创建时间
*/
private Long createTime;
/**
* 订单列表
*/
private List<Order> orders;
}
注:PO类不能使用
extends赋值不进去
UserMapper
public interface UserMapper {
/**
* 获取用户订单列表
* @param userId string 用户ID
* @return
*/
UserOrderList getUserOrderList(int userId);
/**
* 获取用户订单列表
* @param userId string 用户ID
* @return
*/
UserOrderList getOrderListByUserId(int userId);
}
UserMapper.xml
分布查询
resultMap
<!-- 一对多 分布查询 -->
<resultMap id="selectOrderByUser" type="com.xxx.www.mybatis.phase04.po.UserOrderList">
<!-- 用户信息映射 -->
<!-- column 数据库字段 | property 映射po类的字段名 -->
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
<result column="create_time" property="createTime"/>
<!-- 一对多 订单关联属性映射:使用select引用方式 -->
<!-- collection定义关联集合类型的属性的封装规则 -->
<!-- property: 对应po类关联的集合字段 orders -->
<!-- column: 关联字段 与sql查询结果的字段对应 -->
<!-- ofType: 指定的是映射到list集合属性中的pojo类型 -->
<!-- fetchType: 加载类型:lazy(延迟加载)eager(立即加载)如果使用,它将取代全局配置参数lazyLoadingEnable -->
<!-- select 分布查询引用 引用的方法 -->
<collection property="orders" column="id" ofType="com.xxx.www.mybatis.phase04.po.Order" select="com.xxx.www.mybatis.phase04.mapper.OrderMapper.selectOderByUserId" fetchType="lazy">
</collection>
</resultMap>
查询sql
<!-- 查询用户订单列表 一对多 -->
<select id="getUserOrderList" resultMap="selectOrderByUser" parameterType="int">
SELECT
id, username, birthday, sex, address, create_time
FROM
`user` u
<if test="userId != null ">
where
u.id = #{userId}
</if>
</select>
连表单词查询
resultMap
<!-- 一对多 链表查询 -->
<resultMap id="selectOrderListByUserId" type="com.xxx.www.mybatis.phase04.po.UserOrderList">
<!-- 用户信息映射 -->
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
<!-- 一对多 订单信息映射 -->
<collection property="orders" ofType="com.xxx.www.mybatis.phase04.po.Order">
<id column="order_id" property="orderId"/>
<result column="order_number" property="orderNumber"/>
<result column="user_id" property="userId"/>
<result column="prepayment_amount" property="prepaymentAmount"/>
<result column="actually_paid_amount" property="actuallyPaidAmount"/>
<result column="create_time" property="createTime"/>
<result column="goods_kind" property="goodsKind"/>
<result column="goods_quantity" property="goodsQuantity"/>
<result column="payment_method" property="paymentMethod"/>
<result column="trade_on" property="tradeOn"/>
<result column="price_after_discount" property="priceAfterDiscount"/>
</collection>
</resultMap>
查询sql
<!-- 查询用户订单列表 一对多 -->
<select id="getOrderListByUserId" resultMap="selectOrderListByUserId">
SELECT
u.id AS user_id, u.username, u.birthday, u.sex, u.address, o.id AS order_id, o.user_id, u.create_time, o.order_number, o.create_time, o.prepayment_amount, o.actually_paid_amount, o.goods_kind, o.goods_quantity, o.payment_method, o.trade_on, o.price_after_discount
FROM
`user` AS u
JOIN
`order` AS o
where
u.id = o.user_id
and
u.id = #{userId}
</select>
注: 如果两表联查,主表和明细表的主键都是id的话,明细表的多条只能查询出来第一条。 u.id AS user_id 和 o.id AS order_id,直接都用 id 查询多条,得到结果为一条
测试
public class Phase04Test {
/**
* mybatis mysql连接器
*/
private SqlSessionFactory sqlSessionFactory;
private SqlSession sqlSession;
@Before
public void init() throws Exception {
// 加载全局配置文件(同时把映射文件也加载了)
String resource = "phase04/SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// sqlsessionFactory需要通过sqlsessionFactoryBuilder读取全局配置文件信息之后
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//创建UserMapper对象
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void testFindOrderById() {
// 获取代理对象
OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
List<OrderExt> orderExtList = mapper.selectOrderAndUserInfo();
System.out.println(orderExtList);
}
@Test
public void getOrderByUserId() {
// 获取代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
UserOrderList orderList = mapper.getUserOrderList(1);
System.out.println(orderList);
for (Order order: orderList.getOrders()){
System.out.println(order.toString());
}
}
@Test
public void getOrderListByUserId() {
// 获取代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
UserOrderList orderList = mapper.getOrderListByUserId(1);
System.out.println(orderList);
for (Order order: orderList.getOrders()){
System.out.println(order.toString());
}
}
@Test
public void insertOrder() {
// 获取代理对象
OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
Order order = insertOrderInfo();
int rows = mapper.insertOrder(order);
sqlSession.commit();
System.out.println(rows);
System.out.println(order.getOrderNumber());
}
/**
* 添加用户信息
*
* @return User
*/
private Order insertOrderInfo() {
Order order = new Order();
// 订单号
String orderNumber = OrderNumberFactory.getOrderCode(1L);
order.setOrderNumber(orderNumber);
// 用户ID
order.setUserId(1);
// 预付金额
order.setPrepaymentAmount(10L);
// 实付金额
order.setActuallyPaidAmount(10L);
// 创建时间
order.setCreateTime(System.currentTimeMillis());
// 商品种类
order.setGoodsKind(1);
// 商品数量
order.setGoodsQuantity(1);
// 支付方式
order.setPaymentMethod("微信");
// 交易流水号
order.setTradeOn("12311");
// 优惠后价格
order.setPriceAfterDiscount(10L);
return order;
}
@After
public void closeSession(){
if (sqlSession != null){
sqlSession.close();
}
}
}