Mybatis多表查询
![](https://img.haomeiwen.com/i15480448/d3012c878285726b.png)
mybatis的连接池
我们在实际开发中都会用到连接池,因为他可以减少我们获取连接消耗的时间。
mybatis提供了三种配置数据库连接的方式:
-
配置的位置:
-
SqlMapConfig
的DataSource
标签,type
属性就是说明采用何种方式连接
-
-
type
的取值:-
POOLED
:采用传统的javax.sql.DataSource规范中的连接池,mybatis有针对规范的具体实现 -
UNPOOLED
:采用传统的连接方式,虽然也实现了javax.sql.DataSource接口,但是没有用池的思想 -
JNDI
:采用服务器的JNDI技术实现。不同服务器有不同实现。 比如tomcat使用的是dbcp连接池
-
mybatis多表查询
1. 一对一(多对一)
因为多对一从多的一方来看,比如account
,只能找到一个对应的user
,因此在mybatis中把多对一视为一对一。
主要配置方面:
- 实体类中添加关系映射
- 映射配置文件中,添加结果集到封装的映射关系resultMap
以user-account为例,user和account是一对多,account对user是一对一。
这里先配置一对一。
1. 配置实体类
Account中添加user对象。
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
private User user;
//getter
//setter
2. 配置映射配置文件
新建IAccountDao.xml
,添加resultMap,其中主要添加了association
标签配置映射到包含的pojo对象:
<resultMap id="accountMap" type="account">
<id property="id" column="id"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!--主要多了一个这个,包含pojo对象时,使用association标签配置映射到该pojo对象-->
<!--其中column为pojo的主键,javaType是这个pojo的全限定类名(此处使用了别名),告诉mybatis这个pojo是个啥东西-->
<association property="user" column="id" javaType="user">
<!--property为要封装到类的对应属性名-->
<!--这个column是对应你查出来的字段名称,然后注入到属性中。而字段名称是唯一的-->
<id property="id" column="uid"></id>
<result property="name" column="name"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
<result property="birthday" column="birthday"></result>
</association>
</resultMap>
为方法添加合适的sql语句,返回结果的封装关系设置为accountMap
:
<select id="findAll" resultMap="accountMap">
select a.*,u.name as name ,u.address from account a, user u where a.uid=u.id
</select>
注意事项:
上面的column
是对应你查出来的字段名称,然后注入到属性中,如果你用了as
改名了,那么column
也要改名,需要对应上
2. 一对多
同理,需要做两个事情。
- 实体类中添加关系映射
- 映射配置文件中,添加结果集到封装的映射关系resultMap
User类:添加List<Account>
public class User implements Serializable {
private Integer id;
private String name;
private String address;
private String sex;
private Date birthday;
//注意:一对多时,‘一’这里添加的是List的‘多’集合
private List<Account> accounts;
映射配置文件:
如果属性是一个集合的话,需要使用collection
标签,ofType
为集合存放的对象的全限定类名(这里用了别名),别的都一样
<resultMap id="userMap" type="user">
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
<result property="birthday" column="birthday"></result>
<!--如果属性是一个集合的话,需要使用collection标签,oftype为集合存放的对象的全限定类名(这里用了别名),别的都一样-->
<collection property="accounts" ofType="account">
<id property="id" column="aid"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
</collection>
</resultMap>
<!--查询所有user-->
<select id="findAll" resultMap="userMap">
select u.*, a.id as aid, a.money from user u left outer join account a on a.uid=u.id
</select>
3. 多对多
新建表role,代表角色。一个用户有多个角色,一个角色可以属于多个用户,所以是多对多关系。
其实配置很简单。在数据库中需要一个中间表role_user,两个字段uid和rid:
![](https://img.haomeiwen.com/i15480448/24db91c1e1e59ba6.png)
在mybatis中只要配置两个一对多关系即可。
配置role-user的一对多
Role类添加List<User>
:
public class Role implements Serializable {
private Integer id;
private String position;
private String task;
private List<User> users;
IRoleDao.xml
需要修改两个地方:
-
IRoleDao.xml
配置好映射关系:
<resultMap id="roleMap" type="role">
<!--第一个 id属性 对应了column为rid,因为在sql查出来时我重命名为rid-->
<id property="id" column="rid"></id>
<result property="position" column="position"></result>
<result property="task" column="task"></result>
<collection property="users" ofType="user">
<!--这里column为uid也是同理-->
<id property="id" column="uid"></id>
<result property="name" column="name"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
<result property="birthday" column="birthday"></result>
</collection>
</resultMap>
- 修改
select
的sql语句,这个是关键,合并三张表查询出role
和user
的字段。mybatis再利用映射关系给我们封装起来
<!--查询所有role-->
<select id="findAll" resultMap="roleMap">
select r.id as rid,r.position, r.task,u.id as uid, u.name, u.sex, u.address,u.birthday
from role r
left outer join role_user ru on r.id=ru.rid
left outer join user u on ru.uid=u.id
</select>
测试:
//查询
@Test
public void testFindAll(){
List<Role> roles=roleDao.findAll();
for(Role role:roles){
System.out.println(role);
System.out.println(role.getUsers());
}
}
有结果,可见封装成功了
Role{id=1, position='妻子', task='爱老公'}
[User{id=2, name='zyy', address='浙江省宁波市慈溪市', sex='女', birthday=Tue Dec 28 00:00:00 CST 1999}]
Role{id=2, position='老公', task='爱老婆'}
[User{id=1, name='cjc', address='上海市奉贤区南桥镇', sex='男', birthday=Mon Dec 28 00:00:00 CST 1998}]
Role{id=3, position='学生', task='好好学习'}
[User{id=1, name='cjc', address='上海市奉贤区南桥镇', sex='男', birthday=Mon Dec 28 00:00:00 CST 1998}, User{id=2, name='zyy', address='浙江省宁波市慈溪市', sex='女', birthday=Tue Dec 28 00:00:00 CST 1999}]
Role{id=4, position='职员', task='好好工作'}
[User{id=1, name='cjc', address='上海市奉贤区南桥镇', sex='男', birthday=Mon Dec 28 00:00:00 CST 1998}, User{id=2, name='zyy', address='浙江省宁波市慈溪市', sex='女', birthday=Tue Dec 28 00:00:00 CST 1999}]
同理,
配置user-role的一对多关系
直接给出代码,因为和上面的差不多,只要改sql语句、resultMap和User类即可。
User类
public class User implements Serializable {
private Integer id;
private String name;
private String address;
private String sex;
private Date birthday;
private List<Role> roles;
IUserDao.xml
<resultMap id="userMap" type="user">
<id property="id" column="uid"></id>
<result property="name" column="name"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
<result property="birthday" column="birthday"></result>
<collection property="roles" ofType="role">
<id property="id" column="rid"></id>
<result property="position" column="position"></result>
<result property="task" column="task"></result>
</collection>
</resultMap>
<!--查询所有user-->
<select id="findAll" resultMap="userMap">
select u.id as uid, u.name, u.sex, u.address,u.birthday ,r.id as rid,r.position, r.task
from user u
left outer join role_user ru on u.id=ru.uid
left outer join role r on ru.rid=r.id
</select>
结果
User{id=1, name='cjc', address='上海市奉贤区南桥镇', sex='男', birthday=Mon Dec 28 00:00:00 CST 1998}
[Role{id=2, position='老公', task='爱老婆'}, Role{id=3, position='学生', task='好好学习'}, Role{id=4, position='职员', task='好好工作'}]
User{id=2, name='zyy', address='浙江省宁波市慈溪市', sex='女', birthday=Tue Dec 28 00:00:00 CST 1999}
[Role{id=1, position='妻子', task='爱老公'}, Role{id=3, position='学生', task='好好学习'}, Role{id=4, position='职员', task='好好工作'}]
User{id=6, name='mybatis01', address='上海市徐汇区', sex='男', birthday=Sat Feb 01 00:00:00 CST 2020}
[]
User{id=7, name='mybatis02', address='上海市浦东新区', sex='女', birthday=Sat Feb 01 00:00:00 CST 2020}
[]
User{id=8, name='mybatis', address='??????', sex='?', birthday=Sat Feb 01 00:00:00 CST 2020}
[]
User{id=9, name='mybatis', address='??????', sex='?', birthday=Mon Feb 03 00:00:00 CST 2020}
[]
User{id=10, name='mybatis03', address='北京市顺义区', sex='男', birthday=Mon Feb 03 00:00:00 CST 2020}
[]