假如我们有如下3张表
users表
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(50) | YES | | NULL | |
| password | varchar(50) | YES | | NULL | |
| email | varchar(50) | YES | | NULL | |
+----------+-------------+------+-----+---------+----------------+
users表对应的pojo
public class User {
private int id;
private String username;
private String password;
private String email;
private List<Visit> visitList;
}
用户访问表
+--------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| userId | int(11) | YES | | NULL | |
| vTime | datetime | YES | | NULL | |
| vIP | varchar(30) | YES | | NULL | |
+--------+-------------+------+-----+---------+----------------+
seller表
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| userId | int(11) | YES | | NULL | |
| realName | varchar(30) | YES | | NULL | |
| address | varchar(80) | YES | | NULL | |
| phone | varchar(80) | YES | | NULL | |
+----------+-------------+------+-----+---------+----------------+
seller表对应的pojo类
public class Seller {
private int id ;
private User user ;
private String realName ;
private String phone;
}
1.关联查询
获得卖家seller的真实姓名和登录用户名,其sql语句如下
select seller.id as sid,users.id as uid,realName,username from users inner join seller on users.id=userId
在selle.xml中添加一个resultMap和select标签
resultMap的子标签:
- constructor - 类在实例化时,用来注入结果到构造方法中
- idArg - ID 参数;标记结果作为 ID 可以帮助提高整体效能
- arg - 注入到构造方法的一个普通结果
- id – 一个 ID 结果;标记结果作为 ID 可以帮助提高整体效能
- result – 注入到字段或 JavaBean 属性的普通结果
- association – 一个复杂的类型关联;许多结果将包成这种类型
- 嵌入结果映射 – 结果映射自身的关联,或者参考一个
- collection – 复杂类型的集
- 嵌入结果映射 – 结果映射自身的集,或者参考一个
- discriminator – 使用结果值来决定使用哪个结果映射
- case – 基于某些值的结果映射
- 嵌入结果映射 – 这种情形结果也映射它本身,因此可以包含很多相 同的元素,或者它可以参照一个外部的结果映射。
- case – 基于某些值的结果映射
<resultMap id="sellerUserMap" type="Seller">
<id property="id" column="sid"></id>
<result property="realName" column="realName"></result>
<result property="phone" column="phone"></result>
<association property="user" column="uid" javaType="User"><!--user为类属性-->
<id property="id" column="uid"></id><!--区别不同的id,users为表名-->
<result property="username" column="username"></result>
<result property="password" column="password"></result>
<result property="email" column="email"></result>
</association>
</resultMap>
<!--如想同时获得2表的id请使用别名-->
<select id="selectSellerJoin" resultMap="sellerUserMap">
select seller.id as sid,users.id as uid,realName,username from users inner join seller on users.id=userId
</select>
在测试文件的main中
SqlSession session = MySqlSessionFactor.getSqlSession();
List<Seller> sellerList= session.selectList("selectSellerJoin");
for(Seller seller:sellerList){
System.out.println("realName="+seller.getRealName()+" UserName="+seller.getUser().getUsername());
System.out.println(seller.getId()+" "+seller.getUser().getId());
}
以上的resultMap中的User也可以使用构造器来初始化
<resultMap id="sellerUserMap2" type="Seller">
<id property="id" column="seller.id"></id>
<result property="id" column="seller.id"></result>
<result property="realName" column="realName"></result>
<result property="phone" column="phone"></result>
<association property="user" column="userId" javaType="User"><!--user为类属性-->
<constructor>
<arg column="username" javaType="string"></arg>
<arg column="password" javaType="string"></arg>
</constructor>
</association>
</resultMap>
2.子查询
关联查询都可以使用子查询来实现,但是一般情况下子查询的效率不让关联查询
在seller.xml文件中,配置如下的resultMap和select标签
<resultMap id="sellerUserSubMap" type="Seller">
<id property="id" column="seller.id"></id>
<result property="id" column="seller.id"></result>
<result property="realName" column="realName"></result>
<result property="phone" column="phone"></result>
<!--user对象由selectById的sql构建,要和selectById的namespace相同-->
<association property="user" column="userId" javaType="User" select="selectById"/>
</resultMap>
<select id="selectSeller" resultMap="sellerUserSubMap">
select * from seller
</select>
ps: select="selectById"/是之前在user.xml的一个select标签,其要和该标签在一个命名空间下
在java测试文件中
List<Seller> sellerList= session.selectList("selectSeller");
for(Seller seller:sellerList){
System.out.println("realName="+seller.getRealName()+"UserName="+seller.getUser().getUsername());
System.out.println(seller.getId()+" "+seller.getUser().getId());
}
这里也可以使用延迟加载的技术,当使用到user对象实才去查询。默认延迟加载是关闭的,启动只需在mybatis-config.xml文件中添加
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
3.集合查询
集合查询也是关联查询的一种,只不过它是1对多而已,比如我要查询user的id为1的用户登录的相关信息
在user.xml文件中
<resultMap id="visitMap" type="User">
<id column="uid" property="id"></id>
<result column="username" property="username"></result>
<!--ofType就是泛型T的具体类型,vid为sql语句里面的别名-->
<collection property="visitList" column="vid" javaType="ArrayList" ofType="cn.javis.pojo.Visit">
<result column="vid" property="id"></result>
<result column="vTime" property="vTime"></result>
<result column="vIP" property="vIP"></result>
</collection>
</resultMap>
<select id="selectUserVisit" resultMap="visitMap">
select users.id as uid,visit.id as vid,vTime,vIP,username from users inner join visit on users.id=userId where userId=#{id}
</select>
在java测试文件中
User user= session.selectOne("selectUserVisit", 1);
for(Visit v:user.getVisitList()){
System.out.println(user.getUsername()+" "+v.getvIP()+" "+v.getvTime());
}