上一章springboot之mybatis基础我们讲解了基本的环境搭建,这章主要讲实际运用中的一些知识
select – 书写查询sql语句
select中的几个属性说明:
id属性:当前名称空间下的statement的唯一标识。必须。要求id和mapper接口中的方法的名字一致。
resultType:将结果集映射为java的对象类型。必须(和 resultMap 二选一)
parameterType:传入参数类型。可以省略
insert 的几个属性说明:
id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
useGeneratedKeys:开启主键回写
keyColumn:指定数据库的主键
keyProperty:主键对应的pojo属性名
id属性:当前名称空间下的statement的唯一标识(必须属性);
parameterType:传入的参数类型,可以省略。
标签内部:具体的sql语句。
delete 的几个属性说明:
id属性:当前名称空间下的statement的唯一标识(必须属性);
parameterType:传入的参数类型,可以省略。
标签内部:具体的sql语句。
例如在UserMapper.xml中定义如下片段:
id,
user_name,
password,
name,
age,
sex,
birthday,
created,
updated
则可以在UserMapper.xml中使用它:
定义接口:
/**
* 查询男性用户,如果输入了姓名,则按姓名查询
* @param name
* @return
*/
List queryUserList(@Param("name") String name);
编写mapper
定义接口:
/**
* 查询男性用户,如果输入了姓名则按照姓名模糊查找,否则如果输入了年龄则按照年龄查找,否则查找姓名为“鹏程”的用户。
* @param name
* @param age
* @return
*/
List queryUserListByNameOrAge(@Param("name") String name,@Param("age") Integer age);
编写mapper配置:
场景一:查询所有用户,如果输入了姓名按照姓名进行模糊查询,如果输入年龄,按照年龄进行查询,如果两者都输入,两个条件都要成立。
接口:
/**
* 查询所有用户,如果输入了姓名按照姓名进行模糊查询,如果输入年龄,按照年龄进行查询,如果两者都输入,两个条件都要成立
* @param name
* @param age
* @return
*/
List queryUserListByNameAndAge(@Param("name") String name,@Param("age") Integer age);
配置:
场景二:修改用户信息,如果参数user中的某个属性为null,则不修改。
接口:
/**
* 根据id更新用户信息
*
* @param user
*/
public void updateUser(User user);
配置:
UPDATE tb_user
user_name = #{userName},
password = #{password},
name = #{name},
age = #{age},
sex = #{sex},
birthday = #{birthday},
updated = now(),
WHERE
(id = #{id});
场景:按照多个id查询用户信息
接口:
/**
* 按多个Id查询
* @param ids
* @return
*/
List queryUserListByIds(@Param("ids") String[] ids);
配置:
测试:
@Test
public void queryUserListByIds() throws Exception {
List users = this.userMapper.queryUserListByIds(new String[]{"1","2"});
for (User user : users) {
System.out.println(user);
}
}
在mybatis中,一级缓存默认是开启的,并且一直无法关闭
一级缓存满足条件:
1、同一个session中
2、相同的SQL和参数
执行update、insert、delete的时候,会清空缓存
mybatis 的二级缓存的作用域是一个mapper的namespace ,同一个namespace中查询sql可以从缓存中命中。
开启二级缓存:
开启二级缓存,pojo必须序列化:
在Order对象中添加User属性:
public class Order {
private Integer id;
private Long userId;
private String orderNumber;
private Date created;
private Date updated;
private User user;
}
接口:
/**
* 根据订单号查询订单用户的信息
* @param number
* @return
*/
Order queryOrderWithUserByOrderNumber(@Param("number") String number);
使用resultType不能完成自动映射,需要手动完成结果集映射resultMap:
一对多查询:查询订单,查询出下单人信息并且查询出订单详情。
Order类:
public class Order {
private Integer id;
private Long userId;
private String orderNumber;
private Date created;
private Date updated;
private User user;
private List detailList;
}
1
2
3
4
5
6
7
8
9
public class OrderDetail {
private Integer id;
private Integer orderId;
private Double totalPrice;
private Integer status;
}
1
2
3
4
5
6
接口:
/**
* 根据订单号查询订单用户的信息及订单详情
* @param number
* @return
*/
Order queryOrderWithUserAndDetailByOrderNumber(@Param("number") String number);
1
2
3
4
5
6
Mapper映射:
多对多查询:查询订单,查询出下单人信息并且查询出订单详情中的商品数据。
OrderDetail类
public class OrderDetail {
private Integer id;
private Integer orderId;
private Double totalPrice;
private Integer status;
private Item item;
}
public class Item {
private Integer id;
private String itemName;
private Float itemPrice;
private String itemDetail;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
接口:
/**
* 根据订单号查询订单用户的信息及订单详情及订单详情对应的商品信息
* @param number
* @return
*/
Order queryOrderWithUserAndDetailItemByOrderNumber(@Param("number") String number);
1
2
3
4
5
6
Mapper配置:
esutlType无法帮助我们自动的去完成映射,所以只有使用resultMap手动的进行映射
type 结果集对应的数据类型 id 唯一标识,被引用的时候,进行指定
cglib
cglib
3.1
因为业务,需要在mybatis中,使用到大于号,小于号,所以就在SQL中直接使用了。
SELECT * FROM test WHERE 1 = 1 AND start_date <= CURRENT_DATE AND end_date >= CURRENT_DATE
可是,在执行时,总报错误:
```Error creating document instance. Cause: org.xml.sax.SAXParseException; lineNumber: 74; columnNumber: 17; ``元素内容必须由格式正确的字符数据或标记组成。
把AND start_date >= CURRENT_DATE AND end_date <= CURRENT_DATE去掉,就没有问题,所以确定是因为大于号,小于号引起的问题。
于是就想到了特殊符号,于是用了转义字符把>和<替换掉,然后就没有问题了。
SELECT * FROM test WHERE 1 = 1 AND start_date <= CURRENT_DATE AND end_date >= CURRENT_DATE
案例:
1. and mm.ttime > to_date(#{startDateTime},'yyyy-mm-dd hh24:mi:ss')
2. and mm.ttime <= to_date(#{endDateTime},'yyyy-mm-dd hh24:mi:ss')
案例1:
to_date(#{startDateTime},'yyyy-mm-dd hh24:mi:ss')
and mm.ttime <= to_date(#{endDateTime},'yyyy-mm-dd hh24:mi:ss')
]]>
案例2:
mapper文件示例代码 :
and (t1.status = ]]> 1 and t1.status 2)
上述代码其实对应的sql:and (t1.status > =1 andt1.status <= 2)
注意:
使用标记的sql语句中的 等标签不会被解析。
查询数据的时候,发现查不到userName的信息,
User{id=‘2’, userName=‘null’, password=‘123456’, name=‘静静’, age=22, sex=0,
birthday=‘1993-09-05’, created=‘2018-06-30 18:22:28.0’, updated=‘2018-06-30 18:22:28.0’}
原因:数据库的字段名是user_name,POJO中的属性名字是userName
两端不一致,造成mybatis无法填充对应的字段信息。修改方法:在sql语句中使用别名。
当然之前的resultmap也是一样的