本文最终目的是介绍MyBaties中多表查询方法,最难的就是多对多的查询方式,在此之前咱们先一起复习一下数据库的两表间的连接方式。
数据库两个表之间有四种连接方式,其中包括左连接、右连接、内连接和全连接。
左连接的定义:是以左表为基础,根据ON后给出的两表的条件将两表连接起来。结果会将左表所有的查询信息列出,而右表只列出ON后条件与左表满足的部分。
图解:
右连接的定义,是以右表为基础,根据ON后给出的两表的条件将两表连接起来。结果会将右表所有的查询信息列出,而左表只列出ON后条件与右表满足的部分。
图解:
全连接定义:求得两个表的并集,即两表所有的内容都合到一张表上,没有的内容用null代替。
1、请问那什么时候用左连接,内连接或者全连接呢?
2、MyBaties中是如何实现数据库多对多表查询的呢,是如何使用两表之间的连接关系呢?
问题一解:
简单概括一句经典的话:
需要查找两张表同时存在的数据,使用内连接,需要查找两张表中一张表存在,另一张表不存在的时候使用左外链接 或 右外链接。
那如何判断是左连接或者右连接呢,其实很简单,所有的左或者右其实与用户写的sql(LEFTOUTER JOIN RIGHTOUTERJOIN)前后有关系,判断是使用左连接或者右连接的方法是,看你想用哪张表去影响另一张表。被影响的的表在后,影响的表在前。进而再去判断是用左连接或者右连接。实例如下:
业务需求:查询用户表,去找到用户表中所对应的角色。
SELECT r.*,u.id uid, u.username username, u.birthday birthday, u.sex sex, u.address address FROM ROLE r INNER JOIN USER_ROLE ur ON ( r.id = ur.rid) INNER JOIN USER u ON (ur.uid = u.id);
分析:首先role表信息需要全部保留,r-u表是一个关联role与user的表。首先通过role左关联u-r表,再左关联user表,得到最终结果。
这是通过role表去查user表,实际意思就是一个角色对应多个人物。
因为要实现多表对多表,所以反过来,要是实现用user表去查询role表,实际含义就是一个人物可以有多个角色。
最终构成我们的多对多。
问题二解:
1、编写实体类
public class Role implements Serializable {
private Integer roleId;
private String roleName;
private String roleDesc;
//多对多的关系映射:一个角色可以赋予多个用户 private List users;
public List getUsers() { return users; }
public void setUsers(List users) { this.users = users; }
public Integer getRoleId() { return roleId; }
public void setRoleId(Integer roleId) { this.roleId = roleId; }
public String getRoleName() { return roleName; }
public void setRoleName(String roleName) { this.roleName = roleName; }
public String getRoleDesc() { return roleDesc; }
public void setRoleDesc(String roleDesc) { this.roleDesc = roleDesc; }
@Override public String toString() { return "Role{" + "roleId=" + roleId + ", roleName='" + roleName + '\'' + ", roleDesc='" + roleDesc + '\'' + '}';
2、编写role持久层接口
public interface IRoleDao {
/**
* 查询所有角色 * @return */ List findAll(); }
3、编写配置文件
4、编写测试类
public class RoleTest {
private InputStream in; private SqlSession sqlSession; private IRoleDao roleDao;
@Before//用于在测试方法执行之前执行 public void init()throws Exception{ //1.读取配置文件,生成字节输入流 in = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.获取 SqlSessionFactory SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in); //3.获取 SqlSession 对象 sqlSession = factory.openSession(true); //4.获取 dao 的代理对象 roleDao = sqlSession.getMapper(IRoleDao.class); }
@After//用于在测试方法执行之后执行 public void destroy()throws Exception{ //提交事务 // sqlSession.commit();
//6.释放资源 sqlSession.close(); in.close(); }
/**
* 测试查询所有 */ @Test public void testFindAll(){ List roles = roleDao.findAll();
* for(Role role : roles){ System.out.println("---每个角色的信息----"); System.out.println(role); System.out.println(role.getUsers()); } } }