1.输出映射
通过parameterType指定输入参数的类型,类型可以是简单类型、 hashmap 、 pojo 的包装类型。
[1]简单类型
例如入门程序里的根据用户ID查询用户信息的映射文件,输入Int值。
[2]POJO类型
例如入门程序里的添加用户文件,就是输入POJO类型的USER
[3]包装POJO类型
综合查询时,需要传入的查询条件可能很复杂,可能会根据用户信息、商品信息、订单信息等作为条件进行查询,用户信息中的查询条件由:用户的名称和性别进行查询。
POJO包装类:针对上边的需求,建议使用自定义的包装类型pojo,在包装类型的pojo中将复杂的查询条件包装进去。
例如:当我们要用用户的名称和性别进行查询时
1.创建包装POJO
public class UserQueryVO {
//用户信息
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
2.在UserMapper中添加映射文件
#{user.sex}:取出pojo包装对象中性别值
${user.username}:取出pojo对象中姓名值
3.UserMapper 接口文件
输出pojo对象list,方法返回值是List
//综合查询
public List findUserList(UserQueryVO vo);
4.测试代码
2.输出映射
[1]resultType
使用要求:使用resultType进行结果映射时,需要查询出的列名和映射的对象的属性名一致,才能映射成功。
如果查询的列名和对象的属性名全部不一致,那么映射的对象为空。
如果查询的列名和对象的属性名有一个一致,那么映射的对象不为空,但是只有映射正确那一个属性才有值。
如果查询的sql的列名有别名,那么这个别名就是和属性映射的列名。
(1)简单类型
注意,对简单类型的结果映射也是有要求的,查询的列必须是一列,才能映射为简单类型。
例如:
综合查询时 ,根据需求 综合查询符合用户条件的总数1.映射文件
2. Mapper接口
3.测试代码
(2)POJO对象和POJO列表
例如:根据用户ID查询用户信息和根据用户名称模糊查询用户列表
[2]resultMap
使用resultMap进行结果映射时,不需要查询的列名和映射的属性名必须一致。但是需要声明一个resultMap,来对列名和属性名进行映射。
2.Mapper接口
public User findUserRstMap(int id)
3.测试代码
小结:
用 resultType 进行输出映射,只有查询出来的列名和 pojo 中的属性名一致,该列才可以映射成功。
如果查询出来的列名和 pojo 的属性名不一致,通过定义一个 resultMap 对列名和 pojo 属性名之间作一个映射关系。
3.动态SQL
在mybatis中,它提供了一些动态sql标签,可以让程序员更快的进行mybatis的开发,这些动态sql可以通过sql的可重用性。
常用的动态sql标签:if标签、where标签、sql片段、foreach标签
[1] if标签/where标签
综合查询时,查询条件由用户来输入,用户名称可以为空,需要满足这种情况下的sql编写。
1.映射文件
2.测试代码
[2]Foreach标签
可以循环传入参数值
例如:综合查询时,会根据用户ID集合进行查询
SELECT * FROM USER WHERE id IN (1,2,10)
1.包装POJO
2.映射文件
3.测试代码
4.高级映射
主要介绍了如何使用resultMap完成高级映射;分析数据库中表之间的关系(一对一、一对多、多对多
如何在mapper.xml文件中配置resultMap实现一对一、一对多、多对多
【1】数据模型
1、 明确每张表存储的信息
2、 明确每张表中关键字段(主键、外键、非空)
3、 明确数据库中表与表之间的外键关系
4、 明确业务中表与表的关系(建立在具体的业务)
数据库中有已经导入的四个表:items:(商品信息表);orderdetail:(订单明细表);orders:(订单表);user:(用户表)
1) 用户表user:
记录了购买商品的用户
2) 订单表orders:
记录了用户所创建的订单信息
3) 订单明细表orderdetail:
记录了用户创建订单的详细信息
4) 商品信息表items:
记录了商家提供的商品信息
分析表与表之间的关系:
用户user和订单orders:
user---->orders:一个用户可以创建多个订单 一对多
orders-->user:一个订单只能由一个用户创建 一对一
订单orders和订单明细orderdetail:
orders-->orderdetail:一个订单可以包括多个订单明细 一对多
orderdetail-->orders:一个订单明细只属于一个订单 一对一
订单明细orderdetail和商品信息items:
orderdetail-->items:一个订单明细对应一个商品信息一对一
items--> orderdetail:一个商品对应多个订单明细 一对多
以下是这四个表的对应关系:
【2】一对一映射
1.需求
由上图我们可以看出,用户和订单表是一对一映射,所以我们以查询订单信息,关联查询用户信息为需求
2.sql语句
查询语句:
先确定主查询表:订单信息表
再确定关联查询表:用户信息
通过orders关联查询用户使用user_id一个外键,只能关联查询出一条用户记录就可以使用内连接
SELECT
orders.`id`,
orders.`user_id`,
orders.`number`,
user.`username`,
user.`sex`
FROM
orders,
USER
WHERE orders.`user_id` = user.`id`
(1)使用resultType实现
这里输出的结果包括 订单信息和用户信息,之前创建的pojo都是单表的实体类,所以这里需要自定义一个组合的pojo才能完成resultType的映射。
创建OrderCustom作为自定义pojo,补充相应的get()和set()方法
public class OrderCustom extends Orders {
//补充用户信息
private String username;
private String sex;
}
mapper.xml文件配置
定义OrdersMapperCustom.xml文件
SELECT
orders.*,
user.username,
user.sex
FROM
orders,
USER
WHERE orders.user_id = user.id
mapper接口
public interface OrdersMapperCustom {
// 一对一查询,查询订单关联查询用户,使用resultType
public List findOrderUserList() throws Exception;
}
测试代码
public void testFindOrderUserList() throws Exception {
SqlSessionsqlSession = sqlSessionFactory.openSession();
//创建mapper代理对象
OrdersMapperCustomordersMapperCustom = sqlSession
.getMapper(OrdersMapperCustom.class);
//调用方法
List list = ordersMapperCustom.findOrderUserList();
System.out.println(list);
sqlSession.close();
}
使用resultType来进行一对一结果映射,查询出的列的个数和映射的属性的个数要一致。而且映射的属性要存在与一个大的对象中,它是一种平铺式的映射,即数据库查询出多少条记录,则映射成多少个对象。
(2)使用resultMap实现
成一使用resultMap来进行一对一结果映射,它是将关联对象添加到主信息的对象中,具体说是对象嵌套对象的一种映射方式,使用association完对一映射需要配置一个resultMap,过程有点复杂,如果要实现延迟加载就只能用resultMap实现 ,如果为了方便对关联信息进行解析,也可以用association将关联信息映射到pojo中方便解析。
在一对一结果映射时,使用resultType更加简单方便,如果有特殊要求(对象嵌套对象)时,需要使用resultMap进行映射,比如:查询订单列表,然后在点击列表中的查看订单明细按钮,这个时候就需要使用resultMap进行结果映射。而resultType更适应于查询明细信息,比如,查询订单明细列表。
修改扩展类
【3】一对多映射
(1)需求
用mapper接口代理的方式查询所有订单信息(关联用户)及订单下的订单明细信息。
(2)SQL语句
主信息:orders
从信息:orderdetail、user
有两个id重复, 给orderdetail的id设置别名 detailid. 有别名时查询以别名为主
SELECT
orders.`id`,
orders.`user_id`,
orders.`number`,
user.`username`,
user.`sex`,
orderdetail.`id` detailid,
orderdetail.`items_id`,
orderdetail.`items_num`
FROM
orders,
user,
orderdetail
WHERE orders.`user_id` = user.`id`
AND orders.`id` = orderdetail.`orders_id`
(3)resultMap进行一对多映射思路
修改拓展类
映射文件
ofType:集合中pojo的类型
Mapper接口
测试代码
mybatis使用resultMap的collection对关联查询的多条记录映射到一个list集合属性中
【4】多对多映射
多对多映射是一对多映射的特例
(1)需求
查询用户信息,关联查询该用户购买的商品信息
(2)SQL语句
主信息:user
从信息:items、orders、orderdetail
SELECT
orders.`id`,
orders.`user_id`,
orders.`number`,
user.`username`,
user.`sex`,
orderdetail.`id` detailId,
orderdetail.`items_id`,
orderdetail.`items_num`,
items.`name`,
items.`price`
FROM
orders,
USER,
orderdetail,
items
WHERE orders.`user_id` = user.`id`
AND orders.`id` = orderdetail.`orders_id`
AND orderdetail.`items_id` = items.`id`
(3)修改拓展类
一对多映射是多对对映射的一个特殊例子,多对多映射思路如下:
在user.java中创建映射的属性:集合 List
在Orders中创建映射的属性:集合List
在Orderdetail中创建商品属性:pojo Items items
在User类中添加List
在Orders类中添加List
在Orderdetail中添加Items items;
(4)Mapper接口
(5)映射文件
(6)测试代码