文章目录
学习目标
-
(1)ResultMap(重要)
查询数据封装的原理 字段名和成员名不一致 ResultMap标签
-
(2)动态sql(重要)
动态sql-if标签 动态sql-foreach标签
-
(3)关联查询(重要)
关联查询-一对一 关联查询-一对多 关联查询-综合案例
一、ResultMap
1、ResultMap有什么用?
建立查询字段与实体类成员变量的映射关系
- 字段名与变量名不一致,可以赋值
如果查询字段和数据库字段不符,mybatis也可以给它赋值
- 实现一对多,多对多的查询
2、字段名和成员名不一致
- (1)为什么id属性能被Mybatis赋值?
》底层使用id生成setId
》使用反射调用setId方法,setId(10) 方法内完成赋值 id = 10 - (2)为什么user_id属性能被Mybatis赋值?
》底层使用user_id生成setUser_id
》使用反射调用setUser_id方法,类中只有setUserId - (3)所以 为什么强调表与类的对应关系?
》 字段名和成员名要一致
3、ResultMap标签映射关系,ResultMap使用
<!--
id是唯一标识,给select 的resultMap属性使用
-->
<resultMap id="OrderMap" type="com.smp.bean.Order">
<!-- 主键部分-->
<id column="id" property="id"/>
<!-- 非主键部分-->
<result column="user_id" property="userId"/>
<!--查询字段名与类的变量名一样的可以不写 -->
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
</resultMap>
<select id="findAll" resultMap="OrderMap">
select * from `order`;
</select>
二、动态标签介绍
- (1)动态标签是什么?
由于mybatis将sql与java代码分离(sql写在xml中)
if标签,forEach标签 - (2)动态标签有什么用?
用来根据数据的不同来生成对应的sql - (3)应用场景
高级搜索功能
搜索有多个条件,不是每个条件输入框都有值 ,此时需根据值来生成where条件
1、动态sql-if标签与where标签
- (1)if标签
if标签:可以判断传入的参数是否为空,如果不为空则拼接sql - (2)where标签:添加了where标签
1:不用在初始sql后边写where 1=1
2: 不用在第一个拼接的sql前写and,但是你也可以手动写and
UserDao.xml
<select id="findByUser" resultType="user">
select * from user
<where>
<if test="username !=null and username !='' ">
and username like #{
username}
</if>
<if test="address !=null and address !='' ">
and address like #{
address}
</if>
<if test="sex !=null and sex !='' ">
and sex = #{
sex}
</if>
</where>
</select>
Test02.java
public class Test02 {
@test
public void test01(){
SqlSession session= MySessionUtils.getSession();
//开发的 搜索用户,可以根据名字搜索,也可以根据地址搜索。。。
User user=new User();
user.setUsername("张%");
user.setAdress("北京市");
//由dao执行
UserDao dao=session.getMapper(UserDao.class);
List<User> list=dao.findByUser(user);
System.out.println(list);
//关闭资源
session.commit();
session.close();
2、动态sql-foreach标签
(1)foreach标签
向sql传递数组或List,mybatis使用foreach解析
(2)如何使用
collection:表示方法传入的集合对象的名字
item:遍历集合时,会将集合中的元素赋值给item
open表示你要拼接的sql以什么开始
close:表示你拼接的sql以什么结束
separator:表示拼接的分隔符
接口中的变量名不能被标签识别,必须在参数的前边加注解@Param(“xxx”)
UserDao.xml
<select id="findByIds" parameterType="list" resultType="user">
select * from user
<where>
<foreach collection="ids" item="id" open="id in(" close=")" separator=",">
#{
id}
</foreach>
</where>
</select>
Test03.java
public class Test03 {
//@Test
public void test01(){
SqlSession session = MySessionUtils.getSession();
UserDao dao = session.getMapper(UserDao.class);
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(3);
list.add(5);
//根据多个id值 查找用户
List<User> users = dao.findByIds(list);
System.out.println(users);
//关闭资源
session.commit();
session.close();
}
}
三、关联查询
(1)项目不可能只有一个表,一般是多表
(2)多表关系为,一对一,一对多,多对多
(3)查询的数据来自多个表,要使用多表查询
笛卡尔集,显示内连接inner join
,左外连接left outer join
,右外连接right outer join
,子查询select嵌套select
(4)查询的结果要封装成javaBean对象 ,在Mybatis中重点掌握resultType与resultMap
1、关联查询-一对一(1)
(1)关联查询的中的一对一是指,站在订单的角度看,一个订单有一个用户跟它对应
(2)数据来自两个表,使用连接查询,需要输出所有订单,使用左外连接
(3)查询结果可以有两种方式封装数据
》resultType 指定一个自定义javaBean类
》resultMap 指定映射关系
sql语句
select o.id as oid,
o.user_id ,
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;
测试Test04.java
public class Test04 {
@Test
public void test01(){
//ResultType=>类
SqlSession session = MySessionUtils.getSession();
//update insert delete find
OrderDao orderDao = session.getMapper(OrderDao.class);
//List<OrderUer> list=orderDao.findAllOrderUser();
List<OrderUser> list=orderDao.findAllOrderUser();
System.out.println(list);
//关闭资源
session.commit();
session.close();
}
}
创建新类OrderUser
public class OrderUser {
//订单的属性
//订单id
private int id;
//用户id
private Integer userid;
//订单号
private String number;
//创建时间
private Date createtime;
//备注
private String note;
//用户的属性
//用户id
private int uid;
//用户名
private String username;
//用户生日
private Date birthday;
//用户性别
private String sex;
//用户地址
private String address;
}
ResultType映射OrderDao.xml
<!-- 查询结果可以使用resultType来指定每一行记录要保存到哪个javaBean-->
<!-- 更多的是使用resultMap-->
<select id="findAllOrderUser" resultType="com.smp.bean.OrderUser">
select o.id as oid,
o.user_id ,
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>
2、关联查询-一对一(2)
(1)分析下属性
(2)association 标签
成员变量的类型为实体类型
(3)如果是关联查询,则必须添加属性:autoMapping=“true”,自动映射
测试Test05.java
public class Test05 {
@Test
public void test01(){
//ResultMap=>原来的Order类
SqlSession session = MySessionUtils.getSession();
//update insert delete find
OrderDao orderDao = session.getMapper(OrderDao.class);
List<Order> list=orderDao.findAllOrder2();
System.out.println(list);
//关闭资源
session.commit();
session.close();
}
}
修改Order类Order.java
public class Order {
private int id;
private Integer user_id;
private String number;
private Date createtime;
private String note;
//增加User成员变量来记录用户的查询字段
private User user;
定义接口OrderDao.java
/*
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;
*/
List<Order> findAllOrder2();
ResultType映射与association
OrderDao.xml
如果是关联查询,则必须添加属性:autoMapping="true",自动映射
<resultMap id="findAllOrder2Map" type="com.smp.bean.Order" autoMapping="true">
<id property="id" column="id"></id>
<association property="user" javaType="com.smp.bean.User" autoMapping="true">
<id column="uid" property="id"/>
</association>
</resultMap>
<select id="findAllOrder2" resultMap="findAllOrder2Map">
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>
3、关联查询-一对多
(1)分析下属性
从用户表的角度看,一个用户可以多次购买,产生多个订单。使用左连接查询每个用户的订单。
(2)查询结果如何转换成JavaBean?
User {
List orders;
}
(3)如何映射关系?
使用resultMap
》映射 id
》映射 集合 collection
测试类Test06.java
public class Test06 {
@Test
public void test01(){
//ResultMap=>原来的User类
SqlSession session = getSession();
UserDao userDao = session.getMapper(UserDao.class);
List<User> list=userDao.findAllUsers();
//获取用户,然后调用用户的getOrders()
System.out.println(list);
session.commit();
session.close();
}
}
修改User类User.java
public class User {
private int id;
private String username;
private Date birthday;
private String sex;
private String adress;
//变量类型是集合List
private List<Order> orders;
定义接口UserDao.java
/*
select u.id as id,
u.username,
u.birthday,
u.sex,
u.address,
o.id,
o.user_id as userId,
o.number,
o.createtime,
o.note
from `user` u left join `order` o
on u.id=o.user_id;
*/
List<User> findAllUsers();
ResultType映射与collection
UserDao.xml
<!-- 如果字段名与变量名一样,则不需要映射
如果一个类中出现集合类型,List,则需要使用collection标签了映射,字段与变量的关系
-->
<resultMap id="findAllUsersMap" type="com.smp.bean.User" autoMapping="true">
<id property="id" column="uid"></id>
<collection property="orders" ofType="com.smp.bean.Order" autoMapping="true">
<id property="id" column="oid"></id>
</collection>
</resultMap>
<select id="findAllUsers" resultMap="findAllUsersMap">
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>
Mybatis学习就到这里,欢迎大家提出意见,到评论区评论哦(o)/