- 实现关联数据的查询
查询使用 resultType
<select id="selectById_user4" parameterType="int" resultType="map">
取值可以是:
1、map
2、java.util.Map
3、user(指向配置文件typeAlias的值)
4、com.pojo.User
查询使用 resultMap
<select id="selectById_user5" parameterType="int" resultMap="userparameterMap">
取值可以是:
指向xml文件里面一个resultMap的id的值
<!--type= map | com.pojo.user
<resultMap type="map" id="userparameterMap">
<result property="id2" column="id" />
</resultMap>
1、实现多对一的查询 association
对象(对象) (推荐)
map(map)
对象(map)
map(对象)
►都使用的map集合进行封装
(可以使用连表查询[建议]或关联查询实现[N+1问题])
映射文件:
<resultMap type="map" id="selManytoOneR"><!--map里面的属性任意定义-->
<id property="id" column="aid" />
<result property="aname" column="aname" />
<association property="mapuseraddress" javaType="map" ><!--对应多的那个对象 也可以使用另外一个查询获取-->
<id property="bid" column="bid" />
<result property="baddressname" column="baddressname" />
</association>
</resultMap>
<select id="selManytoOne" resultMap="selManytoOneR"><!--连表查询-->
select a.id aid,a.name aname,b.id bid,b.addressname baddressname from user a inner join useraddress b on a.useraddressid=b.id
</select>
---------------------------------------------------------------------------------------------------
►使用对象封装,对象里面用map集合再封装成一个对象(对应多的那个对象)
(可以使用连表查询[建议]或关联查询实现[N+1问题])
<resultMap type="com.pojo.User" id="userparameterObj2">
<result property="id" column="id" />
.......
<association property="mapuser" javaType="map"><!-- mapuser -->
<result property="mapid" column="id" />
........
►使用对象封装,对象里面用对象封装一个对象进行封装
<resultMap type="com.pojo.User" id="userparameterObj2">
<result property="id" column="id" />
...........
<association property="objuser" javaType="com.pojo.User">
<result property="id" column="objid" />
.............
(可以使用连表查询[建议]或关联查询实现[N+1问题])
2、N+1选择问题:什么是N+1问题:
·执行单条SQL语句去获取一个列表的记录( “+1”)。
·对列表中的每一条记录,再执行一个联合select 语句来加载每条记录更加详细的信息(“N”)。
上面的association 和collection使用select属性进行再次查询会出现N+1问题(输出sql语句)
这个问题会导致成千上万的SQL语句的执行
优化方式:尽量使用联合嵌套结果集
----------------------下面出现N+1问题------------------------------
当执行某个查询语句返回resultMap为bank3的时候,这个时候为user属性赋值的时候,在去执行com.pojo.User.seluser1查询语句,出现多次查询,尽量使用联合嵌套结果集为对象的属性赋值
column=”userid”是传值,也可以传多个值
<association property="objusfdfmap" javaType="com.pojo.User" select="seluser1" column="{kid=id,name=name}">
-------------------------------------------------------------------------------
<select id="seluser1" resultType="user">
SELECT * FROM user WHERE id= #{kid} and name=#{name}
</select>
3、实现一对多的查询(collection [以第一个属性分组])
1、用map封装一行结果集,一行map里面的用list封装多个对象(里面每个对象是用map封装)
一行一个map = {id=1,addressname,list[{map},{map}]}
多行map组成一个list结果集
<resultMap type="map" id="rmap1">
<id property="aid" column="aid" /><!--通过id属性分组,也可以设置其他属性,addressname-->
<!-- <id property="addressname" column="addressname" /> -->
<result property="addressname" column="addressname" />
<!--listusermap指定里面的一个属性,类型是list集合类型,list集合里面的类型是map类型-->
<collection property="listusermap" javaType="list" ofType="map">
<id property="bid" column="bid" />
<result property="name" column="name" />
<result property="useraddressid" column="useraddressid" />
</collection>
</resultMap>
------下面这个映射和上面是一样的,只是list集合里面的类型是引用外面的一个resultMap------
<resultMap type="map" id="rmap1">
<id property="aid" column="aid" />
<result property="addressname" column="addressname" />
<collection property="listusermap" javaType="list" resultMap="listmap">
</collection>
</resultMap>
<resultMap type="map" id="listmap">
<id property="bid" column="bid" />
<result property="name" column="name" />
<result property="useraddressid" column="useraddressid" />
</resultMap>
----------------------------------------------------------------------------
<select id="selUserAddress" resultMap="rmap1">
select a.id
aid,addressname,b.id bid,name,useraddressid from useraddress a inner
join user b on a.id=b.useraddressid
</select>
String statement = "com.pojo.UserAddress.selUserAddress";
List<Map<String, Object>> a = s.selectList(statement);
for (Map<String, Object> map : a) {
System.out.println("" + map.get("aid") + map.get("addressname")+map.get("listusermap"));
}
结果:map {id=1,addressname,list[{map},{map}]}
1北京[{name=u1, useraddressid=1, bid=3}, {name=u1, useraddressid=1, bid=4}, {name=你牛, useraddressid=1, bid=9}]
2南京[{name=你好, useraddressid=2, bid=8}, {name=vv个, useraddressid=2, bid=11}]
3普京[{name=啊啊, useraddressid=3, bid=10}]
2、用对象封装一行结果集(1对多(多个里面的每个对应多个)
一个useraddress 对应多个user 而每个user里面又对应 多个bank对象
►连表查询实现(建议)
<resultMap type="com.pojo.UserAddress" id="mapselectuser_useraddress_bank">
<result property="id" column="bid" />
<result property="addressname" column="addressname" />
<collection property="listuser" javaType="list" ofType="com.pojo.User">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="pwd" column="pwd" />
<collection property="listbank" javaType="list" ofType="com.pojo.Bank">
<id property="id" column="cid" />
<result property="name" column="cname" />
</collection>
</collection>
</resultMap>
-------------------------------------
<select id="selectuser_useraddress_bank" resultMap="mapselectuser_useraddress_bank">
select a.id,a.name,a.pwd,a.sex,b.id bid, b.addressname,c.name cname,c.id cid from
user a inner join useraddress b on a.useraddressid=b.id inner join bank c on a.id=c.userid
</select>