动态sql语句概述:Mybatis 的映射文件中,前面我们的 SQL 都是比较简单的,有些时候业务逻辑复杂时,我们的 SQL是动态变化的, 此时在前面的学习中我们的 SQL 就不能满足要求了。
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。
如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。
参考的官方文档,描述如下:
我们根据实体类的不同取值,使用不同的 SQL语句来进行查询。比如在 id如果不为空时可以根据id查询,如果 username 不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。
当查询条件id和username都存在时,控制台打印的sql语句如下:
循环执行sql的拼接操作,例如:SELECT * FROM USER WHERE id IN (1,2,5)。
控制台打印的sql语句如下:
foreach标签的属性含义如下:
< foreach >标签用于遍历集合,它的属性:
Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的
select * from user
< select > :查询
< insert > :插入
< update>:修改
< delete > :删除
< where> :where条件
< if>:if判断
< foreach > :循环
< sql > :sql片段抽取
MyBatis可以使用第三方的插件来对功能进行扩展,分页助手PageHelper是将分页的复杂操作进行封装,使用简单的方式即 可获得分页的相关数据 开发步骤:
① 导入通用PageHelper的坐标
com.github.pagehelper
pagehelper
3.7.5
com.github.jsqlparser
jsqlparser
0.9.1
② 在mybatis核心配置文件中配置PageHelper插件
③ 测试分页数据获取
@Test
public void testPageHelper(){
//设置分页参数
PageHelper.startPage(1,2);
List select = userMapper2.select(null);
for(User user : select){
System.out.println(user);
}
}
获得分页相关的其他参数
PageInfo pageInfo = new PageInfo(select);
System.out.println("总条数:"+pageInfo.getTotal());
System.out.println("总页数:"+pageInfo.getPages());
System.out.println("当前页:"+pageInfo.getPageNum());
System.out.println("每页显示长度:"+pageInfo.getPageSize());
System.out.println("是否第一页:"+pageInfo.isIsFirstPage());
System.out.println("是否最后一页:"+pageInfo.isIsLastPage());
6、Mybatis多表查询
用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户 一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户。
对应的sql语句:
select * from orders o,user u where o.uid=u.id;
创建Order和User实体:
public class User {
private int id;
private String username;
private String password;
private Date birthday;
}
public class Order {
private int id;
private Date ordertime;
private double total;
//代表当前订单从属于哪一个客户
private User user;
}
创建OrderMapper接口:
public interface OrderMapper {
List findAll();
}
配置OrderMapper.xml:
Test
OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
List all = mapper.findAll();
for(Order order : all){
System.out.println(order);
}
用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户 一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单。
对应的sql语句:
select *,o.id oid from user u left join orders o on u.id=o.uid;
修改User实体:
public class User {
private int id;
private String username;
private String password;
private Date birthday;
//代表当前用户具备哪些订单
private List orderList;
}
创建UserMapper接口:
public interface UserMapper {
List findAll();
}
配置UserMapper.xml:
Test:
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List all = mapper.findAll();
for(User user : all){
System.out.println(user.getUsername());
List orderList = user.getOrderList();
for(Order order : orderList){
System.out.println(order);
}
}
用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使用 多对多查询的需求:查询用户同时查询出该用户的所有角色。
对应的sql语句:
select u.*,r.*,r.id rid from user u left join user_role ur on u.id=ur.user_id inner join role r on ur.role_id=r.id;
创建Role实体,修改User实体
public class User {
private int id;
private String username;
private String password;
private Date birthday;
//代表当前用户具备哪些订单
private List orderList;
//代表当前用户具备哪些角色
private List roleList;
}
public class Role {
private int id;
private String rolename;
}
添加UserMapper接口方法
List findAllUserAndRole();
配置UserMapper.xml
Test:
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List all = mapper.findAllUserAndRole();
for(User user : all){
System.out.println(user.getUsername());
List roleList = user.getRoleList();
for(Role role : roleList){
System.out.println(role);
}
}
MyBatis多表配置方式: