MyBatis学习笔记(5)
来源:互联网 发布:淘宝新店怎么增加流量 编辑:程序博客网 时间:2024/06/08 14:59
MyBatis入门之延迟加载
resultMap可以实现高级映射(使用association、collection实现一对一及一对多映射),association、collection具备延迟加载功能。
延迟加载:先从单表查询、需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。
使用association实现延迟加载
- mapper.xml
需要定义两个mapper的方法对应的statement。
在查询博客的statement中使用association去延迟加载下边的satatement(博客作者,即关联的用户):
<select id="findBlogAndUser" resultMap="BlogAndUser"> SELECT * FROM tbl_blog </select>
通过上边的blogUserId来查询关联信息:
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" > select userId, userName from tbl_user where userId = #{userid,jdbcType=INTEGER} </select>
- 延迟加载resultMap
<resultMap type="com.icss.po.Blog" id="BlogAndUser"> <id property="blogid" column="blogId" /> <result property="blogtitle" column="blogTitle" /> <result property="blogcontent" column="blogContent" /> <association property="user" column="blogUserId" select="com.icss.dao.UserMapper.selectByPrimaryKey" javaType="com.icss.po.User"> <id property="userid" column="userId"/> <result property="username" column="userName" /> </association> </resultMap>
与非延迟加载的主要区别就在association标签属性多了select和column
- 延迟加载配置
在mybatis核心配置文件中配置:lazyLoadingEnabled、aggressiveLazyLoading
<settings> <setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/> </settings>
- 测试代码
@Test public void testfindBlogAndUserLoading() throws Exception{ SqlSession sqlSession =null; try { //mybatis配置文件 String resourse = "SqlMapConfig.xml"; //获取配置文件流 InputStream is = Resources.getResourceAsStream(resourse); //创建会话工厂 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //通过会话工厂获取SqlSession sqlSession = sqlSessionFactory.openSession(); //获取代理对象 BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class); List<Blog> list = blogMapper.findBlogAndUser(); for(int i=0;i<list.size();i++){ Blog blog = list.get(i); System.out.println("博客标题:"+blog.getBlogtitle()); System.out.println("博客内容:"+blog.getBlogcontent()); User user = blog.getUser(); System.out.println("博客作者:"+user.getUsername()); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ sqlSession.close(); } }
延迟加载思考
不使用mybatis提供的association及collection中的延迟加载功能,如何实现延迟加载??
实现方法如下:
定义两个mapper方法:
- 查询博客列表
- 根据用户id查询用户信息
实现思路:
先去查询第一个mapper方法,获取博客信息列表;在程序中(service),按需去调用第二个mapper方法去查询用户信息。
总之,使用延迟加载方法,先去查询简单的sql(最好单表,也可以关联查询),再去按需要加载关联查询的其它信息。
结果
DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.DEBUG [main] - PooledDataSource forcefully closed/removed all connections.DEBUG [main] - PooledDataSource forcefully closed/removed all connections.DEBUG [main] - PooledDataSource forcefully closed/removed all connections.DEBUG [main] - PooledDataSource forcefully closed/removed all connections.DEBUG [main] - Opening JDBC ConnectionDEBUG [main] - Created connection 552364977.DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@20ec6bb1]DEBUG [main] - ==> Preparing: SELECT * FROM tbl_blog DEBUG [main] - ==> Parameters: DEBUG [main] - <== Total: 1博客标题:Mybatis入门博客内容:Mybatis入门程序内容DEBUG [main] - ==> Preparing: select userId, userName from tbl_user where userId = ? DEBUG [main] - ==> Parameters: 1(Integer)DEBUG [main] - <== Total: 1博客作者:Mr_LiDEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@20ec6bb1]DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@20ec6bb1]DEBUG [main] - Returned connection 552364977 to pool.
注意
写代码过程中发现一个异常,然后并不是我自己引起的异常,而是因为导入的mybatis包版本问题,异常代码如下:
java.lang.NullPointerException at com.icss.TestMybatis.testfindBlogAndUserLoading(TestMybatis.java:333) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
这是mybatis依赖包OGNL 2.6.9的一个bug,可以通过升级mybatis版本到 3.3.0及以上来解决此问题。
mybatis官方issue说明: https://github.com/mybatis/mybatis-3/issues/224
- MyBatis学习笔记(5)
- mybatis学习笔记(5)-配置文件
- mybatis-generator 1.3.5 学习笔记
- mybatis 学习笔记
- MyBatis学习笔记
- mybatis学习笔记---入门
- MyBatis 学习笔记
- Mybatis学习笔记
- 【MyBatis学习笔记】系列
- Mybatis学习笔记
- mybatis学习笔记
- mybatis学习笔记
- MyBatis 学习笔记
- mybatis学习笔记
- mybatis学习笔记
- MyBatis学习笔记
- mybatis学习笔记
- Mybatis框架学习笔记
- [转] HTTPS详解SSL/TLS
- JavaWeb学习(二)
- windows 学习
- 猫哥带你去战斗—Java Web开发—Servlet篇[4]—JSP顺势而生
- 利用Python数据分析:pandas入门(五)
- MyBatis学习笔记(5)
- 位运算之两数相除
- 游戏UI框架设计(二)
- 历届试题 数字游戏
- Java笔记~ArrayList
- jmap、 jhat 分析堆内存溢出
- 36、C++对C语言的面向对象的扩充
- JavaSE_36th_Set接口
- 2001年北理复试上机题(B)