http://blog.csdn.net/bear_wr/article/details/52383840
怎么让mapper.java和mapper.xml文件对应起来?
在mapper.xml文件中的<mapper>标签的namespace属性中配置对应的mapper.java文件即可。
<resultMap>是结果集映射到java实体的配置标签。解决了90%以上从jdbc结果集取数据的操作。深入了解<resultMap>前,先来看下sql查询出的结果集(ResultSet)到java实体的过程。
1.JDBC查询得到ResultSet对象。
2.遍历Result对象并将每行数据暂存到HashMap实例中,以结果集的字段名或字段别名为键,以字段值为值。
Mybatis的内部缓存使用一个HashMap,key为hashcode+statementId+sql语句。Value为查询出来的结果集映射成的java对象。
3.根据resultMap标签的type属性通过反射来实例化领域模型(最后返回的java实体/javaBean)
4.根据resultMap标签的type属性,id,result等标签信息将HashMap中的键值对填充到领域模型实例中并返回。
<resultMap id="用来标识resultMap" type="映射到的java类型">只用于查询操作,跟其他更新操作无关。
<result property="java实体中的属性" column=“数据库中字段名”>
<select id="与代码中对应" resultMap=“跟resultMap标签的id对应” parameterType=“传进sql中的java参数类型”>
返回集合和返回单个对象的配置一样。
mybatis一二级缓存
mybatis默认开启一级缓存,用户不能配置,一级缓存是数据库session会话级别的缓存,位于表示一次数据库会话的sqlSession对象之中,也叫本地缓存。二级缓存是应用级别的缓存,声明周期是整个应用,或者说它的作用范围是整个应用。缓存保存在hashmap中。
一级缓存原理:
一个sqlSession(对应一个事务)会使用一个executor对象来完成会话操作,executor对象会维护一个cache缓存。会话结束时缓存将清空,会话中执行的更新修改删除操作也会清空缓存。
二级缓存原理:
二级缓存的作用域是同一个namespace下的mapper映射文件内容,多个SqlSession共享
二级缓存也是对sqlSession的executor对象做文章,mybatis为sqlSession对象创建executor时,会给executor对象加上一个装饰者CachingExecutor,这时sqlSession使用cachingExecutor对象来完成操作请求。对于查询请求cachingExecutor会先检查应用范围的二级缓存中是否有缓存结果,有的话直接返回结果,没有则交给executor去执行查询。然后将查询结果放在二级缓存中再返回给用户。
接口绑定有几种实现方式,分别是怎么实现的?
接口绑定有两种实现方式,一种是通过注解绑定,就是在接口的方法上面加上
@Select@Update等注解里面包含Sql语句来绑定,另外一种就是通过xml里面写SQL来绑定,
在这种情况下,要指定xml映射文件里面的namespace必须为接口的全路径名.
什么情况下用注解绑定,什么情况下用xml绑定?
当Sql语句比较简单时候,用注解绑定,
当SQL语句比较复杂时候,用xml绑定,一般用xml绑定的比较多
#{},和 ${}传参的区别?
#{}能防止sql注入。动态排序比如orber by时必须用 ${}
Mybatis是如何进行分页的?分页插件的原理是什么?
答:Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页:
一:sql内直接书写带有物理分页的参数
MySql数据库提供了分页的函数limit m,n,但是该函数的用法和我们的需求不一样,所以就需要我们根据实际情况去改写适合我们自己的分页语句,具体的分析如下:
比如:
查询第1条到第10条的数据的sql是:select * from table limit 0,10; ->对应我们的需求就是查询第一页的数据:select * from table limit (1-1)*10,10;
查询第10条到第20条的数据的sql是:select * from table limit 10,20; ->对应我们的需求就是查询第二页的数据:select * from table limit (2-1)*10,10;
查询第20条到第30条的数据的sql是:select * from table limit 20,30; ->对应我们的需求就是查询第三页的数据:select * from table limit (3-1)*10,10;
通过上面的分析,可以得出符合我们自己需求的分页sql格式是:select * from table limit (start-1)*limit,limit; 其中start是页码,limit是每页显示的条数。
二:分页插件
分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。
举例:select * from student,拦截sql后重写为:select t.* from (select * from student)t limit 0,10
MyBatis使用RowBounds实现的分页是逻辑分页,也就是先把数据记录全部查询出来,然在再根据offset和limit截断记录返回
为了在数据库层面上实现物理分页,又不改变原来MyBatis的函数逻辑,可以编写plugin截获MyBatis Executor的statementhandler,重写SQL来执行查询
什么是延迟加载(懒加载/用于多表查询)
resultMap中的association(联系:一对一)和collection(集合:一对多)标签具有延迟加载的功能。
延迟加载的意思是说,在关联查询时,利用延迟加载,先加载主信息。使用关联信息时再去加载关联信息。
设置延迟加载
需要在SqlMapConfig.xml文件中,在<settings>标签中设置下延迟加载。
lazyLoadingEnabled、aggressiveLazyLoading
设置项 |
描述 |
允许值 |
默认值 |
lazyLoadingEnabled |
全局性设置懒加载。如果设为‘false’,则所有相关联的都会被初始化加载。 |
true | false |
false |
aggressiveLazyLoading |
当设置为‘true’的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。 |
true | false |
true |
|
想查询一个用户的时候,也查到他写的一篇文章,可以怎样写呢?
1、在类user加入一个属性article
private String id;//主键 private String userName;//用户姓名
private Article article;//新增的文章属性
2、mapper.xml 我在user类的mapper.xml这样配置
<resultMap id="userResultMap" type="test.mybatis.entity.User"> <id column="id" property="id" jdbcType="VARCHAR" javaType="java.lang.String"/> <result column="userName" property="userName" jdbcType="VARCHAR" javaType="java.lang.String"/>
//这里把user的id传过去 <association property="article" column="id" select="test.mybatis.dao.articleMapper.selectArticleByUserId"
一对多,collection,理解了一对一,一对多容易理解。
实体类增加对应属性
private String id;//主键 private String userName;//用户姓名 private List<Article> articleList;
userMapper.xml这样配置
<resultMap id="userResultMap" type="test.mybatis.entity.User"> <id column="id" property="id" jdbcType="VARCHAR" javaType="java.lang.String"/> <result column="userName" property="userName" jdbcType="VARCHAR" javaType="java.lang.String"/> //这里把user的id传过去 <collection property="articleList" column="id" select="test.mybatis.dao.articleMapper.selectArticleListByUserId" />
http://blog.csdn.net/wxwzy738/article/details/24742495
http://www.cnblogs.com/yansum/p/5819973.html
<result column="数据库字段名" property="实体类属性" jdbcType="数据库字段类型" />
</resultMap>
mybatis代码的使用:只写一个dao的mapper.java接口就可以了,由service调用并与mapper.xml对应即可。那么,service是怎么实实在在的去调用一个接口的(看起来参数都传给接口了)。????????
mybatis的useGeneratedKeys和keyProperty属性的含义:
keyProperty是java对象的属性名。mybatis执行完插入语句后,自动将自增长值赋值给java对象的该属性,之后可以直接get该属性值。