原代码设计:
一个用户有多个账户,是一对多的关系,用Collection集合关联;一个账户独属于一个用户,是一对一的关系,用association来关联;
UserMapper.xml
<mapper namespace="com.xuetu.springboot.mapper.UserMapper"> <!-- 定义User的resultMap--> <resultMap id="userMap" type="user"> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="address" column="address"></result> <result property="sex" column="sex"></result> <result property="birthday" column="birthday"></result> <!-- 配置user对象中accounts集合的映射 --> <collection property="accounts" ofType="account" select="com.xuetu.springboot.mapper.AccountMapper.findAccountByUid" column="id" /> </resultMap> <!-- 查询所有 --> <select id="findAll" resultMap="userMap"> select * from user </select> <!-- 根据id查询用户 --> <select id="findById" parameterType="INT" resultMap="userMap"> select * from user where id = #{uid} </select>
AccountMapper.xml
<mapper namespace="com.xuetu.springboot.mapper.AccountMapper"> <resultMap id="accountMap" type="account"> <id property="id" column="id" /> <result property="uid" column="uid" /> <result property="money" column="money" /> <association property="user" column="uid" select="com.xuetu.springboot.mapper.UserMapper.findById" /> </resultMap> <select id="findAll" resultMap="accountMap"> select * from account; </select> <select id="findAccountByUid" resultMap="accountMap" parameterType="INT"> select * from account where uid = #{uid} </select>
问题发现:
使用懒加载的情况下,如果仅仅是在controller 中操作一些数据,不把数据返回前端,那么没有问题,但是如果需要把数据集合变成JSON格式 返回给前端就会无限循环的进行SQL语句的查询,因为collection中select 寻找的是对象,这个对象又进行一对一关联查询,获得的对象又进行一对多关联查询,以此循环往复,最终导致内存溢出。
希望的效果是:如果返回用户集合,这个集合中各个用户的只有一个账户列表(一对多),账户对象一对一指向为空
例如下列数据:
[{"id":41,"username":"老王","address":"北京","sex":"男","birthday":"2018-02-27T17:47:08.000+0000","accounts":[{"id":1,"uid":41,"money":1000.0,"user":null},{"id":3,"uid":41,"money":3000.0,"user":null}]},{"id":42,"username":"小二王","address":"北京金燕龙","sex":"女","birthday":"2018-03-02T15:09:37.000+0000","accounts":[]},{"id":43,"username":"小二九","address":"北京金燕龙","sex":"女","birthday":"2018-03-04T11:34:34.000+0000","accounts":[{"id":2,"uid":43,"money":2000.0,"user":null}]},{"id":45,"username":"传智播客","address":"北京金燕龙","sex":"男","birthday":"2018-03-04T12:04:06.000+0000","accounts":[]},{"id":46,"username":"老久","address":"北京","sex":"女","birthday":"2018-03-07T17:37:26.000+0000","accounts":[]},{"id":48,"username":"小马宝莉","address":"北京修正","sex":"女","birthday":"2018-03-08T11:44:00.000+0000","accounts":[]},{"id":51,"username":"李四","address":"广西南宁市","sex":"男","birthday":"2019-07-21T06:29:22.000+0000","accounts":[]},{"id":52,"username":"王五","address":"广西桂林市","sex":"男","birthday":"2019-07-20T08:19:50.000+0000","accounts":[]}]解决办法:新增一个单独指向不关联的方法
UserMapper中:<!-- 定义User的resultMap--> <resultMap id="userMap" type="user"> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="address" column="address"></result> <result property="sex" column="sex"></result> <result property="birthday" column="birthday"></result> <!-- 配置user对象中accounts集合的映射 --> <collection property="accounts" ofType="account" select="com.xuetu.springboot.mapper.AccountMapper.findAccountByUidNoRel" column="id" /> </resultMap>AccountMapper中: <!--返回的对象是Account普通对象,而不是原来的accountMap-->
<select id="findAccountByUidNoRel" resultType="account" parameterType="INT"> select * from account where uid = #{uid}</select>UserMapper.java接口中新增方法findByIdNoRel:
@Repositorypublic interface UserMapper { /** * 查询所有用户,同时获取到用户下所有账户的信息 * @return */ List<User> findAll();// /**// * 根据id查询用户信息// * @param userId// * @return// */ User findById(Integer userId); User findByIdNoRel(Integer userId);
这样返回的数据就不会一直相互请求关联下去了,这里需要忽略序列化的属性,使用@JsonIgnore,因为一对一指向为空
@JsonIgnoreProperties(value = {"handler"}) public class User implements Serializable {
private Integer id;private String username;private String address;
......
最终可以将查询用户的结果集json格式 返回给前端结果:
[{"id":41,"username":"老王","address":"北京","sex":"男","birthday":"2018-02-27T17:47:08.000+0000","accounts":[{"id":1,"uid":41,"money":1000.0,"user":null},{"id":3,"uid":41,"money":3000.0,"user":null}]},{"id":42,"username":"小二王","address":"北京金燕龙","sex":"女","birthday":"2018-03-02T15:09:37.000+0000","accounts":[]},{"id":43,"username":"小二九","address":"北京金燕龙","sex":"女","birthday":"2018-03-04T11:34:34.000+0000","accounts":[{"id":2,"uid":43,"money":2000.0,"user":null}]},{"id":45,"username":"传智播客","address":"北京金燕龙","sex":"男","birthday":"2018-03-04T12:04:06.000+0000","accounts":[]},{"id":46,"username":"老久","address":"北京","sex":"女","birthday":"2018-03-07T17:37:26.000+0000","accounts":[]},{"id":48,"username":"小马宝莉","address":"北京修正","sex":"女","birthday":"2018-03-08T11:44:00.000+0000","accounts":[]},{"id":51,"username":"李四","address":"广西南宁市","sex":"男","birthday":"2019-07-21T06:29:22.000+0000","accounts":[]},{"id":52,"username":"王五","address":"广西桂林市","sex":"男","birthday":"2019-07-20T08:19:50.000+0000","accounts":[]}]