MyBatis中使用#和$的区别
#表示字符串,会对传入的数据自动加上引号。使用$可能导致sql注入攻击,所以尽量使用#。order by时候应该用$。
Xml映射文件中,有哪些常见的标签
<select>、<insert>、<update>、<delete>、<sql>、<include>、<resultMap>、<parameterMap>、<selectKey>。
<selectKey>为不支持自增的主键生成策略标签。
MyBatis延迟加载原理
创建目标对象的代理对象,当调用目标方法时候,进入拦截器方法,例如a.getA.getName(),拦截器invoke方法发现getA是null,那么就会单独发送事先保存好的查询关联A对象的sql,查询出来后,调用setA(),结果调用getName()。Hibernate同理。
-
Hibernate是全自动的、完全面向对象的持久层框架;Mybatis是半自动的持久层框架
-
Hibernate自动生成sql,简单但是可能会进行不必要的查询,消耗性能;Mybatis自己编写
Mybatis缓存机制
-
一级缓存是sqlSession级别缓存
基于HashMap的本地缓存,不同的sqlSession之间的缓存数据互不影响。默认开启一级缓存
-
二级缓存是mapper级别缓存,多个sqlSession共享
同样基于HashMap进行存储,多个sqlSession共用二级缓存,作用域是mapper的同一个namespace。不同的sqlSession执行两次相同的namespace下的sql,第二次查询不会去数据库查询。默认不开启。
#开启二级缓存
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
MyBatis工作原理
mybatis应用程序通过SqlSessionFactoryBuilder从mybatis-config.xml配置文件(也可以用Java文件配置的方式,需要添加@Configuration)来构建SqlSessionFactory(SqlSessionFactory是线程安全的);然后,SqlSessionFactory的实例直接开启一个SqlSession,再通过SqlSession实例获得Mapper对象并运行Mapper映射的SQL语句,完成对数据库的CRUD和事务提交,之后关闭SqlSession。
详细流程如下:
1、加载mybatis全局配置文件(数据源、mapper映射文件等),解析配置文件,MyBatis基于XML配置文件生成Configuration,和一个个MappedStatement(包括了参数映射配置、动态SQL语句、结果映射配置),其对应着<select | update | delete | insert>标签项。
2、SqlSessionFactoryBuilder通过Configuration对象生成SqlSessionFactory,用来开启SqlSession。
3、SqlSession对象完成和数据库的交互:
a、用户程序调用mybatis接口层api(即Mapper接口中的方法)
b、SqlSession通过调用api的Statement ID找到对应的MappedStatement对象
c、通过Executor(负责动态SQL的生成和查询缓存的维护)将MappedStatement对象进行解析,sql参数转化、动态sql拼接,生成jdbc Statement对象
d、JDBC执行sql。
e、借助MappedStatement中的结果映射关系,将返回结果转化成HashMap、JavaBean等存储结构并返回。