在一对一映射中使用:
首先配置延迟加载,需要在mybatis.xml中配置
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 配置是否为深度加载,默认就是false,所以也可以不写,使用侵入式加载就用true-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
mapper文件:
<!-- 一对一关系 延迟加载-->
<!-- 查询所用订单的sql-->
<select id="findOrderUserList" resultMap="resultMap_order_user">
select o.id,o.uid,o.number,o.createtime,o.des from t_orders o
</select>
<!-- 查询用户的sql,需要时才会使用此sql-->
<select id="findUserListToOrder" parameterType="int" resultType="user">
select u.id as id,u.username as username from t_user u where id=#{uid}
</select>
<resultMap id="resultMap_order_user" type="ordervo">
<id column="id" property="id"/>
<result column="uid" property="uid"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<!-- 延迟加载,配置后只有需要user的数据时,才会加载select中的语句-->
<association property="user" javaType="User" column="uid" select="findUserListToOrder">
<id column="id" property="id"/>
<result column="username" property="username"/>
</association>
</resultMap>
只有在使用到User的数据时才会加载查询Order的sql:
@Test
public void test2(){
IOrderMapper iOrderMapper = sqlSession.getMapper(IOrderMapper.class);
List<OrderVo> list = iOrderMapper.findOrderUserList();
for (OrderVo orderVo: list){
System.out.println(orderVo);
System.out.println(orderVo.getUser());
}
}
一对一延迟加载:
<resultMap id="resultMapfindPersonId" type="mybatis.pojo.Person">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="age" column="age" />
<result property="sex" column="sex" />
<association property="card" column="card_Id" javaType="mybatis.pojo.IdCard"
select="mybatis.mapper.IdCardMapper.findCodeById">
</association>
</resultMap>
<!--嵌套查询延迟结果 -->
<select id="findPersonID" resultMap="resultMapfindPersonId">
select * from t_person;
</select>
测试:
@org.junit.Test
public void testFindAll() throws Exception{
SqlSession sqlSession = MyBatisUtils.getSession();
System.out.println(sqlSession);
List<Person> accounts = sqlSession.selectList("mybatis.mapper.PersonMapper.findPersonID");
for (Person a:accounts){
System.out.println("-----------------------");
System.out.println(a );
System.out.println(a.getCard());
}
}
2021-02-04 10:50:32 [ main:788 ] - [ DEBUG ] org.apache.ibatis.datasource.pooled.PooledDataSource.popConnection(PooledDataSource.java:406) Created connection 1073533248.
2021-02-04 10:50:32 [ main:789 ] - [ DEBUG ] org.apache.ibatis.transaction.jdbc.JdbcTransaction.setDesiredAutoCommit(JdbcTransaction.java:101) Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@3ffcd140]
2021-02-04 10:50:32 [ main:793 ] - [ DEBUG ] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159) ==> Preparing: select * from t_person;
2021-02-04 10:50:32 [ main:869 ] - [ DEBUG ] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159) ==> Parameters:
2021-02-04 10:50:32 [ main:950 ] - [ DEBUG ] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159) <== Total: 4
-----------------------
2021-02-04 10:50:32 [ main:951 ] - [ DEBUG ] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159) ==> Preparing: SELECT * from t_idcard where id=?
2021-02-04 10:50:32 [ main:952 ] - [ DEBUG ] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159) ==> Parameters: 1(Integer)
2021-02-04 10:50:32 [ main:956 ] - [ DEBUG ] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159) <== Total: 1
Person(id=1, name=小米, age=12, sex=男, card=IdCard(id=1, code=2222222))
IdCard(id=1, code=2222222)
在调用到card信息时会自动调用sql查询,延迟加载产生的N+1问题从sql查询可以看出,person表查询一次 而card表要查询4次