Mybatis
2021-05-07 14:20:50 0 举报
AI智能生成
Mybatis主要API及常见问题解答
作者其他创作
大纲/内容
Java API
SqlSession: 使用这个接口执行命令,获 取映射器和管理事务
语句执行方法
T selectOne(String statement)
List selectList(String statement)
Map selectMap(String statement, String mapKey)
int insert(String statement)
int update(String statement)
int delete(String statement)
<E> List<E> selectList (String statement, Object parameter, RowBounds rowBounds)
<K,V> Map<K,V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowbounds)
void select (String statement, Object parameter, ResultHandler<T> handler)
void select (String statement, Object parameter, RowBounds rowBounds, ResultHandler<T> handler)
事务控制方法
void commit()
void commit(boolean force)
void rollback()
void rollback(boolean force)
清理 Session 级的缓存
void clearCache()
清理 Session 级的缓存
void close()
SqlSessionFactoryBuilder: 从 XML 配置,注解或手动配置 Java 来创建 SqlSessionFactory
SqlSessionFactory: 创建SqlSession
SqlSessionFactory 用来创建 SqlSession 实例
- SqlSession openSession()
- SqlSession openSession(boolean autoCommit)
- SqlSession openSession(Connection connection)
- SqlSession openSession(TransactionIsolationLevel level)
- SqlSession openSession(ExecutorType execType,TransactionIsolationLevel level)
- SqlSession openSession(ExecutorType execType)
- SqlSession openSession(ExecutorType execType, boolean autoCommit)
- SqlSession openSession(ExecutorType execType, Connection connection)
- Transaction (事务): 你想为 session 使用事务或者使用自动提交
- Connection (连接): 你想 MyBatis 获得来自配置的数据源的连接还是提供你自己
- Execution (执行): 你想 MyBatis 复用预处理语句和/或批量更新语句(包括插入和 删除)
常见问题
MyBatis和ORM的区别
mybatis属于半orm,因为sql语句需要自己写。
与其他比较标准的 ORM 框架(比如 Hibernate )不同, mybatis 并没有将 java 对象与数据库关联起来,而是将 java 方法与 sql 语句关联起来,mybatis 允许用户充分利用数据库的各种功能,例如存储、视图、各种复杂的查询以及某些数据库的专有特性。
与其他比较标准的 ORM 框架(比如 Hibernate )不同, mybatis 并没有将 java 对象与数据库关联起来,而是将 java 方法与 sql 语句关联起来,mybatis 允许用户充分利用数据库的各种功能,例如存储、视图、各种复杂的查询以及某些数据库的专有特性。
MyBatis 中#{}和${}区别
#{} 是预编译处理,像传进来的数据会加个" "(#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号)
${} 就是字符串替换。直接替换掉占位符。$方式一般用于传入数据库对象,例如传入表名. 使用 ${} 的话会导致 sql 注入。
MyBatis接口绑定的几种方式
1、使用注解,在接口的方法上面添加@Select@Update等注解,里面写上对应的SQL语句进行SQL语句的绑定。
2、通过映射文件xml方式进行绑定,指定xml映射文件中的namespace对应的接口的全路径名
通常一个mapper.XML对应一个DAO接口,DAO是否可以重载?
不能重载,方法名对应的 mapper.xml 文件里的一个 id,这个与方法名对应,系统会根据 namespace+id 找到对应的方法对应。
Dao 接口即 Mapper 接口。接口的全限名,就是映射文件中的 namespace 的值;接口的方法名,就是映射文件中 Mapper 的 Statement 的 id 值;接口方法内的参数,就是传递给 sql 的参数。Mapper 接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为 key 值,可唯一定位一个 MapperStatement。在 Mybatis 中,每一个标签,都会被解析为一个MapperStatement 对象。
举例:com.mybatis3.mappers.StudentDao.findStudentById,可以唯一找到 namespace 为 com.mybatis3.mappers.StudentDao 下面 id 为findStudentById 的 MapperStatement。
举例:com.mybatis3.mappers.StudentDao.findStudentById,可以唯一找到 namespace 为 com.mybatis3.mappers.StudentDao 下面 id 为findStudentById 的 MapperStatement。
Mapper 接口里的方法,是不能重载的,因为是使用 全限名+方法名 的保存和寻找策略。Mapper 接口的工作原理是 JDK 动态代理,Mybatis 运行时会使用 JDK动态代理为 Mapper 接口生成代理对象 proxy,代理对象会拦截接口方法,转而执行 MapperStatement 所代表的 sql,然后将 sql 执行结果返回。
MyBatis映射文件中A标签引用B标签,如果B标签在A的后面定义,可以吗?
Mybatis 解析 A 标签时,发现引用了 B 标签,未解析到 B 标签,此时会把 A 标签标记为未解析状态;
继续解析下面内容,把剩下解析完之后,再解析标记为未解析的标签;
此时已解析到 B 标签,此时再解析A标签时,B标签已经存在,A 标签也就顺利解析完成。
MyBatis不同映射文件中的id是否可以重复?
可以重复,但是需要映射文件的namespace不同
原因就是 namespace+id 是作为 Map<String, MapperStatement>的 key使用的,如果没有 namespace,就剩下 id,那么,id 重复会导致数据互相覆盖。有了 namespace,自然 id 就可以重复,namespace 不同,namespace+id 自然也就不同。
原因就是 namespace+id 是作为 Map<String, MapperStatement>的 key使用的,如果没有 namespace,就剩下 id,那么,id 重复会导致数据互相覆盖。有了 namespace,自然 id 就可以重复,namespace 不同,namespace+id 自然也就不同。
MyBatis如何获取自动生成的主键id
MySQL:Mapper 文件 insert 语句设置
useGeneratedKeys="true" keyProperty="id"
Oracle:Mapper 文件 insert 语句增加
<selectKey keyProperty="id" order="BEFORE" resultType="Integer">
select xxx_SEQ.nextval from dual
</selectKey>
select xxx_SEQ.nextval from dual
</selectKey>
MyBatis 传递多个参数
方法一:使用map接口传递参数
方法二:使用注解@Param传递多个参数
方法三:通过Java Bean传递多个参数
方法四:混合使用
MyBatis缓存机制
一级缓存
一级缓存为 sqlsesson 缓存,缓存的数据只在 SqlSession 内有效。
在操作数据库的时候需要先创建 SqlSession 会话对象,在对象中有一个 HashMap 用于存储缓存数据,此 HashMap 是当前会话对象私有的,别的 SqlSession 会话对象无法访问。
在操作数据库的时候需要先创建 SqlSession 会话对象,在对象中有一个 HashMap 用于存储缓存数据,此 HashMap 是当前会话对象私有的,别的 SqlSession 会话对象无法访问。
第一次执行 select 完毕会将查到的数据写入 SqlSession 内的 HashMap 中缓存起来
第二次执行 select 会从缓存中查数据,如果 select 同传参数一样,那么就能从缓存中返回数据,不用去数据库了,从而提高了效率
如果 SqlSession 执行了 DML 操作(insert、update、delete),并 commit 了,那么 mybatis 就会清空当前 SqlSession 缓存中的所有缓存数据,这样可以保证缓存中的存的数据永远和数据库中一致,避免出现差异
当一个 SqlSession 结束后那么他里面的一级缓存也就不存在了, mybatis 默认是开启一级缓存,不需要配置
mybatis 的缓存是基于 [namespace:sql语句:参数] 来进行缓存的,意思就是, SqlSession 的 HashMap 存储缓存数据时,是使用 [namespace:sql:参数] 作为 key ,查询返回的语句作为 value 保存的
二级缓存
二级缓存是 mapper 级别的缓存,也就是同一个 namespace 的 mapper.xml ,当多个 SqlSession 使用同一个 Mapper 操作数据库的时候,得到的数据会缓存在同一个二级缓存区域
二级缓存默认是没有开启的。需要在 setting 全局参数中配置开启二级缓存
1.当一个 sqlseesion 执行了一次 select 后,在关闭此 session 的时候,会将查询结果缓存到二级缓存
2.当另一个 sqlsession 执行 select 时,首先会在他自己的一级缓存中找,如果没找到,就回去二级缓存中找,找到了就返回,就不用去数据库了,从而减少了数据库压力提高了性能
0 条评论
下一页