mybatis多表查询的实现(xml方式)
目录
- 前言
- 数据库表及关系
- 一对多查询
- 多对一及一对一查询
- 总结
前言 表之间的关系有几种:一对多、多对一、 一对一、多对多
在多对一关系中,把多的部分拆成一个一个对象其实就是一对一关系,如账户和用户是多对一关系,但每个账户只对应一个用户。所以在mybatis中,多对一的关系可以看成一对一的关系。
这里我把一对多和多对一的xml配置方式总结了一下,同时还有加载方式。
一对多,多对多:通常情况下我们都是采用延迟加载。
多对一,一对一:通常情况下我们都是采用立即加载。
至于注解方式和多对多查询的xml和注解方式我会另外写博客。
数据库表及关系 我们以用户和账户为例,用户可以有多个账户,账户只能对应一个用户。所以用户对账户是一对多关系,账户对用户是多对一关系。表如下图所示,用户表user,账户表account,账户表UID对应用户表id。
文章图片
文章图片
一对多查询 首先我们要在User实体类中添加List accounts的集合成员变量,表示一对多映射关系,主表实体含有从表实体的集合引用。
public class User implements Serializable{private Integer id; private String username; private String address; private String sex; private Date birthday; //一对多映射关系,主表实体含有从表实体的集合引用private List accounts; public List getAccounts() {return accounts; }public void setAccounts(List accounts) {this.accounts = accounts; }@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", address='" + address + '\'' +", sex='" + sex + '\'' +", birthday=" + birthday +'}'; }public Integer getId() {return id; }public void setId(Integer id) {this.id = id; }public String getUsername() {return username; }public void setUsername(String username) {this.username = username; }public String getAddress() {return address; }public void setAddress(String address) {this.address = address; }public String getSex() {return sex; }public void setSex(String sex) {this.sex = sex; }public Date getBirthday() {return birthday; }public void setBirthday(Date birthday) {this.birthday = birthday; }}
同时在User Dao接口中提供查询所有方法findAll,在Account Dao接口中提供根据id查询user的方法findById,以便延时加载时调用。
这里说明因为用户可能对应许多账户,当我们查询用户时可能并不需要账户信息,而且如果我们每次查询用户时都立即查询用户的账户信息,并且账户信息有很多,势必对内存有很大的开销。所以当我们需要账户信息时再调用findById方法去查询用户对应的账户信息。
public interface IUserDao {/*** 查询所有操作,并携带账户信息* @return*/ListfindAll(); /*** 根据id查询一个用户* @param uid*/User findById(Integer uid); }
public interface IAccountDao {/*** 查询所有账户* @return*/List findAll(); /*** 根据用户id查询账户* @param uid* @return*/List findByUid(Integer uid); }
然后配置userDao.xml,说明会在代码中给出。
select * from userselect * from user where id=#{uid};
当然我们还要在主配置文件中开启延时加载,默认情况下是立即加载。
lazyLoadingEnabled:是否启用延迟加载,mybatis默认为false,不启用延迟加载。lazyLoadingEnabled属性控制全局是否使用延迟加载,特殊关联关系也可以通过嵌套查询中fetchType属性单独配置(fetchType属性值lazy或者eager)。
也就是说我们可以不用在主配置文件中配置而在userDao.xml中配置,这里我们采用全局配置。
然后我们就可以测试了
public class UserTest {private InputStream in; private SqlSessionFactory factory; private SqlSession sqlSession; private IUserDao userDao; @Before//在测试方法执行之前执行public void init() throws IOException {//1.读取配置文件,生成字节输入流in = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.生成SqlSessionFactoryfactory = new SqlSessionFactoryBuilder().build(in); //3.获取SqlSessionsqlSession = factory.openSession(); //4.获取dao的代理对象userDao = sqlSession.getMapper(IUserDao.class); }@After//在测试方法执行之后执行public void destory() throws IOException {//提交事务sqlSession.commit(); //关闭资源sqlSession.close(); in.close(); }/*** 测试查询所有账户*/@Testpublic void TestFindAll() {//5.执行查询所有方法ListuserList = userDao.findAll(); for (User user : userList) {System.out.println(user); System.out.println(user.getAccounts()); }}}
先把遍历输出部分代码注释掉,测试可以看出我们只查询了用户信息。
文章图片
然后去掉注释,发现当我们需要输出用户账户时,他就会去查询用户的账户信息。
文章图片
多对一及一对一查询 步骤其实和一对多差不多。
首先我们在account实体类中加入user成员变量表示一对一映射。
public class Account implements Serializable {private Integer id; private Integer uid; private Double money; //从表实体应该包含一个主表实体的对象引用private User user; public User getUser() {return user; }public void setUser(User user) {this.user = user; }public Integer getId() {return id; }public void setId(Integer id) {this.id = id; }public Integer getUid() {return uid; }public void setUid(Integer uid) {this.uid = uid; }public Double getMoney() {return money; }public void setMoney(Double money) {this.money = money; }@Overridepublic String toString() {return "Account{" +"id=" + id +", uid=" + uid +", money=" + money +'}'; }}
Dao接口中需要的的方法在上面总结一对多查询时的图中已经给出。
然后配置accountDao.xml,这里是立即查询,在我们已经配置全局延时加载的情况下,我们需要配置fetchType=“eager”。
SELECT * from accountselect * from account where uid = #{uid}
然后我们就可以测试。可以看出当查询账户时就立即查询了对应的用户信息。
文章图片
总结 第一尝试博客,肯定有很多欠缺的地方,希望大家看到能评论指出。我自己学mybatis时间也不是很长,这里只给出了简单的案例。如果什么理解不到位的地方也请大家谅解并指出。以后我会更多的写博客,希望能够给一起处在学习阶段的人一些启发。
【mybatis多表查询的实现(xml方式)】到此这篇关于mybatis多表查询的实现(xml方式)的文章就介绍到这了,更多相关mybatis多表查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- Entity|Entity Framework常用查询语句
- mysql的sql优化工具_DBA的五款最佳SQL查询优化工具,收藏了
- MySQL让人又爱又恨的多表查询
- 项目资料|基于JAVA+SpringBoot+Mybatis+Vue+MYSQL的智慧养老管理系统
- mybatis和springboot整合
- 如何获取 Docker 容器的 IP 地址
- mybatisPlus填坑之逻辑删除的实现
- mybatis如何设置useGeneratedKeys=true
- mysql中Mysql模糊查询like效率,以及更高效的写法和sql优化方法
- mysql|MYSQL数据库复杂查询练习题(难度适中)