关联查询
一对一查询
案例:查询所有订单信息,关联查询下单用户信息。
注意:因为一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询。如果从用户信息出发查询用户下的订单信息则为一对多查询,因为一个用户可以下多个订单。
方法一:
使用resultType,定义订单信息po类,此po类中包括了订单信息和用户信息:
Sql语句:
SELECT orders.*, user.username, userss.address FROM orders, user WHEREorders.user_id=user.id
定义po类
Po类中应该包括上边sql查询出来的所有字段,如下:
publicclassOrdersCustomextendsOrders{ privateStringusername;//用户名称 privateStringaddress;//用户地址 get/set。。。。 OrdersCustom类继承Orders类后OrdersCustom类包括了Orders类的所有字段,只需要定义用户的信息字段即可。
Mapper.xml
<!--查询所有订单信息--> <selectid="findOrdersList"resultType="com.pp.mybatis.po.OrdersCustom"> SELECT orders.*, user.username, user.address FROM orders,user WHEREorders.user_id=user.id </select>
Mapper接口:
publicList<OrdersCustom>findOrdersList()throwsException; 测试: PublicvoidtestfindOrdersList()throwsException{ //获取session SqlSessionsession=sqlSessionFactory.openSession(); //获限mapper接口实例 UserMapperuserMapper=session.getMapper(UserMapper.class); //查询订单信息 List<OrdersCustom>list=userMapper.findOrdersList(); System.out.println(list); //关闭session session.close(); }
小结:
定义专门的po类作为输出类型,其中定义了sql查询结果集所有的字段。此方法较为简单,企业中使用普遍。
方法二:
使用resultMap,定义专门的resultMap用于映射一对一查询结果。
Sql语句:
SELECT orders.*, user.username, user.address FROM orders, user WHEREorders.user_id=user.id
定义po类
在Orders类中加入User属性,user属性中用于存储关联查询的用户信息,因为订单关联查询用户是一对一关系,所以这里使用单个User对象存储关联查询的用户信息。
publicclassOrders{ privateIntegerid; privateIntegeruserId; privateStringnumber; privateDatecreatetime; privateStringnote; privateUseruser; publicIntegergetId(){ returnid; } publicvoidsetId(Integerid){ this.id=id; } publicIntegergetUserId(){ returnuserId; } publicvoidsetUserId(IntegeruserId){ this.userId=userId; } publicStringgetNumber(){ returnnumber; } publicvoidsetNumber(Stringnumber){ this.number=number; } publicDategetCreatetime(){ returncreatetime; } publicvoidsetCreatetime(Datecreatetime){ this.createtime=createtime; } publicStringgetNote(){ returnnote; } publicvoidsetNote(Stringnote){ this.note=note; } publicUsergetUser(){ returnuser; } publicvoidsetUser(Useruser){ this.user=user; } @Override publicStringtoString(){ return"Orders{"+ "id="+id+ ",userId="+userId+ ",number='"+number+'\''+ ",createtime="+createtime+ ",note='"+note+'\''+ ",user="+user+ '}'; } }
Mapper.xml
<!--查询订单关联用户信息使用resultmap--> <resultMaptype="com.pp.po.Orders"id="orderUserResultMap"> <idcolumn="id"property="id"/> <resultcolumn="user_id"property="userId"/> <resultcolumn="number"property="number"/> <resultcolumn="createtime"property="createtime"/> <resultcolumn="note"property="note"/> <!--一对一关联映射--> <!-- property:Orders对象的user属性 javaType:user属性对应的类型 --> <associationproperty="user"javaType="com.pp.po.User"> <!--column:user表的主键对应的列property:user对象中id属性--> <idcolumn="user_id"property="id"/> <resultcolumn="username"property="username"/> <resultcolumn="address"property="address"/> </association> </resultMap> <selectid="findOrdersWithUserResultMap"resultMap="orderUserResultMap"> SELECT o.id, o.user_id, o.number, o.createtime, o.note, u.username, u.address FROM orderso JOIN`user`uONu.id=o.user_id </select> 这里resultMap指定orderUserResultMap。 association:表示进行关联查询单条记录 property:表示关联查询的结果存储在com.pp.mybatis.po.Orders的user属性中 javaType:表示关联查询的结果类型 <idproperty="id" column="user_id"/>:查询结果的user_id列对应关联对象的id属性,这里是<id />表示user_id是关联查询对象的唯一标识。 <resultproperty="username" column="username"/>:查询结果的username列对应关联对象的username属性。
Mapper接口:
publicList<Orders>findOrdersListResultMap()throwsException; 测试: PublicvoidtestfindOrdersListResultMap()throwsException{ //获取session SqlSessionsession=sqlSessionFactory.openSession(); //获限mapper接口实例 UserMapperuserMapper=session.getMapper(UserMapper.class); //查询订单信息 List<Orders>list=userMapper.findOrdersList2(); System.out.println(list); //关闭session session.close(); }
小结:
使用association完成关联查询,将关联查询信息映射到pojo对象中。
一对多查询
案例:查询所有用户信息及用户关联的订单信息。
用户信息和订单信息为一对多关系。
使用resultMap实现如下:
Sql语句:
SELECT u.*,o.idoid, o.number, o.createtime, o.note FROM `user`u LEFTJOINordersoONu.id=o.user_id
定义po类
在User类中加入List orders属性
publicclassUser{ privateintid; privateStringusername; privateStringsex; privateDatebirthday; privateStringaddress; privateList<Orders>ordersList; @Override publicStringtoString(){ return"User{"+ "id="+id+ ",username='"+username+'\''+ ",sex='"+sex+'\''+ ",birthday="+birthday+ ",address='"+address+'\''+ ",ordersList="+ordersList+ '}'; } publicList<Orders>getOrdersList(){ returnordersList; } publicvoidsetOrdersList(List<Orders>ordersList){ this.ordersList=ordersList; } publicintgetId(){ returnid; } publicvoidsetId(intid){ this.id=id; } publicStringgetUsername(){ returnusername; } publicvoidsetUsername(Stringusername){ this.username=username; } publicStringgetSex(){ returnsex; } publicvoidsetSex(Stringsex){ this.sex=sex; } publicDategetBirthday(){ returnbirthday; } publicvoidsetBirthday(Datebirthday){ this.birthday=birthday; } publicStringgetAddress(){ returnaddress; } publicvoidsetAddress(Stringaddress){ this.address=address; } }
Mapper.xml
<resultMaptype="com.pp.po.user"id="userOrderResultMap"> <!--用户信息映射--> <idproperty="id"column="id"/> <resultproperty="username"column="username"/> <resultproperty="birthday"column="birthday"/> <resultproperty="sex"column="sex"/> <resultproperty="address"column="address"/> <!--一对多关联映射--> <collectionproperty="orders"ofType="com.pp.po.Orders"> <idproperty="id"column="oid"/> <!--用户id已经在user对象中存在,此处可以不设置--> <!--<resultproperty="userId"column="id"/>--> <resultproperty="number"column="number"/> <resultproperty="createtime"column="createtime"/> <resultproperty="note"column="note"/> </collection> </resultMap> <selectid="getUserOrderList"resultMap="userOrderResultMap"> SELECT u.*,o.idoid, o.number, o.createtime, o.note FROM `user`u LEFTJOINordersoONu.id=o.user_id </select>
collection部分定义了用户关联的订单信息。表示关联查询结果集
property="orders":关联查询的结果集存储在User对象的上哪个属性。
ofType="orders":指定关联查询的结果集中的对象类型即List中的对象类型。此处可以使用别名,也可以使用全限定名。
及的意义同一对一查询。
Mapper接口:
List<User>getUserOrderList();
测试
@Test publicvoidgetUserOrderList(){ SqlSessionsession=sqlSessionFactory.openSession(); UserMapperuserMapper=session.getMapper(UserMapper.class); List<User>result=userMapper.getUserOrderList(); for(Useruser:result){ System.out.println(user); } session.close(); }