MyBatis多表查询
一、创建部门表和员工表:
创建部门信息表`t_department`,其中包括`id`, `name`
CREATE TABLE t_department (
id INT AUTO_INCREMENT,
name VARCHAR(20) UNIQUE NOT NULL,
PRIMARY KEY(id)
) DEFAULT CHARSET=UTF8;
往部门表中插入数据:
INSERT INTO t_department (name) VALUES
('UI'), ('RD'), ('TEST');
创建员工信息表t_user
CREATE TABLE t_user(
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(20) ,
password VARCHAR(20) ,
age int ,
phone VARCHAR(20) ,
email VARCHAR(20) ,
is_Delete int
)DEFAULT CHARSET=UTF8;
往员工表中插入数据:
INSERT INTO t_user VALUES(null,'张三','123456',23,'110','11111@qq.com',1),(null,'历史','123456',23,'110','11111@qq.com',1),(null,'孙悟空','123456',23,'110','11111@qq.com',2),(null,'李白','123456',23,'110','11111@qq.com',2),(null,'八戒','123456',23,'110','11111@qq.com',2);
插入数据错误:
https://www.cnblogs.com/package-java/p/10494380.html
二、创建VO类
如果尝试执行多表关联查询,必然没有匹配的实体类可以封装查询结果,则需要创建VO(Value Object)类,它不同于实体类,实体类是与某1张数据表完全对应的,而VO类是与实际应用需求相对应的!
假设要查询用户数据,且部门应该是显示部门的名称,则VO类应该是:
package cn.tedu.mybatis.vo; import java.io.Serializable; public class UserVO implements Serializable{ /** * */ private static final long serialVersionUID = -2717875053900055423L; private Integer uid; private String username; private String password; private Integer age; private String phone; private String email; private Integer isDelete; private Integer did; private String name; public Integer getUid() { return uid; } public void setUid(Integer uid) { this.uid = uid; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Integer getIsDelete() { return isDelete; } public Integer getDid() { return did; } public void setDid(Integer did) { this.did = did; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "UserVO [uid=" + uid + ", username=" + username + ", password=" + password + ", age=" + age + ", phone=" + phone + ", email=" + email + ", isDelete=" + isDelete + ", did=" + did + ", name=" + name + "]"; } }
三、创建接口和抽象方法:
则设计的抽象方法的返回值就应该是List集合中存放VO类型的数据:
List<UserVO> findAll2();
四、创建SQL映射:
在查询时,`<select>`节点必须指定结果的类型,可以通过`resultType`属性来指定,也可以通过`resultMap`属性来指定。
当有直接对应的查询结果时,可以使用`resultType`,取值一般是实体类的类型,或VO类的类型。
某些查询可能需要将查询结果进行特殊的封装,例如查询时存在1对多、多对多、多对1等关系,则需要使用`resultMap`来配置封装的方式。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN" "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd"> <mapper namespace="cn.tedu.mybatis.mapper.UserMapper"> <select id="findAll2" resultType="cn.tedu.mybatis.vo.UserVO"> SELECT t_user.id AS uid, username, password, age, phone, email, is_delete AS isDelete, did, name FROM t_user INNER JOIN t_department ON t_user.did=t_department.id; </select> </mapper>
以上代码中,自定义别名是因为需要区分查询结果中的列的名称,并不是因为需要与数据类型中的属性对应,关于查询结果的列名与数据类型的属性名的对应,可以通过`<resultMap>`中的配置来完成!
<resultMap>用法:https://www.cnblogs.com/package-java/p/10495912.html
五、添加测试
import java.sql.SQLException; import java.util.List; import javax.sql.DataSource; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.mapper.MapperScannerConfigurer; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.tedu.mybatis.entity.User; import cn.tedu.mybatis.mapper.UserMapper; import cn.tedu.mybatis.vo.UserVO; public class Testdemo { AbstractApplicationContext ac; UserMapper mapper; @Test public void findAll2() { List<UserVO> list = mapper.findAll2(); System.out.println("BEGIN:"); for (UserVO userVO : list) { System.out.println(userVO); } System.out.println("END."); } }