mybatis的多表操作
2021/5/24 18:55:09
本文主要是介绍mybatis的多表操作,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
mybatis的多表操作
mybatis表之间的关系
mybatis表之间的关系有:
- 一对多
- 多对一
- 一对一
- 多对多
举例:
多对一
-
一个用户可以有多个订单
-
多个订单属于一个用户
一对一
- 一个人对应一个身份证号
多对多
老师与学生之间的关系
- 一个学生可以被多个老师教
- 一个老师可以同时交多个学生
用户与角色
- 一个用户可以有多个角色
- 一个角色可以对应多个用户
特例
如果拿出每一个订单,他只能属于一个用户。
mybatis就会把多对一看做为一对一。
mybatis中的多表查询
一对多实例
任务:用户与账户
- 一个用户可以有多个账户
- 一个账户只能属于一个用户(多个账户也可以属于一个用户)
步骤:
- 建立两张表:用户表和账户表。让用户表和账户表建立一对多的关系,需要在账户表中添加外键。
- 建立两个实体类:用户实体类和账户实体类,让账户和用户的实体类能体现出一对多的关系。
- 建立两个配置文件,用户的配置文件和账户的配置文件。
- 建立mybatis的核心配置文件。
- 实现配置:在查询用户时,可以得到用户所有的账户信息。在查询账户时,可以得到对应的用户信息。
1.建立数据库表
DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL auto_increment, `username` varchar(32) NOT NULL COMMENT '用户名称', `birthday` datetime default NULL COMMENT '生日', `sex` char(1) default NULL COMMENT '性别', `address` varchar(256) default NULL COMMENT '地址', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (41,'老王','2018-02-27 17:47:08','男','北京'),(42,'小二王','2018-03-02 15:09:37','女','北京金燕龙'),(43,'小二王','2018-03-04 11:34:34','女','北京金燕龙'),(45,'传智播客','2018-03-04 12:04:06','男','北京金燕龙'),(46,'老王','2018-03-07 17:37:26','男','北京'),(48,'小马宝莉','2018-03-08 11:44:00','女','北京修正'); DROP TABLE IF EXISTS `account`; CREATE TABLE `account` ( `ID` int(11) NOT NULL COMMENT '编号', `UID` int(11) default NULL COMMENT '用户编号', `MONEY` double default NULL COMMENT '金额', PRIMARY KEY (`ID`), KEY `FK_Reference_8` (`UID`), CONSTRAINT `FK_Reference_8` FOREIGN KEY (`UID`) REFERENCES `user` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into `account`(`ID`,`UID`,`MONEY`) values (1,46,1000),(2,45,1000),(3,46,2000);
2.建立两个实体类
用户实体类
package com.javaqian.domain; import java.io.Serializable; import java.util.Date; import java.util.List; /** * @author javaqian * @Company */ public class User implements Serializable { private Integer id; private String username; private String address; private String sex; private Date birthday; //一对多关系映射:主表实体应该包含从表实体的集合引用 private List<Account> accounts; public List<Account> getAccounts() { return accounts; } public void setAccounts(List<Account> accounts) { this.accounts = accounts; } 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; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", address='" + address + '\'' + ", sex='" + sex + '\'' + ", birthday=" + birthday + '}'; } }
账户实体类
package com.javaqian.domain; import java.io.Serializable; /** * @author javaqain * @Company */ 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; } @Override public String toString() { return "Account{" + "id=" + id + ", uid=" + uid + ", money=" + money + '}'; } }
用户账单类
package com.javaqian.domain; /** * @author javaqian * @Company */ public class AccountUser extends Account { private String username; private String address; 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; } @Override public String toString() { return super.toString()+" AccountUser{" + "username='" + username + '\'' + ", address='" + address + '\'' + '}'; } }
3.建立用户和账单的配置文件
用户配置文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.javaqian.dao.IUserDao"> <!--定义user的resultmap--> <resultMap id="findUserAccount" type="com.javaqian.domain.User"> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="address" column="address"></result> <result property="sex" column="sex"></result> <result property="birthday" column="birthday"></result> <!-- 配置user对象中account集合的映射--> <collection property="accounts" ofType="com.javaqian.domain.Account"> <id column="aid" property="id"></id> <result column="uid" property="uid"></result> <result column="money" property="money"></result> </collection> </resultMap> <!--查询所有--> <select id="findAll" resultMap="findUserAccount"> SELECT * FROM user u LEFT OUTER JOIN account a on u.id=a.UID; </select> </mapper>
账户的配置文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.javaqian.dao.IAccountDao"> <!--利用accountUser实体类查询所有账户同时包含用户名和地址信息--> <select id="findAllAccount" resultType="com.javaqian.domain.AccountUser"> select a.*,u.username,u.address from account a , user u where u.id = a.uid; </select> <!-- 定义封装account和user的resultMap --> <resultMap id="accountUserMap" type="com.javaqian.domain.Account"> <id property="id" column="aid"></id> <result property="uid" column="uid"></result> <result property="money" column="money"></result> <association property="user" column="uid" javaType="com.javaqian.domain.User"> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="address" column="address"></result> <result property="sex" column="sex"></result> <result property="birthday" column="birthday"></result> </association> </resultMap> <!-- 查询所有账户信息,同时包含有用户信息 --> <select id="findAll" resultMap="accountUserMap"> SELECT u.*,a.id as aid,a.uid ,a.money FROM account a,USER u WHERE u.id=a.uid; </select> </mapper>
4.建立mybatis的核心配置文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="mysql"> <environment id="mysql"> <!-- 配置JDBC事务控制,由mybatis进行管理 --> <transactionManager type="JDBC"></transactionManager> <!-- 配置数据源,采JDBC连接池 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <package name="com.javaqian.dao"/> </mappers> </configuration>
5.最终类的测试结果
用户的测试类
在查询用户时,可以得到用户所有的账户信息。
package com.javaqian; import com.javaqian.dao.IUserDao; import com.javaqian.domain.User; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.InputStream; import java.util.List; /** * @author javaqian * @Company */ public class UserTest { private InputStream in; private SqlSession sqlSession; private IUserDao userDao; @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的代理对象 userDao = sqlSession.getMapper(IUserDao.class); } @After//用于在测试方法执行之后执行 public void destroy()throws Exception{ //提交事务 // sqlSession.commit(); //6.释放资源 sqlSession.close(); in.close(); } /** * 查询所有用户,同时查询用户所包含的账单信息 */ @Test public void findAll(){ List<User> users=userDao.findAll(); for (User user : users) { System.out.println(user); } } }
账户的测试类
在查询账户时,可以得到对应的用户信息。
package com.javaqian; import com.javaqian.dao.IAccountDao; import com.javaqian.domain.Account; import com.javaqian.domain.AccountUser; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.After; import org.junit.Before; import org.junit.Test; import javax.sound.midi.Soundbank; import java.io.InputStream; import java.util.List; /** * @author javaqian * @Company */ public class AccountTest { private InputStream in; private SqlSession sqlSession; private IAccountDao accountDao; @Before//用于在测试方法执行之前执行 public void init()throws Exception{ //1.读取配置文件,生成字节输入流 in = Resources.getResourceAsStream("mybatis-config.xml"); //2.获取SqlSessionFactory SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in); //3.获取SqlSession对象 sqlSession = factory.openSession(true); //4.获取dao的代理对象 accountDao = sqlSession.getMapper(IAccountDao.class); } @After//用于在测试方法执行之后执行 public void destroy()throws Exception{ //提交事务 // sqlSession.commit(); //6.释放资源 sqlSession.close(); in.close(); } /** *查询所有用户 */ @Test public void findAll(){ List<Account> accounts=accountDao.findAll(); for (Account account : accounts) { System.out.println(account); } } /** * 查询所有账户,同时包含包含用户名地址 */ @Test public void findAllAccount(){ List<AccountUser> accountUsers=accountDao.findAllAccount(); for (AccountUser accountUser : accountUsers) { System.out.println(accountUser); } } }
多对多实例
任务:用户与角色
- 一个用户可以有多个角色
- 一个角色可以对应多个用户
步骤:
1. 建立两张表:用户表,角色表让用户表和角色表具有多对多的关系。需要使用中间表,中间表中包含各自的主键,在中间表中是外键。 2. 建立两个实体类:用户实体类和角色实体类 让用户和角色的实体类能体现出来多对多的关系各自包含对方一个集合引用。
- 建立两个配置文件用户的配置文件角色的配置文件。
- 建立mybatis的核心配置文件。
- 实现配置: 当我们查询用户时,可以同时得到用户所包含的角色信息。当我们查询角色时,可以同时得到角色的所属用户信息。
1.建立数据库表
DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL auto_increment, `username` varchar(32) NOT NULL COMMENT '用户名称', `birthday` datetime default NULL COMMENT '生日', `sex` char(1) default NULL COMMENT '性别', `address` varchar(256) default NULL COMMENT '地址', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (41,'老王','2018-02-27 17:47:08','男','北京'),(42,'小二王','2018-03-02 15:09:37','女','北京金燕龙'),(43,'小二王','2018-03-04 11:34:34','女','北京金燕龙'),(45,'传智播客','2018-03-04 12:04:06','男','北京金燕龙'),(46,'老王','2018-03-07 17:37:26','男','北京'),(48,'小马宝莉','2018-03-08 11:44:00','女','北京修正'); DROP TABLE IF EXISTS `role`; CREATE TABLE `role` ( `ID` int(11) NOT NULL COMMENT '编号', `ROLE_NAME` varchar(30) default NULL COMMENT '角色名称', `ROLE_DESC` varchar(60) default NULL COMMENT '角色描述', PRIMARY KEY (`ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into `role`(`ID`,`ROLE_NAME`,`ROLE_DESC`) values (1,'院长','管理整个学院'),(2,'总裁','管理整个公司'),(3,'校长','管理整个学校'); DROP TABLE IF EXISTS `user_role`; CREATE TABLE `user_role` ( `UID` int(11) NOT NULL COMMENT '用户编号', `RID` int(11) NOT NULL COMMENT '角色编号', PRIMARY KEY (`UID`,`RID`), KEY `FK_Reference_10` (`RID`), CONSTRAINT `FK_Reference_10` FOREIGN KEY (`RID`) REFERENCES `role` (`ID`), CONSTRAINT `FK_Reference_9` FOREIGN KEY (`UID`) REFERENCES `user` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into `user_role`(`UID`,`RID`) values (41,1),(45,1),(41,2);
2.建立两个实体类
role实体类:
package com.javaqian.domain; import com.javaqian.domain.User; import java.io.Serializable; import java.util.List; /** * @author javaqian * @Company */ public class Role implements Serializable { private Integer roleId; private String roleName; private String roleDesc; //多对多的关系映射:一个角色可以赋予多个用户 private List<User> users; public List<User> getUsers() { return users; } public void setUsers(List<User> 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 + '\'' + '}'; } }
user类:
package com.javaqian.domain; import java.io.Serializable; import java.util.Date; import java.util.List; /** * @author javaqian * @Company http://www.ithiema.com */ public class User implements Serializable { private Integer id; private String username; private String address; private String sex; private Date birthday; //多对多的关系映射:一个用户可以有多个角色 private List<Role> roles; public List<Role> getRoles() { return roles; } public void setRoles(List<Role> roles) { this.roles = roles; } 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; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", address='" + address + '\'' + ", sex='" + sex + '\'' + ", birthday=" + birthday + '}'; } }
3.建立用户和角色的配置文件
角色配置文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.javaqian.dao.IRoleDao"> <!-- 定义role的resultmap--> <resultMap id="roleMap" type="com.javaqian.domain.Role"> <id property="roleId" column="rid"></id> <result property="roleName" column="role_name"></result> <result property="roleDesc" column="role_desc"></result> <collection property="users" ofType="com.javaqian.domain.User"> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="address" column="address"></result> <result property="sex" column="sex"></result> <result property="birthday" column="birthday"></result> </collection> </resultMap> <!--查询所有--> <select id="findAll" resultMap="roleMap"> SELECT u.*,r.id as rid, r.role_name,r.role_desc FROM role r LEFT OUTER JOIN user_role ur ON r.id=ur.rid LEFT OUTER JOIN user u on u.id=ur.uid; </select> </mapper>
用户配置文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.javaqian.dao.IUserDao"> <!-- 定义user的resultmap--> <resultMap id="userMap" type="com.javaqian.domain.User"> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="address" column="address"></result> <result property="sex" column="sex"></result> <result property="birthday" column="birthday"></result> <collection property="roles" ofType="com.javaqian.domain.Role"> <id property="roleId" column="rid"></id> <result property="roleName" column="role_name"></result> <result property="roleDesc" column="role_desc"></result> </collection> </resultMap> <!-- 查询所有的用户信息以及对应的角色信息--> <select id="findAll" resultMap="userMap"> SELECT u.*,r.id as rid, r.role_name,r.role_desc FROM user u LEFT OUTER JOIN user_role ur ON u.id=ur.uid LEFT OUTER JOIN role r on r.id=ur.rid; </select> </mapper>
4.建立mybatis的核心配置文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="mysql"> <environment id="mysql"> <!-- 配置JDBC事务控制,由mybatis进行管理 --> <transactionManager type="JDBC"></transactionManager> <!-- 配置数据源,采JDBC连接池 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <package name="com.javaqian.dao"/> </mappers> </configuration>
5.最终类的测试结果
当我们查询用户时,可以同时得到用户所包含的角色信息
测试类
package com.javaqian; import com.javaqian.dao.IUserDao; import com.javaqian.domain.User; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.InputStream; import java.util.List; /** * @author 黑马程序员 * @Company http://www.ithiema.com */ public class UserTest { private InputStream in; private SqlSession sqlSession; private IUserDao userDao; @Before//用于在测试方法执行之前执行 public void init()throws Exception{ //1.读取配置文件,生成字节输入流 in = Resources.getResourceAsStream("mybatis-config.xml"); //2.获取SqlSessionFactory SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in); //3.获取SqlSession对象 sqlSession = factory.openSession(true); //4.获取dao的代理对象 userDao = sqlSession.getMapper(IUserDao.class); } /** * 查询所有用户,同时查询用户所包含的账单信息 */ @Test public void findAll(){ List<User> users=userDao.findAll(); for (User user : users) { System.out.println(user); System.out.println(user.getRoles()); } } @After//用于在测试方法执行之后执行 public void destroy()throws Exception{ //提交事务 // sqlSession.commit(); //6.释放资源 sqlSession.close(); in.close(); } }
当我们查询角色时,可以同时得到角色的所属用户信息
测试类
package com.javaqian; import com.javaqian.dao.IRoleDao; import com.javaqian.dao.IUserDao; import com.javaqian.domain.Role; import com.javaqian.domain.User; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.InputStream; import java.util.List; /** * @author * @Company */ public class RoleTest { private InputStream in; private SqlSession sqlSession; private IRoleDao roleDao; @Before//用于在测试方法执行之前执行 public void init()throws Exception{ //1.读取配置文件,生成字节输入流 in = Resources.getResourceAsStream("mybatis-config.xml"); //2.获取SqlSessionFactory SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in); //3.获取SqlSession对象 sqlSession = factory.openSession(true); //4.获取dao的代理对象 roleDao = sqlSession.getMapper(IRoleDao.class); } /** * 查询所有角色 */ @Test public void findAll(){ List<Role> roles=roleDao.findAll(); for (Role role : roles) { System.out.println(role); System.out.println(role.getUsers()); } } @After//用于在测试方法执行之后执行 public void destroy()throws Exception{ //提交事务 // sqlSession.commit(); //6.释放资源 sqlSession.close(); in.close(); } }
这篇关于mybatis的多表操作的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-26JAVA语音识别项目资料的收集与应用
- 2024-11-26Java语音识别项目资料:入门级教程与实战指南
- 2024-11-26SpringAI:Java 开发的智能新利器
- 2024-11-26Java云原生资料:新手入门教程与实战指南
- 2024-11-26JAVA云原生资料入门教程
- 2024-11-26Mybatis官方生成器资料详解与应用教程
- 2024-11-26Mybatis一级缓存资料详解与实战教程
- 2024-11-26Mybatis一级缓存资料详解:新手快速入门
- 2024-11-26SpringBoot3+JDK17搭建后端资料详尽教程
- 2024-11-26Springboot单体架构搭建资料:新手入门教程