MyBatis基础
什么是 MyBatis
Mybatis 是一个半 ORM 框架,内部封装了 JDBC,开发时只需要关注 sql 语句本身,不用去处理加载驱动,创建连接等过程
程序员可以直接编写原生 sql,可以严格控制 sql 执行性能,灵活度高
MyBatis 可以使用 xml 或注解来配置和映射原生信息,将 pojo 映射成数据库中的记录
ORM 是什么
ORM,对象关系映射,是一种为了解决关系型数据库数据与简单 Java 对象的映射关系的技术
通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系型数据库中
为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?
Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取
Mybatis 在查询关联对象或关联集合对象时,需要手动编写 SQL 来完成
MyBatis 使用过程


创建 SqlSessionFactory
SqlSessionFactory 是 MyBatis 框架中的核心接口,它是创建 SqlSession 的工厂类,负责管理数据库会话的创建和配置
- 创建 SqlSession:作为工厂类,生产 SqlSession 实例
- 管理数据库配置:持有 MyBatis 的所有配置信息
- 线程安全:SqlSessionFactory 一旦创建,可以在应用运行期间一直存在
创建 SqlSession
SqlSession(会话)可以理解为程序和数据库之间的桥梁
通过 sqlsession 执行数据库操作
可以通过 SqlSession 实例来直接执行已映射的 SQL 语句:
Blog blog = (Blog)session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);更常用的方式是先获取 Mapper(映射),然后再执行 SQL 语句:
BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);如果是更新、删除语句,我们还需要提交一下事务。
最后一定要调用 session.close()关闭会话
#{}和${}的区别?
#{} 是预编译处理,${} 是字符串替换
当使用 #{} 时,MyBatis 会在 SQL 执行之前,将占位符替换为问号 ?,并使用参数值来替代这些问号
当使用 ${} 时,参数的值会直接替换到 SQL 语句中去,而不会经过预处理
Mybatis 的一级、二级缓存
- 一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 SqlSession,各个 SqlSession 之间的缓存相互隔离,当 Session flush 或 close 之后,该 SqlSession 中的所有 Cache 就将清空,MyBatis 默认打开一级缓存
- 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同之处在于其存储作用域为 Mapper(Namespace),可以在多个 SqlSession 之间共享,并且可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现 Serializable 序列化接口(可用来保存对象的状态),可在它的映射文件中配置
如何防止 sql 住入
使用参数化查询
使用参数化查询,即使用PreparedStatement对象,通过setXxx方法设置参数值,而不是通过字符串拼接 SQL 语句。这样可以有效防止 SQL 注入
String query = "SELECT * FROM users WHERE username = ?";
PreparedStatement pstmt = connection.prepareStatement(query);
pstmt.setString(1, userName); // userName 是用户输入
ResultSet rs = pstmt.executeQuery();限制用户输入
对用户输入进行验证和过滤,只允许输入预期的数据,不允许输入特殊字符或 SQL 关键字
使用 ORM 框架
在 MyBatis 中,使用#{}占位符来代替直接拼接 SQL 语句,MyBatis 会自动进行参数化处理