Mybatis延迟加载
目的:延迟加载其实就是为了推迟嵌套查询时机,避免一些无谓的性能浪费。
如有两张表,good与goodstype是一对多关系,一个goodstype可以对应多个good。当想要查询goodstype表以及每种typename对应的goods时,及时加载(aggressiveLazyLoading)会立即执行所有sql语句,一次性返回所有结果。但是如果后续没有调用每种typename对应的goods时,这就造成了性能开销。而这时如果使用延迟加载,sql会先执行查询goodstype的语句,当后续需要调用typename对应的goods时,则才继续调用sql语句查询good。
Mybatis实现
1.编写实体层
public class Good {
private Integer id;
private String gname;
private int goodstype_id;
//以及它们的的set与get方法
}
public class GoodStype {
private Integer id;
private String typename;
private List<Good> goods;
//以及它们的的set与get方法
}
2.编写spring配置文件
配置数据源
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="url" value="自己数据库的url地址"></property>
<property name="driverClassName" value="驱动器名称"></property>
<property name="username" value="账户名称"></property>
<property name="password" value="账户密码"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!-- 关联mybatis位置-->
<property name="configLocation" value="classpath:mybatis.xml"> </property>
</bean>
<!-- 扫描Mapper注解 放入容器-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="mybatis"></property>
</bean>
3.编写mybatis配置文件
<configuration>
<settings>
<!-- 开启延迟加载,关闭及时加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
<!-- 加载mapper映射路径-->
<mappers>
<mapper resource="Mybatis/Good.xml"/>
<mapper resource="Mybatis/GoodStype.xml"/>
</mappers>
</configuration>
4.编写mapper映射文件
@Mapper
@Repository
public interface GoodMapper {
public List<Good> all();
public List<Good> querygoodsbygoodstype_id();
}
@Mapper
@Repository
public interface GoodStypeMapper{
public List<GoodStype> all();
public List<GoodStype> queryGoodsbyStype();
}
<mapper namespace="mybatis.GoodMapper">
<select id="querygoodsbygoodstype_id" parameterType="int" resultType="po.Good">
select * from goodstable where goodstype_id=#{id}
</select>
</mapper>
<mapper namespace="mybatis.GoodStypeMapper">
<select id="queryGoodsbyStype" resultMap="GoodStype-Good">
select * from goodstype
</select>
<resultMap type="po.GoodStype" id="GoodStype-Good">
<id property="id" column="id"/>
<result property="typename" column="typename"/>
<!-- property为配置的属性名称, ofType为返回的类型,select则为后续需要调用的sql语句的路径, column则为选择传入下一个sql语句的值-->
<collection property="goods" ofType="po.Good" select="mybatis.GoodMapper.querygoodsbygoodstype_id" column="id">
</collection>
</resultMap>
</mapper>
5.编写测试类
public class TestMybatis {
public static void main(String[] args) {
// 加载spring容器
ApplicationContext a=new ClassPathXmlApplicationContext("applicationContext.xml");
//获取GoodStypeMapper对象
GoodStypeMapper gsi=(GoodStypeMapper)a.getBean("goodStypeMapper");
//调用方法并遍历GoodStype的属性,在此处设置断点,并在后台观看gs的值,会发现gs中每个GoodStype的goods属性值为null
List<GoodStype> gs=gsi.queryGoodsbyStype();
for(GoodStype i:gs) {
System.out.println(i.getId()+" "+i.getTypename());
}
//这时遍历GoodStype中goods的值,发现原来为null的goods属性值发生改变,原因就是启用了延迟加载,在需要调用时才执行后续的sql语句。
for(GoodStype i:gs) {
System.out.print(i.getId()+" "+i.getTypename());
for(Good k:i.getGoods()) {
System.out.println(k.toString());
}
}
}
}
6.实验结果
后续调用goods属性时,属性值发生改变。