[org.apache.ibatis.logging.LogFactory]-Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
[org.apache.ibatis.logging.LogFactory]-Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
[org.apache.ibatis.io.VFS]-Class not found: org.jboss.vfs.VFS
[org.apache.ibatis.io.JBoss6VFS]-JBoss 6 VFS API is not available in this environment.
[org.apache.ibatis.io.VFS]-Class not found: org.jboss.vfs.VirtualFile
[org.apache.ibatis.io.VFS]-VFS implementation org.apache.ibatis.io.JBoss6VFS is not valid in this environment.
[org.apache.ibatis.io.VFS]-Using VFS adapter org.apache.ibatis.io.DefaultVFS
[org.apache.ibatis.io.DefaultVFS]-Find JAR URL: file:/D:/IDEA%e6%95%b0%e6%8d%ae/mybatis-study/mybatis-04/target/classes/com/yin/pojo
[org.apache.ibatis.io.DefaultVFS]-Not a JAR: file:/D:/IDEA%e6%95%b0%e6%8d%ae/mybatis-study/mybatis-04/target/classes/com/yin/pojo
[org.apache.ibatis.io.DefaultVFS]-Reader entry: User.class
[org.apache.ibatis.io.DefaultVFS]-Listing file:/D:/IDEA%e6%95%b0%e6%8d%ae/mybatis-study/mybatis-04/target/classes/com/yin/pojo
[org.apache.ibatis.io.DefaultVFS]-Find JAR URL: file:/D:/IDEA%e6%95%b0%e6%8d%ae/mybatis-study/mybatis-04/target/classes/com/yin/pojo/User.class
[org.apache.ibatis.io.DefaultVFS]-Not a JAR: file:/D:/IDEA%e6%95%b0%e6%8d%ae/mybatis-study/mybatis-04/target/classes/com/yin/pojo/User.class
[org.apache.ibatis.io.DefaultVFS]-Reader entry: 漱壕 4 <
[org.apache.ibatis.io.ResolverUtil]-Checking to see if class com.yin.pojo.User matches criteria [is assignable to Object]
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Opening JDBC Connection
[org.apache.ibatis.datasource.pooled.PooledDataSource]-Created connection 255334292.
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@f381794]
[com.yin.dao.UserMapper.getUserById]-==> Preparing: select * from user where id = ?
[com.yin.dao.UserMapper.getUserById]-==> Parameters: 1(Integer)
[com.yin.dao.UserMapper.getUserById]-<== Total: 1
User{id=1, name='张三', password='123'}
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@f381794]
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@f381794]
[org.apache.ibatis.datasource.pooled.PooledDataSource]-Returned connection 255334292 to pool.
Process finished with exit code 0
public interface UserMapper {
@Select("select * from user")
List getUsers();
}
需要在核心配置文件中绑定接口
测试
本质:反射机制实现
底层:动态代理!
动态代理
MyBatis详细执行流程(重要)
思路:
8.3 注解CURD
自动提交事务
在工具类创建的时候实现自动提交事务
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession(true);//这里需要获取sqlSessionFactory的连接
}
CURD
编写接口,增加注解
//通过id查询
//方法存在多个参数,所有的参数前面必须加上@Param("id")注解
@Select("select * from user where id = #{id}")
User getUserByID(@Param("id") int id2);
@Insert("insert into user(id, name, pwd) values(#{id}, #{name}, #{password})")
int addUser(User user);
@Update("update user set name = #{name} ,pwd = #{password} where id = #{id}")
int updateUser(User user);
@Delete("delete from user where id = #{uid}")
int deleteUser(@Param("uid") int id);
insert into blog (id, title, author, create_time, views)
values (#{id}, #{title}, #{author}, #{createTime}, #{views});
select *
from blog where 1=1
and title = #{title}
and author = #{author}
测试
@Test
public void queryBlog(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
map.put("title","java");
map.put("author","狂神说");
List blogs = mapper.queryBlogIF(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
======
Blog(id=2, title=java, author=狂神说, createTime=Wed Apr 13 08:00:00 CST 2016, views=1000)
这样写我们可以看到,如果 author 等于 null,那么查询语句为 select from user where title=#{title},但是如果title为空呢?那么查询语句为 select from user where and author=#{author},这是错误的 SQL 语句,如何解决呢?请看下面的 where 语句!
choose (when, otherwise)
choose:选择
when:什么时候
otherwise:其他
select *
from blog
title = #{title}
and author = #{author}
and views = #{views}
@Test
public void queryBlogChoose(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
map.put("title","java");
map.put("author","狂神说");
map.put("views",9999);
List blogs = mapper.queryBlogChoose(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
=========
Blog(id=2, title=java, author=狂神说, createTime=Wed Apr 13 08:00:00 CST 2016, views=1000)
trim、where、set
where(重点)
修改上面的SQL语句;
select *
from blog
and title = #{title}
and author = #{author}
@Test
public void queryBlog(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
map.put("title","java");
map.put("author","狂神说");
List blogs = mapper.queryBlogIF(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。
此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。【这是我们使用的最多的案例】
set(重点)
同理,上面的对于查询 SQL 语句包含 where 关键字,如果在进行更新操作的时候,含有 set 关键词,我们怎么处理呢?
set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。
编写接口方法
//更新博客
int updateBlog(Map map);
xml
update blog
title = #{title},
author = #{author},
where id = #{id}
测试
@Test
public void updateBlog(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
// map.put("title","java2");
map.put("author","狂神说4");
map.put("id",1);
// map.put("views",9999);
mapper.updateBlog(map);
sqlSession.close();
}
===================
==> Preparing: update blog SET author = ? where id = ?
==> Parameters: 狂神说4(String), 1(Integer)
<== Updates: 1
@Test
public void queryUserById(){
//创建两个sqlSession
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
System.out.println(user);
sqlSession.close();
SqlSession sqlSession2 = MybatisUtils.getSqlSession();
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.queryUserById(1);
System.out.println(user2);
System.out.println(user == user2);
sqlSession2.close();
}
Opening JDBC Connection
Created connection 689654773.
==> Preparing: select * from user where id = ?
==> Parameters: 1(Integer)
<== Columns: id, name, pwd
<== Row: 1, 张三, 123
<== Total: 1
User(id=1, name=张三, pwd=123)
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@291b4bf5]
Returned connection 689654773 to pool.
As you are using functionality that deserializes object streams, it is recommended to define the JEP-290 serial filter. Please refer to https://docs.oracle.com/pls/topic/lookup?ctx=javase15&id=GUID-8296D8E8-2B93-4B9A-856E-0A65AF9B8C66
Cache Hit Ratio [com.yin.dao.UserMapper]: 0.5
User(id=1, name=张三, pwd=123)
false
Process finished with exit code 0
小结:
只要开启了二级缓存,在同一个Mapper下就有效
所有的数据都会先放在一级缓存中
只有当前会话提交,或者关闭的时候,才会提交到二级缓存中
13.5 缓存原理
流程图
代码实现
@Test
public void queryUserById(){
//创建两个sqlSession
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
System.out.println(user);
sqlSession.close();
System.out.println("=============================");
SqlSession sqlSession2 = MybatisUtils.getSqlSession();
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.queryUserById(1);
System.out.println(user2);
System.out.println("=============================");
User user3 = mapper2.queryUserById(2);
System.out.println(user2);
System.out.println(user3);
System.out.println("=============================");
User user4 = mapper2.queryUserById(2);
System.out.println(user3);
sqlSession2.close();
}
输出结果
Cache Hit Ratio [com.yin.dao.UserMapper]: 0.0
Opening JDBC Connection
Created connection 689654773.
==> Preparing: select * from user where id = ?
==> Parameters: 1(Integer)
<== Columns: id, name, pwd
<== Row: 1, 张三, 123
<== Total: 1
User(id=1, name=张三, pwd=123)
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@291b4bf5]
Returned connection 689654773 to pool.
=============================
As you are using functionality that deserializes object streams, it is recommended to define the JEP-290 serial filter. Please refer to https://docs.oracle.com/pls/topic/lookup?ctx=javase15&id=GUID-8296D8E8-2B93-4B9A-856E-0A65AF9B8C66
Cache Hit Ratio [com.yin.dao.UserMapper]: 0.5
User(id=1, name=张三, pwd=123)
=============================
Cache Hit Ratio [com.yin.dao.UserMapper]: 0.3333333333333333
Opening JDBC Connection
Checked out connection 689654773 from pool.
==> Preparing: select * from user where id = ?
==> Parameters: 2(Integer)
<== Columns: id, name, pwd
<== Row: 2, AAA, BBB
<== Total: 1
User(id=1, name=张三, pwd=123)
User(id=2, name=AAA, pwd=BBB)
=============================
Cache Hit Ratio [com.yin.dao.UserMapper]: 0.25
User(id=2, name=AAA, pwd=BBB)
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@291b4bf5]
Returned connection 689654773 to pool.
Process finished with exit code 0
代码讲解
Cache Hit Ratio [com.yin.dao.UserMapper]: 0.0
Opening JDBC Connection
Created connection 689654773.
//第一次查询 获取第一个用户
==> Preparing: select * from user where id = ?
==> Parameters: 1(Integer)
<== Columns: id, name, pwd
<== Row: 1, 张三, 123
<== Total: 1
User(id=1, name=张三, pwd=123)
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@291b4bf5]
//关闭连接,提交到二级缓存
Returned connection 689654773 to pool.
=============================
As you are using functionality that deserializes object streams, it is recommended to define the JEP-290 serial filter. Please refer to https://docs.oracle.com/pls/topic/lookup?ctx=javase15&id=GUID-8296D8E8-2B93-4B9A-856E-0A65AF9B8C66
//二号用户查用户时,直接从缓存中查
Cache Hit Ratio [com.yin.dao.UserMapper]: 0.5
User(id=1, name=张三, pwd=123)
=============================
//查二号用户的时候,缓存中没有,打开JDBC连接,从数据库中查
Cache Hit Ratio [com.yin.dao.UserMapper]: 0.3333333333333333
Opening JDBC Connection
Checked out connection 689654773 from pool.
==> Preparing: select * from user where id = ?
==> Parameters: 2(Integer)
<== Columns: id, name, pwd
<== Row: 2, AAA, BBB
<== Total: 1
User(id=1, name=张三, pwd=123)
User(id=2, name=AAA, pwd=BBB)
=============================
//第二次查二号用户,缓存中有二号用户
Cache Hit Ratio [com.yin.dao.UserMapper]: 0.25
User(id=2, name=AAA, pwd=BBB)
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@291b4bf5]
Returned connection 689654773 to pool.