嘉定专业网站制作公司,做网站客户没有付定金,酷炫网站,网页升级紧急通知拿笔记好文章目录 Mybatis 多对一 and 一对多查询详解数据库需求Mybatis代码注意 Mybatis 多对一 and 一对多查询详解
数据库
员工表 t_emp 部门表 t_dept CREATE TABLE t_emp (emp_id int NOT NULL AUTO_INCREMENT,emp_name varchar(25) CHARACTER SET utf8 COLLATE utf8_general_ci… 文章目录 Mybatis 多对一 and 一对多查询详解数据库需求Mybatis代码注意 Mybatis 多对一 and 一对多查询详解
数据库
员工表 t_emp 部门表 t_dept CREATE TABLE t_emp (emp_id int NOT NULL AUTO_INCREMENT,emp_name varchar(25) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,age int DEFAULT NULL,gender varchar(25) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,dept_id int DEFAULT NULL,PRIMARY KEY (emp_id)
) ENGINEInnoDB AUTO_INCREMENT5 DEFAULT CHARSETutf8;CREATE TABLE t_dept (dept_id int NOT NULL AUTO_INCREMENT,dept_name varchar(25) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,PRIMARY KEY (dept_id)
) ENGINEInnoDB AUTO_INCREMENT4 DEFAULT CHARSETutf8;INSERT INTO t_emp (emp_id, emp_name, age, gender, dept_id) VALUES (1, 张三, 20, 男, 1), (2, 李四, 22, 男, 2), (3, 王五, 23, 男, 3), (4, 赵六, 24, 男, 1);INSERT INTO t_dept (dept_id, dept_name) VALUES (1, A), (2, B), (3, C); 需求
多对一员工表对应部门表 查询指定id的员工以及其对应的部门
一对多部门表对应员工表 查询指定的部门以及其包含的员工 Mybatis代码 DeptMapper接口文件
package com.atguigu.mybatis.mapper;import com.ruanjian.pojo.Dept;
import com.ruanjian.pojo.Emp;
import org.apache.ibatis.annotations.Param;import java.util.List;public interface DeptMapper {// 一对多查询// 查询部门表中的员工信息// 需要在部门类中添加员工的集合 private ListEmp emps;Dept getDeptAndEmpById(Param(deptId) Integer deptId);// 分步查询// 1.先查出指定id的部门信息部门信息中有对应员工的dept_idDept getDeptAndEmpByStepOne(Param(deptId) int deptId);// 2.再根据dept_id查出相对应的员工信息ListEmp getDeptAndEmpByStepTwo(Param(deptId) int deptId);}
EmpMapper接口文件
package com.atguigu.mybatis.mapper;
import com.ruanjian.pojo.Dept;
import com.ruanjian.pojo.Emp;
import org.apache.ibatis.annotations.Param;public interface EmpMapper {// 多对一查询// 查询指定id员工以及该员工所对应的部门信息Emp getEmpAndDeptById(Param(empId) Integer empId);Emp getEmpAndDeptById_association(Param(empId) Integer empId);// 分步查询// 先从员工表中查询出指定id的员工的数据该数据中有对应部门id// 再根据部门id从部门表中查询出对应的部门信息// 分步查询第一步Emp getEmpAndDeptByIdOne(Param(empId) Integer empId);// 分步查询第二步Dept getEmpAndDeptByIdTwo(Param(deptId) Integer deptId);
} Dept类文件 部门实体类
package com.ruanjian.pojo;/*
员工对部门 是多对一多对一是在多的那个类员工类中添加一个部门对象
部门对员工 是一对多一对多是在一的那个类中部门类中添加一个员工集合对一 对的就是一个对象
对多 对的就是一个集合*/import java.util.List;// 部门实体类
public class Dept {private Integer deptId;private String deptName;private ListEmp emps; // 添加的一个员工的集合public Dept() {}public Dept(Integer deptId, String deptName) {this.deptId deptId;this.deptName deptName;}public Integer getDeptId() {return deptId;}public void setDeptId(Integer deptId) {this.deptId deptId;}public String getDeptName() {return deptName;}public void setDeptName(String deptName) {this.deptName deptName;}public ListEmp getEmps() {return emps;}public void setEmps(ListEmp emps) {this.emps emps;}Overridepublic String toString() {return Dept{ deptId deptId , deptName deptName \ , emps emps };}
}Emp类文件 员工实体类
package com.ruanjian.pojo;/*
员工对部门 是多对一多对一是在多的那个类员工类中添加一个部门对象
部门对员工 是一对多一对多是在一的那个类中部门类中添加一个员工集合对一 对的就是一个对象
对多 对的就是一个集合*/// 员工实体类// 对一就是对应的一个对象
// 对多就是对应的一个集合
public class Emp {private Integer empId;private String empName;private Integer age;private String gender;private Dept dept; // 加上一个部门的对象public Emp() {}public Emp(Integer empId, String empName, Integer age, String gender) {this.empId empId;this.empName empName;this.age age;this.gender gender;}public Integer getEmpId() {return empId;}public void setEmpId(Integer empId) {this.empId empId;}public String getEmpName() {return empName;}public void setEmpName(String empName) {this.empName empName;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age age;}public String getGender() {return gender;}public void setGender(String gender) {this.gender gender;}public Dept getDept() {return dept;}public void setDept(Dept dept) {this.dept dept;}Overridepublic String toString() {return Emp{ empId empId , empName empName \ , age age , gender gender \ , dept dept };}
} DeptMapper
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.atguigu.mybatis.mapper.DeptMapper!-- 处理一对多的映射关系1. collection2. 分步查询
--
!--*************************** 一对多 collection ****************************************--resultMap iddeptAndEmpById_resultMap typedeptid columndept_id propertydeptId/idresult columndept_name propertydeptName/result!-- collection : 处理一对多的映射关系处理集合类型的属性--!-- ofType表示的是集合中的类型--collection propertyemps ofTypeEmpid columnemp_id propertyempId/idresult columnemp_name propertyempName/resultresult columnage propertyage/resultresult columngender propertygender/result/collection/resultMap!-- Dept getDeptAndEmpById(Param(deptId) Integer deptId);--select idgetDeptAndEmpById resultMapdeptAndEmpById_resultMapselect *from t_deptleft join t_emp on t_dept.dept_id t_emp.dept_idwhere t_dept.dept_id#{deptId}/select!--*************************** 一对多 collection ****************************************--!--*************************** 一对多 分步查询 ****************************************--resultMap iddeptAndEmpResultMapByStep typeDeptid columndept_id propertydeptId/idresult columndept_name propertydeptName/resultcollection propertyempsselectcom.atguigu.mybatis.mapper.DeptMapper.getDeptAndEmpByStepTwocolumndept_id/collection/resultMap!-- Dept getDeptAndEmpByStepOne(Param(deptId) int deptId);// 先查出指定id的部门信息部门信息中有对应员工的dept_id --select idgetDeptAndEmpByStepOne resultMapdeptAndEmpResultMapByStepselect * from t_dept where dept_id #{deptId}/select!-- ListEmp getDeptAndEmpByStepTwo(Param(deptId) int deptId);// 再根据dept_id查出相对应的员工信息--select idgetDeptAndEmpByStepTwo resultTypeEmpselect * from t_emp where dept_id #{deptId}/select/mapperEmpMapper
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.atguigu.mybatis.mapper.EmpMapper!--处理多对一的映射关系有三种方法第一种级联方式处理第二种association 处理多对一的映射关系处理的是实体类类型的属性第三种分布查询--!-- ************ 第一种级联方式处理 *************** --resultMap idEmpAndDeptById_resultMap typeEmpid columnemp_id propertyempId/idresult columnemp_name propertyempName/resultresult columnage propertyage/resultresult columngender propertygender/resultresult columndept_id propertydept.deptId/resultresult columndept_name propertydept.deptName/result/resultMap!--Emp getEmpAndDeptById(Param(empId) Integer empId);--select idgetEmpAndDeptById resultMapEmpAndDeptById_resultMapselect *from t_empleft join t_dept on t_emp.dept_id t_dept.dept_idwhere t_emp.emp_id#{empId}/select!-- *********************************************--!-- *************** 第二种 association ******************************--!-- 第二种 association--resultMap idgetEmpAndDeptById_association_resultMap typeEmpid columnemp_id propertyempId/idresult columnemp_name propertyempName/resultresult columnage propertyage/resultresult columngender propertygender/result!--association: 处理多对一的映射关系处理实体类类型的属性property: 设置需要处理映射关系的属性的属性名javaType: 设置要处理的属性的类型, 就是把association标签下设置映射关系的字段封装给某个类--association propertydept javaTypeDeptid columndept_id propertydeptId/idresult columndept_name propertydeptName/result/association/resultMap!-- Emp getEmpAndDeptById_association(Param(empId) Integer empId);--select idgetEmpAndDeptById_association resultMapgetEmpAndDeptById_association_resultMapselect *from t_empleft join t_dept on t_emp.dept_id t_dept.dept_idwhere t_emp.emp_id#{empId}/select!-- *********************************************--!-- ****************** 第三种分布查询 ***************************--resultMap idgetEmpAndDeptByIdOne_resultMap typeEmpid columnemp_id propertyempId/idresult columnemp_name propertyempName/resultresult columnage propertyage/resultresult columngender propertygender/result!--property: 设置需要处理映射关系的属性的属性名select: 填写分步查询的sql的唯一标识就是设置下一步要执行的sql语句column: 将上一个sql查询出的某个字段作为分步查询的下一个sql语句sql条件相当于函数的参数传给下一个sql语句fetchType: 在开启了延时加载的环境中通过该属性设置当前的分步查询是否使用延迟加载有两个值eager立即加载 lazy(延迟加载)--association propertydeptfetchTypeeagerselectcom.atguigu.mybatis.mapper.EmpMapper.getEmpAndDeptByIdTwocolumndept_id/association/resultMap!-- Emp getEmpAndDeptByIdOne(Param(empId) Integer empId);--select idgetEmpAndDeptByIdOne resultMapgetEmpAndDeptByIdOne_resultMapselect * from t_emp where emp_id #{empId}/select!-- Dept getEmpAndDeptByIdTwo(Param(deptId) Integer deptId);--select idgetEmpAndDeptByIdTwo resultTypeDeptselect * from t_dept where dept_id #{deptId}/select!-- *********************************************--/mapperResultMapTest
import com.atguigu.mybatis.mapper.DeptMapper;
import com.atguigu.mybatis.mapper.EmpMapper;
import com.ruanjian.pojo.Dept;
import com.ruanjian.pojo.Emp;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;import java.io.IOException;public class ResultMapTest {private SqlSession session;/*处理多对一的映射关系有三种方法第一种级联方式处理第二种association 处理多对一的映射关系处理的是实体类类型的属性第三种分步查询*/// *********************** 多对一 ****************************************Test// 第三种分步查询public void textGetEmpAndDeptByIdOne() {EmpMapper mapper session.getMapper(EmpMapper.class);Emp emp mapper.getEmpAndDeptByIdOne(1);System.out.println(emp);}Test// 第二种associationpublic void textGetEmpAndDeptById_association() {EmpMapper mapper session.getMapper(EmpMapper.class);Emp emp mapper.getEmpAndDeptById_association(2);System.out.println(emp);}Test// 第一种级联方式处理public void textGetEmpAndDeptById() {EmpMapper mapper session.getMapper(EmpMapper.class);Emp emp mapper.getEmpAndDeptById(2);System.out.println(emp);}// *********************** 一对多 ****************************************Test// 分步查询public void textGetDeptAndEmpByStep() {DeptMapper mapper session.getMapper(DeptMapper.class);Dept dept mapper.getDeptAndEmpByStepOne(2);System.out.println(dept);}Test// 一对多查询public void textGetDeptAndEmpById() {DeptMapper mapper session.getMapper(DeptMapper.class);Dept dept mapper.getDeptAndEmpById(1);System.out.println(dept);}// ***************************************************************// junit会在每一个Test方法前执行Before方法Beforepublic void init() throws IOException {session new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream(mybatis-config.xml)).openSession();}// junit会在每一个Test方法后执行After方法Afterpublic void clear() {session.commit();session.close();}
} db.properties
mysql.drivercom.mysql.cj.jdbc.Driver
mysql.urljdbc:mysql://localhost:3306/mybatis?serverTimezoneUTCcharacterEncodingutf8useUnicodetrueuseSSLfalse
mysql.usernameroot
mysql.password123456log4j.xml
?xml version1.0 encodingUTF-8 ?
!DOCTYPE log4j:configuration SYSTEM log4j.dtdlog4j:configuration xmlns:log4jhttp://jakarta.apache.org/log4j/appender nameSTDOUT classorg.apache.log4j.ConsoleAppenderparam nameEncoding valueUTF-8/layout classorg.apache.log4j.PatternLayoutparam nameConversionPattern value%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n//layout/appenderlogger namejava.sqllevel valuedebug//loggerlogger nameorg.apache.ibatislevel valueinfo//loggerrootlevel valuedebug/appender-ref refSTDOUT//root
/log4j:configurationmybatis-config.xml
?xml version1.0 encodingUTF-8 ?
!DOCTYPE configurationPUBLIC -//mybatis.org//DTD Config 3.0//ENhttp://mybatis.org/dtd/mybatis-3-config.dtd
configuration!--环境配置--!--引入外部db.properties--properties resourcedb.properties/settings!-- setting namecacheEnabled valuetrue /--!-- 开启延时加载--setting namelazyLoadingEnabled valuetrue/!-- 开启时即为true时任何方法的调用都会加载相关类的全部属性false时是按需加载true是全部加载--setting nameaggressiveLazyLoading valuefalse/setting namemapUnderscoreToCamelCase valuetrue//settingstypeAliasespackage namecom.ruanjian.pojo//typeAliases!--配置mybatis的连接环境可以配置多个环境--environments defaultdevelopment!--开发环境--environment iddevelopment!--使用JDBC事务管理--transactionManager typeJDBC/!--数据库连接相关配置db.properties文件中的内容--!--使用连接池技术--dataSource typePOOLED!--数据库驱动--property namedriver value${mysql.driver}/!--连接字符串--property nameurl value${mysql.url}/!--数据库用户名--property nameusername value${mysql.username}/!--数据库密码--property namepassword value${mysql.password}//dataSource/environment/environments!--mapping文件路径配置--mappers!-- mapper resourcemapper/DeptMapper.xml/--package namecom.atguigu.mybatis.mapper//mappers
/configuration pom.xml
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.itheima/groupIdartifactIdMyBaits_2/artifactIdversion1.0-SNAPSHOT/versionbuildpluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdconfigurationsource8/sourcetarget8/target/configuration/plugin/plugins/buildpropertiesmaven.compiler.sourece11/maven.compiler.sourecemaven.compiler.target11/maven.compiler.targetproject.build.sourceEncodingUTF-8/project.build.sourceEncoding/propertiesdependenciesdependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion3.5.2/version/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.11/versionscoperuntime/scope/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/versionscopetext/scope/dependency!-- log4j日志 --dependencygroupIdlog4j/groupIdartifactIdlog4j/artifactIdversion1.2.17/version/dependency/dependencies
/project注意
新建包时用点 例如com.atguigu.mybatis.mapper
resources目录下建立多层目录的时候时是用分割线 例如com/atguigu/mybatis/mapper mybatis-config.xml文件中
package namecom.atguigu.mybatis.mapper/package的使用条件: 接口文件要和xml文件同名并且在同一个目录下
使用注解写的接口只能有class的方式注册例
mapper classcom.atguigu.mybatis.mapper.DeptMapper/mapper