MyBatis最佳实践:多表联查
第一章:一对多查询
-
多表设计:
- 一对一:其实一对一可以设计成一张表
- 一对多
- 多对一
- 多对多
-
搭建开发环境:
- 执行建表语句:
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 (1,'老王','2018-02-27 17:47:08','男','北京'), (2,'熊大','2018-03-02 15:09:37','女','上海'), (3,'熊二','2018-03-04 11:34:34','女','深圳'), (4,'光头强','2018-03-04 12:04:06','男','广州'); 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,1,1000),(2,2,1000),(3,3,2000);
- 编写 Account 的 JavaBean 类:
public class Account { private Integer id; private Integer uid; private String money; 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 String getMoney() { return money; } public void setMoney(String money) { this.money = money; } @Override public String toString() { return "Account{" + "id=" + id + ", uid=" + uid + ", money='" + money + '\'' + '}'; } }
- 编写 AccountMapper 接口:
public interface AccountMapper { }
- 编写 AccountMapper.xml 配置文件:
<?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.qcby.mapper.AccountMapper"> </mapper>
- 主配置文件中引入映射配置文件:
<mappers> <mapper resource="Mapper/UserMapper.xml"/> <mapper resource="Mapper/AccountMapper.xml"/> </mappers>
- 执行建表语句:
- 多对一查询(一对一查询):
- 需求:查询的数据中包含 account 所有的字段,再包含用户的名称和地址
- 在 Account 类中添加 User 的属性,表示该账户只属于这个用户:
public class Account { private Integer id; private Integer uid; private String money; private 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 String getMoney() { return money; } public void setMoney(String money) { this.money = money; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } @Override public String toString() { return "Account{" + "id=" + id + ", uid=" + uid + ", money='" + money + '\'' + ", user=" + user + '}'; } }
- 在 AccountMapper 接口中编写查询的方法:
public interface AccountMapper { public List<Account> findAll(); }
- 编写配置文件:
<?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.qcby.mapper.AccountMapper"> <!-- 进行数据封装 --> <resultMap id="accountMap" type="com.qcby.model.Account"> <result property="id" column="id"/> <result property="uid" column="uid"/> <result property="money" column="money"/> <association property="user" javaType="com.qcby.model.User"> <result property="username" column="username"/> <result property="address" column="address"/> </association> </resultMap> <!-- 内连接查询 --> <select id="findAll" resultMap="accountMap"> select a.*,u.username,u.address from account a,user u where a.uid = u.id; </select> </mapper>
- 测试方法:
public class Demo01 { /** * 多对一查询 * */ @Test public void findAll() throws IOException { //加载主配置文件到输入流 InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); //创建 SqlSessionFactory 对象,创建 SqlSession 对象 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); //创建 SqlSession 对象 SqlSession session = factory.openSession(); //获取代理对象 AccountMapper accountMapper = session.getMapper(AccountMapper.class); //查询 List<Account> all = accountMapper.findAll(); for (Account a : all){ System.out.println(a); } //关闭资源 session.close(); inputStream.close(); } }
-
一对多查询:
- 如果想查询 select u.*,a.money form user u left join account a on u.id = a.uid 语句中的内容
- 在 User 类中添加 List 的属性:
public class User implements Serializable { private static final long serialVersionUID = 525400707336671154L; private Integer id; private String username; private Date birthday; private String sex; private String address; private List<Integer> ids; private List<Account> accounts; public List<Integer> getIds() { return ids; } public void setIds(List<Integer> ids) { this.ids = ids; } 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 Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public List<Account> getAccounts() { return accounts; } public void setAccounts(List<Account> accounts) { this.accounts = accounts; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", birthday=" + birthday + ", sex='" + sex + '\'' + ", address='" + address + '\'' + ", ids=" + ids + ", accounts=" + accounts + '}'; } }
- 在 UserMapper 接口中定义方法:
public interface UserMapper { //查询一对多 public List<User> findOneToMony(); }
- 编写配置文件:
<?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.qcby.mapper.UserMapper"> <!-- 配置 resultMap,用来进行数据封装 id="唯一的名称,用来被引用的唯一标识" type="进行封装数据的类型" --> <resultMap id="userMap" type="com.qcby.model.User"> <!-- property="JavaBean 中的属性"--> <!-- colum="表中的字段"--> <result property="id" column="id"/> <result property="username" column="username"/> <result property="birthday" column="birthday"/> <result property="sex" column="sex"/> <result property="address" column="address"/> <collection property="accounts" ofType="com.qcby.model.Account"> <result property="money" column="money"/> </collection> </resultMap> <!-- 一对多查询 --> <select id="findOneToMony" resultMap="userMap"> select u.*,a.money from user u left join account a on u.id = a.uid; </select> </mapper>
- 编写测试方法:
public class Demo01 { /** * 一对多查询 */ @Test public void findOneToMoney() throws IOException { //加载主配置文件到输入流 InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); //创建 SqlSessionFactory 对象,创建 SqlSession 对象 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); //创建 SqlSession 对象 SqlSession session = factory.openSession(); //获取代理对象 UserMapper userMapper = session.getMapper(UserMapper.class); List<User> oneToMony = userMapper.findOneToMony(); for (User u : oneToMony){ System.out.println(u); } //关闭资源 session.close(); inputStream.close(); } }
第二章:多对多查询
- 执行 SQL 语句,创建表结构:
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,'校长','管理整个学校'); 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 (1,1),(1,2),(2,2);
- 编写 JavaBean 对象:
public class Role implements Serializable { private static final long serialVersionUID = 4836306672907553166L; private Integer id; private String role_name; private String role_desc; private User user; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getRole_name() { return role_name; } public void setRole_name(String role_name) { this.role_name = role_name; } public String getRole_desc() { return role_desc; } public void setRole_desc(String role_desc) { this.role_desc = role_desc; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } @Override public String toString() { return "Role{" + "id=" + id + ", role_name='" + role_name + '\'' + ", role_desc='" + role_desc + '\'' + ", user=" + user + '}'; } }
- 编写接口:
public interface RoleMapper { public List<Role> findAll(); }
- 编写配置文件:
<?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.qcby.mapper.RoleMapper"> <resultMap id="roleMap" type="com.qcby.model.Role"> <result property="id" column="id"/> <result property="role_name" column="role_name"/> <result property="role_desc" column="role_desc"/> <collection property="user" ofType="com.qcby.model.User"> <result property="username" column="username"/> </collection> </resultMap> <select id="findAll" resultMap="roleMap"> select r.*,u.username from user u,user_role ur,role r where u.id = ur.UID and ur.RID = r.ID; </select> </mapper>
- 编写 SqlMapConfig.xml 配置文件:
<!-- 加载映射的配置文件 --> <mappers> <mapper resource="Mapper/UserMapper.xml"/> <mapper resource="Mapper/AccountMapper.xml"/> <mapper resource="Mapper/RoleMapper.xml"/> </mappers>
- 编写测试类:
public class Demo01 { @Test public void run() throws IOException { //加载配置文件 InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml"); //创建工厂对象 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in); //构建 session SqlSession session = factory.openSession(); RoleMapper roleMapper = session.getMapper(RoleMapper.class); List<Role> all = roleMapper.findAll(); for (Role r: all){ System.out.println(r); } session.close(); in.close(); } }
原文地址:https://blog.csdn.net/SOS_suyan/article/details/145312051
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!