mybatis详解(2)
1 #和$的区别
| # | $ | 
|---|---|
| PreparedStatement | Statement | 
| ? | 拼接 | 
| 解决了SQL注入漏洞 | SQL注入漏洞( OR 1=‘1’) | 
| #{title} —>book.getTitle() | ORDER BY ${price} -->将传入的price拼接在ORDER BY 的后面 | 
1.1 例子
1.1.1 第一步:在接口中写方法

1.1.2 第二步:写sql语句

1.1.3 第三步:测试

使用$的测试,可以看到成功查询,并且以价格高到低排序
 
1.1.4 补充:如果在第二步用#{price}代替${price}
- #是注入book.get()方法的值,而book中并没有book_price DESC 这个属性,自然也就调用不了get方法。
 - 因此,如果使用#,就只会做全查询
 

2 缓存问题
2.1 用一个查询测试
@Test
	public void testFindById() throws IOException {
		// 这里先把before和after注释
		// 1.读取mybatis配置文件,变成字符流对象
		Reader in = Resources.getResourceAsReader("resources/mybatisConfig/mybatis-config.xml");
		// 2.创建SqlSessionFactory工厂,管理多个数据库操作会话
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
		// 3.开启一次sql会话
		sqlSession = sqlSessionFactory.openSession();
		// 4.创建数据库操作接口对象
		IBookMapper mapper = sqlSession.getMapper(IBookMapper.class);
		// 5.接口操作,调用接口方法
		Book book = mapper.findById(3);
		
		System.out.println(book);
		// 6.事务提交
		sqlSession.commit();
		sqlSession.close();
	}
 

2.1.1 逐行解释
- DEBUG - Opening JDBC Connection 打开jdbc连接,从数据源中取得Connection对象
 - INFO - {dataSource-1} inited 初始化数据源
 - DEBUG - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@73d4cc9e] 将事务的自动提交设置为false
 - DEBUG - ==> Preparing: SELECT * FROM book_tab WHERE book_id = ? PreparedStatment 读取SQL语句
 - DEBUG - ==> Parameters: 3(Integer) 给?号注入值
 - 影响行数
 - 查询的数据
 - DEBUG - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@73d4cc9e] 将事务的自动提交设置为真
 - DEBUG - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@73d4cc9e] 将连接对象Connection重新放入数据源连接池中
 
2.2 第二次测试

可以发现如果book的id不同,并没有发生不同的事
 
2.3 第三次测试

当book的id一样时,可以发现sql语句只执行了一次,就查询到两个Book对象的数据。证明了mybatis是存在缓存的。
 
2.4 一级缓存
通过上面三个测试,可以发现mybatis是有缓存的。
mybatis内置一个缓存,SqlSession对象- 一级缓存(运行速度块,空间小),内置的,用户不能手动关闭。
- 在sqlSession.close() ,已经关闭SqlSession对象,缓存也自然关闭了
 - sqlSession.clearCache() , 则是清空缓存
 




2.5 二级缓存
二级缓存,客户选择实现,默认是关闭状态 ,针对SqlSessionFactory
2.5.1 设置二级缓存

2.5.2 二级缓存的效果
设置了二级缓存,即使关闭了SqlSession,它的缓存依旧存在,二级缓存的存储时间很长。
2.5.3 二级缓存需要注意的事
因为这里缓存了Book对象,所以对象需要序列化
 











