黑马程序员mybatis教程第二天:延迟加载

合集下载

黑马程序员mybatis教程第二天:查询缓存

黑马程序员mybatis教程第二天:查询缓存

查询缓存什么是查询缓存mybatis提供查询缓存,用于减轻数据压力,提高数据库性能。

mybaits提供一级缓存,和二级缓存。

一级缓存是SqlSession级别的缓存。

在操作数据库时需要构造 sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。

不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。

二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

为什么要用缓存?如果缓存中有数据就不用从数据库中获取,大大提高系统性能。

一级缓存一级缓存工作原理第一次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,如果没有,从数据库查询用户信息。

得到用户信息,将用户信息存储到一级缓存中。

如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession 中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。

第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。

一级缓存测试mybatis默认支持一级缓存,不需要在配置文件去配置。

按照上边一级缓存原理步骤去测试。

@Testpublicvoid testCache1() throws Exception{SqlSession sqlSession = sqlSessionFactory.openSession();//创建代理对象UserMapper userMapper =sqlSession.getMapper(UserMapper.class);//下边查询使用一个SqlSession//第一次发起请求,查询id为1的用户User user1 = userMapper.findUserById(1);System.out.println(user1);// 如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。

ssh下基于junit测试出现的延迟加载的解决方案

ssh下基于junit测试出现的延迟加载的解决方案

ssh下基于junit测试出现的延迟加载的解决方案篇一:ssh框架常见错误与解决方法not Found Exception 异常.---->解决方法:在lib中加入两个jar包(与struts2- );2.使用hql语句时出现(即使用hql回调函数带参数时) 或者是()I异常---->解决方法:(()I异常XX-04-06 14:56:57| 分类: java编程 | 标签:antlr jar collections ast getline |字号大中小订阅我用的,装在 D:\\,SSH组合完成后,执行hibernate 的HQL查询时,报错:: ()I看来是antlr这个语法解析包出错因为Struts自带的,比自带的的版本要低,故要删除前一个低版本的,,和都带有 ,,,下面我要把它们都清除了,由于myeclipse 添加的struts性能不是放在工程lib下的,而是myeclipse自带的,,所以删除比较麻烦,,我觉得最简单的做法应该是这样:D:\\\configuration\\bundles 下搜索完成后能看到的,都删除掉,,(可能有些是在下面的,有些是在下面的) 然后在 D:\\Common\plugins 搜索 *struts*.jar 会发现,出来三个选中一个文件,,打开方式选择压缩包,,我的winRAR 的,_ 在lib下和data\下要删除(这个是删除里面的)而再打开 _ data\\core 下删除 (这个是里面的)好了,,这个就从和中移除了,,因为这两个jar是common目录下的,所以删除了后,再运行myeclipse后,myeclipse就不能再从这两个包中找并加载了注意:如果程序已经运行过,则同时需要删除TOMCAT 下的)3.(使用JSONObject与JSONArray时出现的问题)程序运行到 JSONObject j=(map) 这部分后就没反应了,无任何异常抛出---->解决方法:(本文来自:blog_这句话前面和后面都加上了打印信息,运行结果是前面有打印,后面没有打印,也没有任何异常抛出,就这么莫名其妙的断掉了。

关于延迟加载(lazy)和强制加载

关于延迟加载(lazy)和强制加载
信息,那么自动加载address的特性就显得多余,并且造成了极大的性能浪费。为了获得user 的性别属性,我们可能还要同时从数据库中读取数条无用的地址数据,这导致了大量无谓的系统开销。
延迟加载特性的出现,正是为了解决这个问题。所谓延迟加载,就是在需要数据的时候,才真正执行数据加载操作。
对于我们这里的user对象的加载过程,也就意味着,加载user对象时只针对其本身的属性, 而当我们需要获取user对象所关联的address信息时(如执行user.getAddresses时),才
TUser user = (TUser)session.load(TUser.class,new Integer(1));
VO经过Hibernate进行处理,就变成了PO。上面的示例代码session.save(user)中,我们把一个VO “user”传递给Hibernate的Session.save方法进行保存。在save方法中,Hibernate对其进
TUser user =(TUser)userList.get(0);
System.out.println("User name => "+user.getName());
Set hset = user.getAddresses();
session.close();//关闭Session
这里有个问题,如果我们采用了延迟加载机制,但希望在一些情况下,实现非延迟加载时的功能,也就是说,我们希望在Session关闭后,依然允许操作user的addresses
属性。如,为了向View层提供数据,我们必须提供一个完整的User对象,包含其所关联的address信息,而这个User对象必须在Session关闭之后仍然可以使用。

【黑马程序员】类加载器的解析

【黑马程序员】类加载器的解析

【黑马程序员】类加载器的解析为什么要使用类加载器类加载器作用于类加载过程中加载环节,是将.class文件加载进入内存时所使用到的技术,下文介绍类加载器类加载的机制加载: 1.取得类的二进制流, 2.转为方法区数据结构, 3.在Java堆中生成对应ng.Class对象链接1.验证:保证Class流的格式是正确的一、文件格式的验证(是否以0xCAFEBABE开头)。

二、元数据验证(是否有父类,继承了final类?非抽象类实现了所有的抽象方法。

三、字节码验证 (很复杂)。

四、符号引用验证)2.准备:分配内存,并为类的静态变量设置默认初始值(方法区中),注意:此时对象并未创建,且常量在该阶段就完成赋值3.解析:符号引用替换为直接引用1)、符号引用:Java中,一个java类将会编译成一个class文件。

在编译时,java类并不知道所引用的类的实际地址,因此只能使用符号引用来代替。

比如org.simple.People类引用了nguage类,在编译时People类并不知道Language类的实际内存地址2)、直接引用:、实际内存地址,指向了实际的内存如果有了直接引用,那引用的目标必定已经被加载入内存中了。

初始化:执行类构造器 1、static变量赋值语句 2、static{}语句 3、子类的调用前保证父类的被调用 4、是线程安全的判断什么时候需要进行初始化有6种情况称之为主动使用,在主动使用的情况下,该类会被类加载器加入内存,且进行初始化,除此以外都不会加载该类创建类的实例–访问某个类或接口的静态变量,或者对该静态变量赋值–调用类的静态方法–反射(如Class.forName(“ng.String”)–初始化一个类的子类– Java虚拟机启动时被标明为启动类的类(Java Test)类加载器的介绍BootStrap ClassLoader (启动ClassLoader,根类加载器)rt.jar ng Extension ClassLoader (扩展ClassLoader)ext包下的内容App ClassLoader (应用ClassLoader/系统ClassLoader)开发人员自己写的Custom ClassLoader(自定义ClassLoader) 根类加载器并不是由Java代码写的,且sun公司也不提供对根类加载器的任何操作,想要拿到这个一个加载器,返回的结果是null除了根类加载器以外,其他的加载器都是java代码写的,上一层是下一层的父容器,值得注意的是他们并不是一个继承关系,而是逻辑上的父子关系启动类加载器,由C++实现,没有父类。

解析Mybatis延迟加载问题

解析Mybatis延迟加载问题

解析Mybatis延迟加载问题延迟加载问题MyBatis针对关联表中的数据⽀持延迟加载。

延迟加载其实就是将数据加载时机推迟,⽐如推迟嵌套查询的执⾏时机。

延迟加载可以实现先查询主表,按需实时做关联查询,返回关联表结果集,⼀定程度上提⾼了效率。

<settings><!-- 启⽤延迟加载特性,不配置默认关闭该特性--><setting name="lazyLoadingEnabled" value="true" /><!-- 按需加载: false:使⽤关联属性时才进⾏加载; true加载对象,则加载所有属性 --><setting name="aggressiveLazyLoading" value="false"/></settings>lazyLoadingEnabled:是否启⽤延迟加载,默认值为false,不启⽤延迟加载。

lazyLoadingEnabled属性控制全局是否使⽤延迟加载,特殊关联关系也可以通过嵌套查询中fetchType属性单独配置(fetchType属性值可以是lazy或者eager)aggressiveLazyLoading:是否按需加载属性,默认值false,lazyLoadingEnabled属性启⽤时只要加载对象,就会加载该对象的所有属性;关闭该属性则会按需加载,即使⽤到某关联属性时,实时执⾏嵌套查询加载该属性对⼀<resultMap id="ExtResultMap" type="er" extends="BaseResultMap"><association property="role" select="com.yan.dao.RoleMapper.selectByPrimaryKey" column="role_id"/></resultMap>如果不访问role属性,则不会执⾏t_roles表的查询。

Hibernate学习--hibernate延迟加载原理(动态代理)

Hibernate学习--hibernate延迟加载原理(动态代理)

Hibernate学习--hibernate延迟加载原理(动态代理)在正式说hibernate延迟加载时,先说说⼀个⽐较奇怪的现象吧:hibernate中,在many-to-one时,如果我们设置了延迟加载,会发现我们在eclipse的调试框中查看one对应对象时,它的内部成员变量全是null的(因为这个原因我还调了好久的代码!),贴张图给你们感受下:左边是设置延迟加载的调试图,右边是没设置延迟加载的⽰意图;ok,估计⼤家也理解我说什么了,下⾯就从这个现象进作为⼊⼝,阐述hibernate延迟加载背后的原理----动态代理。

⼀、hibernate的延迟加载与动态代理 1、hibernate中的延迟加载:get VS load 我们知道,在hibernate⽅法中,直接涉及到延迟加载的⽅法有get和load,使⽤get时,不会延迟加载,load则反之。

另外,在many-to-one等关系配置中,我们也可以通过lazy属性设置是否延迟加载,这是我们对hibernate最直观的认识。

2、现象解释----动态代理机制 所以,开头说到的奇怪现象的原因是什么呢?其实在hibernate设置延迟加载后,hibernate返回给我们的对象(要延迟加载的对象)是⼀个代理对象,并不是真实的对象,该对象没有真实对象的数据,只有真正需要⽤到对象数据(调⽤getter等⽅法时)时,才会触发hibernate去数据库查对应数据,⽽且查回来的数据不会存储在代理对象中,所以这些数据是⽆法在调试窗⼝查看到的。

如果在调试是要查看该数据,我们可以查看代理对象中的hadler属性中的target变量,该对象变量才是真实的对象,看下⾯截图:也就是说,我们user变量仅仅是⼀个代理类,target才是真正数据库中获取的数据。

当我们在调⽤getter⽅法式,hibernate会利⽤动态代理的⽅法,直接调⽤target中的getter⽅法发挥对应的值。

MyBatis官方中文文档

MyBatis官方中文文档

提示 命名空间的一点注释
命名空间(Namespaces)在之前版本的 MyBatis 中是可选的,容易引起混淆因此是没有益处的。现在的命名空 间则是必须的,目的是希望能比只是简单的使用更长的完全限定名来更进一步区分语句。 命名空间使得你所见到的接口绑定成为可能,尽管你觉得这些东西未必用得上,你还是应该遵循这里的规定以防哪 天你改变了主意。出于长远考虑,使用命名空间,并将它置于合适的 Java 包命名空间之下,你将拥有一份更加整 洁的代码并提高了 MyBatis 的可用性。 命名解析:为了减少输入量,MyBatis 对所有的命名配置元素(包括语句,结果映射,缓存等)使用了如下的命名 解析规则。 完全限定名(比如“com.mypackage.MyMapper.selectAllThings”)将被直接查找并且找到即用。 短名称(比如“selectAllThings”)如果全局唯一也可以作为一个单独的引用。如果不唯一,有两个或两个以上的相 同名称(比如“com.foo.selectAllThings ”和“com.bar.selectAllThings”),那么使用时就会收到错误报告说短名称 是不唯一的,这种情况下就必须使用完全限定名。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-////DTD Config 3.0//EN" "/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <mappers> <mapper resource="org/mybatis/example/BlogMapper.xml"/> </mappers> </configuration>

黑马程序员资料参考

黑马程序员资料参考

目录北京黑马培训简介: (2)报名流程: (2)自学课程: (2)上课时间安排:(实行指纹打卡,迟到10天以上劝退!) (3)课程设置:(四个月集训) (3)培训费用: (3)师资力量:(部分) (3)往届课程参考: (6)黑马晨读资料: (14)(ref. full specialization) (22)CCP(communication[kə,mju:ni'keiʃən]control [kən'trəul]processor ['prəusesə]) 通信控制处理机 (27)MIPS(millions of instructions per second 每秒百万条指令 (30)学习路线图: (40)北京黑马培训 JAVA Android IOS北京黑马培训简介:报名流程:1.网上填写报名信息,并进入报名系统提交一封自荐信(3000字左右)2.下载基础测试,测试基础知识掌握情况。

(3天左右做完)3.根据基础测试结果,自学相应的技术视频4.需要写10篇技术blog、在黑马论坛与志同道合的朋友交流。

(积累技术分)5.技术储备好了,就可以参加入学考试了。

(一份试卷,一天内完成)6.预约老师,进行远程面试。

(面试时间30分钟以上,主要是技术性问题)自学课程:黑马程序员JavaEE+Android——开学前自学的Java课程(提供这些课程的视频下载)◇基础好:视频学习周期建议为5—10天,具体根据学生自学能力,自行合理安排时间。

第一阶段:Java基础(1-2天)●Java高级视频_IO输入与输出●Java高级视频_网络编程第二阶段:Java基础加强(3-4天)●2016年Java高新技术第三阶段:7k月薪面试题破解(2天)●交通灯管理系统视频●银行业务调度系统◇没有基础:视频学习周期建议为20-40天,具体根据学生自学能力,自行合理安排时间。

第一阶段:Java初级(8-15天)●Java开发前奏●Java编程基础●面向对象●多线程●JavaAPI第二阶段:Java基础(6-8天)●Java高级视频_IO输入与输出●图形用户界面GU●Java高级视频_网络编程第三阶段:Java基础加强(5-7天)●2016年Java高新技术第四阶段:7k月薪面试题破解(2-3天)●交通灯管理系统视频●银行业务调度系统上课时间安排:(实行指纹打卡,迟到10天以上劝退!)作息时间:早8:30——晚8:30早8:30——9:00 英语晨读时间,掌握软件开发常用词汇早9:00——12:00 上午上课时间12:00——14:00 午餐和午休时间14:00——17:00 下午上课时间17:00——18:00 晚餐时间18:00——20:30 晚自习时间课程设置:(四个月集训)第一阶段:Html+CSS+JavaScript基础第二阶段:JavaWEB+JavaMail开发技术+网上银行交易系统+网上在线支付第三阶段:Android核心基础第四阶段:Android高级+Git版本管理+linux+Webservice技术第五阶段:Android项目实战:手机卫士+321播放器+红孩子电子商城+植物大战僵尸+智能短信分类管理+豆瓣客户端+手机彩票等等第六阶段:就业面试与指导、现场招聘一个班级有7、8个讲师,其中3个主讲班型:大班70人左右上课形式:讲师一天讲5个小时左右,讲课过程中每敲一行代码,讲解一行代码;课下学员自己找时间练习。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

延迟加载
什么是延迟加载
resultMap可以实现高级映射(使用association、collection实现一对一及一对多映射),association、collection具备延迟加载功能。

需求:
如果查询订单并且关联查询用户信息。

如果先查询订单信息即可满足要求,当我们需要查询用户信息时再查询用户信息。

把对用户信息的按需去查询就是延迟加载。

延迟加载:先从单表查询、需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。

使用association实现延迟加载
需求
查询订单并且关联查询用户信息
mapper.xml
需要定义两个mapper的方法对应的statement。

1、只查询订单信息
SELECT * FROM orders
在查询订单的statement中使用association去延迟加载(执行)下边的satatement(关联查询用户信息)
2、关联查询用户信息
通过上边查询到的订单信息中user_id去关联查询用户信息
使用UserMapper.xml中的findUserById
上边先去执行findOrdersUserLazyLoading,当需要去查询用户的时候再去执行findUserById,通过resultMap的定义将延迟加载执行配置起来。

延迟加载resultMap
使用association中的select指定延迟加载去执行的statement的id。

<!-- 延迟加载的resultMap -->
<resultMap type="cn.itcast.mybatis.po.Orders"id="OrdersUserL azyLoadingResultMap">
<!--对订单信息进行映射配置 -->
<id column="id"property="id"/>
<result column="user_id"property="userId"/>
<result column="number"property="number"/>
<result column="createtime"property="createtime"/>
<result column="note"property="note"/>
<!-- 实现对用户信息进行延迟加载
select:指定延迟加载需要执行的statement的id(是根据
user_id查询用户信息的statement)
要使用userMapper.xml中findUserById完成根据用户
id(user_id)用户信息的查询,如果findUserById不在本mapper中需要前边加namespace
column:订单信息中关联用户信息查询的列,是user_id
关联查询的sql理解为:
SELECT orders.*,
(SELECT username FROM USER WHERE er_id =
user.id)username,
(SELECT sex FROM USER WHERE er_id = user.id)sex FROM orders
-->
<association property="user"javaType="cn.itcast.mybatis.po.U ser"
select="erMapper.findUserById"co
lumn="user_id">
<!-- 实现对用户信息进行延迟加载 -->
</association>
</resultMap>
mapper.java
测试
测试思路:
1、执行上边mapper方法(findOrdersUserLazyLoading),内部去调用
cn.itcast.mybatis.mapper.OrdersMapperCustom中的findOrdersUserLazyLoading只查询orders信息(单表)。

2、在程序中去遍历上一步骤查询出的List<Orders>,当我们调用Orders中的getUser方法时,开始进行延迟加载。

3、延迟加载,去调用UserMapper.xml中findUserbyId这个方法获取用户信息。

延迟加载配置
mybatis默认没有开启延迟加载,需要在SqlMapConfig.xml中setting配置。

在mybatis核心配置文件中配置:
在SqlMapConfig.xml中配置:
测试代码
延迟加载思考
不使用mybatis提供的association及collection中的延迟加载功能,如何实现延迟加载??
实现方法如下:
定义两个mapper方法:
1、查询订单列表
2、根据用户id查询用户信息
实现思路:
先去查询第一个mapper方法,获取订单信息列表
在程序中(service),按需去调用第二个mapper方法去查询用户信息。

总之:
使用延迟加载方法,先去查询简单的sql(最好单表,也可以关联查询),再去按需要加载关联查询的其它信息。

相关文档
最新文档