1.CRUD
1.1 注解实现
1.使用注解就不需要mapper.xml文件了,所以要把sqlMapConfig.xml中的<mapper resource="XXMapper.xml"></mapper>改成<mapper class||name="com.***"></mapper>(扫描使用了注解的dao接口全类名或者包名)
2.Dao层(使用注解+SQL)
@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
2.DAO层开发
2.1 传统型
将3.1中的测试方法移到DaoImpl;
2.2 代理型(目前主流)
只需要定义Dao接口,无需提供实现
private userMapper;
@Before
public void before() {
InputStream resourceAsStream =
Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//获得MyBatis框架生成的UserMapper接口的实现类
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void testProxyDao() throws IOException {
User user = userMapper.findById(1);
System.out.println(user);
sqlSession.close();
}
2.2.1 注解实现
Dao接口方法上需要写注解+SQL语句
3.复杂映射
public class Order {
private int id;
private Date ordertime;
private double total;
//代表当前订单从属于哪一个客户
private User user;
}
public class User {
private int id;
private String username;
private String password;
private Date birthday;
//代表当前用户有多少订单
private List<Order> orders;
//代表当前用户有多少角色
private List<Role> roleList;
}
public class Role {
private int id;
private String rolename;
}
3.1 一对一映射
3.1.1 注解实现
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
public interface OrderMapper {
@Select("select * from orders")
@Results({
@Result(id=true,property = "id",column = "id"),
@Result(property = "ordertime",column = "ordertime"),
@Result(property = "total",column = "total"),
@Result(property = "user",column = "uid",
javaType = User.class,
one = @One(select = "com.dck.mapper.UserMapper.findById"))
})
List<Order> findAll();
}
3.2 一对多映射
3.2.1 注解实现(分成两条sql语句查询)
public interface UserMapper {
@Select("select * from user")
@Results({
@Result(id = true,property = "id",column = "id"),
@Result(property = "username",column = "username"),
@Result(property = "password",column = "password"),
@Result(property = "birthday",column = "birthday"),
@Result(property = "orderList",column = "id",
javaType = List.class,
many = @Many(select =
"com.dck.mapper.OrderMapper.findByUid"))
})
List<User> findAllUserAndOrder();
}
public interface OrderMapper {
@Select("select * from orders where uid=#{uid}")
List<Order> findByUid(int uid);
}
3.3 多对多映射
3.3.1 注解实现
public interface UserMapper {
@Select("select * from user")
@Results({
@Result(id = true,property = "id",column = "id"),
@Result(property = "username",column = "username"),
@Result(property = "password",column = "password"),
@Result(property = "birthday",column = "birthday"),
@Result(property = "roleList",column = "id",
javaType = List.class,
many = @Many(select = "com.dck.mapper.RoleMapper.findByUid"))
})
List<User> findAllUserAndRole();
}
4.缓存
4.1 一级缓存(sqlSession级别,默认开启)
共用一个sqlSession的情况下才使用到了一级缓存,比如@Transational注解的方法内的所有数据库请求共用一个sqlSession、sqlSession是单例、静态域或者实例成员变量。
存放位置:SqlSession>Executor>PerpetualCache>Map<Object,Object>
使用:每次Executor执行数据库查询query之前,都会检查缓存中是否有完全相同SQL语句的缓存,有则直接返回对应value
- 第一次查询---》1.读取缓存,发现没有匹配key;2.从数据库读取,并插入缓存
- 第二次查询完全相同的SQL---》读取缓存,命中直接返回,且是同一个对象
- sqlSession.commit()或clearCache()或close()---》清空缓存
4.2 二级缓存(nameSpace级别,默认关闭)
4.2.1 默认二级缓存
注解开启:
@CacheNamespace
- 第一次查询---》1.读取缓存,发现没有匹配key;2.从数据库读取,并插入缓存
- 第二次查询完全相同的SQL---》读取缓存,命中直接返回,但已经不是原来的对象(不==)
- sqlSession.commit()---》清空缓存
因为二级缓存数据存储介质多种多样,不一定只存在内存中,有可能存在硬盘中,如果我们要再取这个缓存的话,就需要反序列化了。所以mybatis中的pojo都要去实现Serializable接口。
4.2.2 使用redis作为二级缓存
解决问题:当服务器集群或者多个实例访问同一个数据库时,无法实现数据库缓存 在多个服务器之间共享,故使用第三方内存数据库作为缓存----分布式缓存。