mybatis中的多对一和一对多关系
以用户(User)和用户的订单(Order)为例:
在用户和订单关系中,一个用户可以有多个订单,同时多个订单也可以对应同一个用户
以下是两个bean类的属性
User:
private int id;
private String username;
private Date birthday;
private String sex;
private String address;
private List<Order> orders;
Order:
private int id;
private Integer userId;
private String number;
private Date createtime;
private String note;
private User user;
数据库sql(练习用):
CREATE DATABASE day13 DEFAULT CHARSET='UTF8';
USE day13;
CREATE TABLE USER (
id INT(11) PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(32) NOT NULL COMMENT '用户名称',
birthday DATE DEFAULT NULL COMMENT '生日',
sex CHAR(1) DEFAULT NULL COMMENT '性别',
address VARCHAR(256) DEFAULT NULL COMMENT '地址'
);
INSERT INTO `user` VALUES (NULL, '王五', '2015-05-10', '2', NULL);
INSERT INTO `user` VALUES (NULL, '张三', '2014-07-10', '1', '北京市');
INSERT INTO `user` VALUES (NULL, '张小明', '2018-11-11', '1', '郑州');
INSERT INTO `user` VALUES (NULL, '陈小明', '2019-07-20', '1', '广州');
INSERT INTO `user` VALUES (NULL, '张三丰', '2011-04-11', '1', '西安');
INSERT INTO `user` VALUES (NULL, '陈小明', '2019-09-10', '2', '杭州');
INSERT INTO `user` VALUES (NULL, '王五', '2014-07-07', NULL, NULL);
#创建订单表
CREATE TABLE `order`(
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL ,
number VARCHAR(50) NOT NULL,
createtime DATETIME NOT NULL,
note VARCHAR(100) DEFAULT NULL,
CONSTRAINT FK_order_id FOREIGN KEY (user_id) REFERENCES USER(id)
);
INSERT INTO `order` VALUES ('3', '1', '1000010', '2018-02-04 13:22:35', '备注3');
INSERT INTO `order` VALUES ('4', '1', '1000011', '2017-02-03 13:22:41', NULL);
INSERT INTO `order` VALUES ('5', '5', '1000012', '2019-02-12 16:13:23', NULL);
INSERT INTO `order` VALUES ('6', '6', '1000012', '2025-02-12 16:13:23', NULL);
INSERT INTO `order` VALUES ('7', '7', '1000012', '2020-02-12 16:13:23', NULL);
老样子,先编写mybatis的核心配置文件以及log4j参数配置文件(可选)
如果不知道怎么配置,就参考之前的文章“mybatis入门…”
编写的OrderDao接口:
public interface OrderDao {
//找到所有的订单信息,以及相应的user信息
public List<Order> selectAllOrders();
}
编写的UserDao接口:
public interface UserDao {
//找到所有的user信息以及该user下的所有订单
public List<User> selectAllUsers();
}
Dao同名mapper文件
<mapper namespace="cn.yw.dao.OrderDao">
<resultMap id="selectAllOrdersMap" type="cn.yw.bean.Order" autoMapping="true">
<id property="id" column="id"></id>
<association property="user" javaType="cn.yw.bean.User" autoMapping="true">
<id column="uid" property="id"/>
</association>
</resultMap>
<select id="selectAllOrders" resultMap="selectAllOrdersMap">
select o.id as id,
o.user_id as userId,
o.number,
o.createtime,
o.note,
u.id as uid,
u.username,
u.birthday,
u.sex,
u.address
from `order` o left join `user` u
on o.user_id=u.id;
</select>
</mapper>
这里除了sql语句的配置外,还出现了一个作为sql语句属性reslutMap的参数的新标签-----resultMap,它的作用是,如果被封装的bean类的属性含有非基本类则可以使用这个标签告诉mybatis 应该怎么样进行字段的对应,association标签里面就包含了作为属性的非基本类的映射规则,id标签指代查询到的主键,此外,result标签指定了其他列,如果学过spring 可能会发现
它有些类似于spring基于xml的非基本类型的依赖注入,当然这是题外话了。
<mapper namespace="cn.yw.dao.UserDao">
<resultMap id="selectAllUsersMap" type="cn.yw.bean.User" autoMapping="true">
<id property="id" column="uid"></id>
<collection property="orders" ofType="cn.yw.bean.Order" autoMapping="true">
<id property="id" column="oid"></id>
</collection>
</resultMap>
<select id="selectAllUsers" resultMap="selectAllUsersMap">
select u.id as uid,
u.username,
u.birthday,
u.sex,
u.address,
o.id as oid,
o.user_id as userId,
o.number,
o.createtime,
o.note
from `user` u left join `order` o
on u.id=o.user_id;
</select>
</mapper>
collection 标签,顾名思义,就是用来封装集合的标签,应用于数据库字段之间的一对多关系,properties属性告诉了mybatis,应当映射的是User类中
对应的集合属性的属性名,ofType则指明了作为占位符的类的类型全路径名
标签内部说明了 每一个Order订单对应查询结果时的封装规则。