mybatis多表查询的实现(xml方式)

网友投稿 580 2022-10-25

mybatis多表查询的实现(xml方式)

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;

}

@Override

public String toString() {

return "User{" +

"id=" + id +

", username='" + username + '\'' +

", address='" + address + '\'' +

", sex='" + sex + '\'' +

", birthday=" + birthday +

'}';

}

public Integer getId() {

return id;

}

public void setId(http://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

*/

List findAll();

/**

* 根据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 user

select * 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.生成SqlSessionFactory

factory = new SqlSessionFactoryBuilder().build(in);

//3.获取SqlSession

sqlSession = factory.openSession();

//4.获取dao的代理对象

userDao = sqlSession.getMapper(IUserDao.class);

}

@After//在测试方法执行之后执行

public void destory() throws IOException {

//提交事务

sqlSession.commit();

//关闭资源

sqlSession.close();

in.close();

}

/**

* 测试查询所有账户

*/

@Test

public void TestFindAll() {

//5.执行查询所有方法

List userList = userDao.findAll();

for (User user : userList) {

System.out.println(user);

System.out.println(user.getAccounts());

}

}

}

先把遍历输出部分代码注释掉,测试可以看出我们只查询了用户信息。

然后去掉注释,发现当我们需要输出用户账户时,他就会去查询用户的账户信息。

多对一及一对一查询

步骤其实和一对多差不多。首先我们在account实体类中加入user成员变量表示一对一映射。

public class Account implements GFIhCCQThSerializable {

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;

}

@Override

public String toString() {

return "Account{" +

"id=" + id +

", uid=" + uid +

", money=" + money +

'}';

}

}

Dao接口中需要的的方法在上面总结一对多查询时的图中已经给出。然后配置accountDao.xml,这里是立即查询,在我们已经配置全局延时加载的情况下,我们需要配置fetchType=“eager”。

SELECT * from account

select * from account where uid = #{uid}

然后我们就可以测试。可以看出当查询账户时就立即查询了对应的用户信息。

总结

第一尝试博客,肯定有很多欠缺的地方,希望大家看到能评论指出。我自己学mybatis时间也不是很长,这里只给出了简单的案例。如果什么理解不到位的地方也请大家谅解并指出。以后我会更多的写博客,希望能够给一起处在学习阶段的人一些启发。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Swoole/Process API 实现的消息处理框架
下一篇:iOS小技能: 按钮标题自动适配的中英文长度 & 动态控制子视图按钮的显示与隐藏 (Masonry版本)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~