这里写目录标题
一级缓存(默认开启)
同一个SqlSession执行的同一个sql语句只会执行一次
pojo
User.java
package com.ahu.pojo;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 一个用户对应多个订单
*/
public class User implements Serializable {
private int id;
private String username;
private String sex;
private Date birthday;
private String address;
private List<Orders> ordersList;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List<Orders> getOrdersList() {
return ordersList;
}
public void setOrdersList(List<Orders> ordersList) {
this.ordersList = ordersList;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", sex='" + sex + '\'' +
", birthday=" + birthday +
", address='" + address + '\'' +
", ordersList=" + ordersList +
'}';
}
}
配置文件
UserMapper.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--mapper标签属性namespace和接口名相同-->
<mapper namespace="com.ahu.mapper.UserMapper">
<!--开启二级缓存-->
<cache/>
<select id="queryUser" resultType="user">
select <include refid="userColumn"/> from user
</select>
<!--
多条件查询
标签where拼接查询的条件(自动检查,不需要加1=1)
根据pojo中的对象决定查询的条件(username和sex)
标签if对pojo的属性进行判断
属性test判断属性是否为空
-->
<!--
直接用属性名就可以如username,如果使用user.username则user是内置的属性对象,空串用''表示
SQL语句会自动加where,也会自动删除第一个and
-->
<select id="queryByWhere" resultType="user" parameterType="user">
select * from user
<where>
<if test="username != null and username != ''">
and username like #{username}
</if>
<if test="sex != null and sex != ''">
and sex = #{sex}
</if>
</where>
</select>
<!--
批量删除
参数是集合
使用迭代标签foreach,标签属性parameterType,参数的数据类型,写的是集合的泛型
迭代标签 foreach 遍历集合,固定的集合list
属性: collection 遍历容器集合
属性: open SQL开始的符号
属性: close SQL结束符号
属性: separator SQL语句参数分隔符
属性 item 遍历的容器的元素
-->
<delete id="deleteUserByList" parameterType="list">
delete from user where id in
<foreach collection="list" open="(" close=")" separator="," item="id">
#{id}
-- 取出集合元素
</foreach>
</delete>
<!--
传入数组
collection属性填array
-->
<delete id="deleteUserByArray" parameterType="int[]">
delete from user where id in
<foreach collection="array" open="(" close=")" separator="," item="id">
#{id}
</foreach>
</delete>
<!--
拆分sql语句
select u.id uid,u.username,u.sex,u.birthday,u.address,o.id,o.user_id,o.number,o.createtime,o.note
from user u left outer join orders o on u.id = o.user_id;
-->
<select id="queryUserOrders" resultMap="queryUserOrdersResultMap">
select u.id uid,u.username,u.sex,u.birthday,u.address from user u;
</select>
<!-- type返回类型-->
<resultMap id="queryUserOrdersResultMap" type="User">
<id column="uid" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="birthday" property="birthday"/>
<result column="address" property="address"/>
<!--
配置user对象的属性,不是单一的对象,是集合容器
collection配置一对多
属性property配置pojo对象的属性
属性ofTyte指定集合泛型
-->
<!--
可以传入重命名的列名uid(防止重名)
使用子标签select的第二次子查询也是可以使用映射的
ofType传入泛型
-->
<collection property="ordersList" ofType="Orders" column="uid" select="queryOrdersByUserId">
<id column="id" property="id"/>
<id column="user_id" property="userId"/>
<id column="number" property="number"/>
<id column="createtime" property="createtime"/>
<id column="note" property="note"/>
</collection>
</resultMap>
<select id="queryOrdersByUserId" parameterType="Integer" resultType="Orders">
select o.id,o.user_id,o.number,o.createtime,o.note from orders o where o.user_id = #{id};
</select>
<select id="queryUserById" resultType="User" parameterType="Integer">
select * from user where id=#{id}
</select>
<sql id="userColumn">
id,username,sex,birthday,address
</sql>
</mapper>
业务代码(最下面两个函数)
package com.ahu.test;
import com.ahu.mapper.OrdersMapper;
import com.ahu.mapper.UserMapper;
import com.ahu.pojo.Orders;
import com.ahu.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class MainTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void before() throws IOException {
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
}
/**
* SQ查询了用户和订单信息,但是运行时期只需要订单数据
* 没有用户数据,对用户数据的查询就是浪费资源
* 延迟查询:需要的时候就查,不需要就不查
*
* 方法:拆分SQL语句
*/
@Test
public void testQueryOrdersUser(){
SqlSession sqlSession = sqlSessionFactory.openSession();
OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
List<Orders> orders = ordersMapper.queryOrdersUser();
for (Orders order : orders) {
// System.out.println(order);
System.out.println(order.getId() + "::" + order.getUserId()
+ "::" + order.getNumber());
}
sqlSession.close();
}
/**
* 一对多查询,以用户表为基准,不过和上例相同,Orders内置为User属性,查询出来Orders的属性user为空,不能套娃
*/
@Test
public void testQueryUserOrders(){
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> users = userMapper.queryUserOrders();
for (User user : users) {
System.out.println(user.getUsername());
}
sqlSession.close();
}
/**
* Mybatis一级缓存(sql语句相同)
* 只出现一次sql语句
*/
@Test
public void testQueryUserById(){
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.queryUserById(2);
System.out.println(user);
User user1 = userMapper.queryUserById(2);
System.out.println(user1);
sqlSession.close();
}
/**
* 二级缓存针对的是xml文件
* 不同的sqlSession对象
* 在UserMapper.xml文件中开启二级缓存
* 不同的sqlSession调用同一个xml文件的缓存的时候不需要再重新执行语句
*/
@Test
public void testSecondCache(){
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.queryUserById(2);
System.out.println(user);
sqlSession.close();
SqlSession sqlSession1 = sqlSessionFactory.openSession();
UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = userMapper1.queryUserById(2);
System.out.println(user1);
sqlSession1.close();
}
}
二级缓存
代码同上,在xml配置文件中加cache配置,开启二级缓存,不同的SqlSession对象在同一个xml文件中的sql操作不必重复进行
可能有安全隐患(改动的数据的情况下)