JavaWEB大神成长篇:if、where、choose标签详解(第七期)
·
7_动态SQL
-
1_if标签
-
接口
public interface EmpMapper2 { List<Emp> findByCondition(Emp emp); } -
映射文件
<?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.msb.mapper.EmpMapper2"> <!--List<Emp> findByCondition(Emp emp);--> <select id="findByCondition" resultType="emp"> select * from emp where 1 = 1 <if test="empno != null"> and empno = #{empno} </if> <if test="ename != null and ename != ''"> and ename like concat('%',#{ename},'%') </if> <if test="job != null and job != ''"> and job = #{job} </if> <if test="mgr != null"> and mgr = #{mgr} </if> <if test="hiredate != null"> and hiredate = #{hiredate} </if> <if test="sal != null"> and sal = #{sal} </if> <if test="comm != null"> and comm = #{comm} </if> <if test="deptno != null"> and deptno = #{deptno} </if> </select> </mapper> -
测试代码
public static void main(String[] args) { SqlSession sqlSession = MyBatisUtil.getSqlSession(false); EmpMapper2 mapper = sqlSession.getMapper(EmpMapper2.class); Emp condition = new Emp(); /* condition.setDeptno(20); */ /* condition.setSal(3000.0); */ /* condition.setHiredate(new java.sql.Date(81,1,22)); */ condition.setComm(0.0); condition.setDeptno(20); List<Emp> emps = mapper.findEmpByCondition(condition); for (Emp e:emps) { System.out.println(e); }
-
-
2_where标签
-
用于处理 where 关键字和 and
<select id="findEmpByCondition" resultType="emp"> select * from emp <where> <if test="empno != null"> and empno = #{empno} </if> <if test="ename != null and ename != ''"> and ename = #{ename} </if> <if test="job != null and job != ''"> and job = #{job} </if> <if test="mgr != null "> and mgr = #{mgr} </if> <if test="hiredate != null "> and hiredate = #{hiredate} </if> <if test="sal != null"> and sal= #{sal} </if> <if test="comm != null "> and comm = #{comm} </if> <if test="deptno != null "> and deptno = #{deptno} </if> </where> </select>
-
-
3_choose标签
-
前面的 when 条件成立 后面的 when 就不再判断了
<select id="findEmpByCondition2" resultType="emp"> select * from emp <where> <choose> <when test="empno != null"> and empno = #{empno} </when> <when test="ename != null and ename != ''"> and ename = #{ename} </when> <when test="job != null and job != ''"> and job = #{job} </when> <when test="mgr != null "> and mgr = #{mgr} </when> <when test="hiredate != null "> and hiredate = #{hiredate} </when> <when test="sal != null"> and sal = #{sal} </when> <when test="comm != null "> and comm = #{comm} </when> <when test="deptno != null "> and deptno = #{deptno} </when> </choose> </where> </selec>
-
-
4_set标签
-
接口
int updateEmpByCondition(Emp emp); -
映射文件
<!--int updateEmpByCondtion(Emp emp);--> <update id="updateEmpByCondtion" > update emp <set> <if test="ename != null and ename != '' "> , ename = #{ename} </if> <if test="job != null and ename != '' "> , job = #{job} </if> <if test="mgr != null "> , mgr = #{mgr} </if> <if test="hiredate != null "> , hiredate = #{hiredate} </if> <if test="sal != null "> , sal = #{sal} </if> <if test="comm != null "> , comm = #{comm} </if> <if test="deptno != null "> , deptno = #{deptno} </if> </set> where empno = #{empno} </update>
-
-
5_trim标签
-
Trim 标签处理 set
<update id="updateEmpByCondition2" > update emp <!-- prefix 要增加什么前缀 prefixOverrides 要去除什么前缀 suffix 要增加什么后缀 suffixOverrides 要去除什么后缀 set 是trim的一种特殊情况 --> <trim prefix="set" suffixOverrides="," > <if test="ename != null and ename != ''"> ename = #{ename}, </if> <if test="job != null and job != ''"> job = #{job}, </if> <if test="mgr != null "> mgr = #{mgr}, </if> <if test="hiredate != null "> hiredate = #{hiredate}, </if> <if test="sal != null"> sal = #{sal}, </if> <if test="comm != null "> comm = #{comm}, </if> <if test="deptno != null "> deptno = #{deptno}, </if> </trim> where empno = #{empno} </update> -
Trim 标签 处理 where
<select id="findEmpByCondition" resultType="emp"> <!-- prefix 要增加什么前缀 prefixOverrides 要去除什么前缀 suffix 要增加什么后缀 suffixOverrides 要去除什么后缀 set 是trim的一种特殊情况 --> select * from emp <trim prefix="where" prefixOverrides="and"> <if test="empno != null"> and empno = #{empno} </if> <if test="ename != null and ename != ''"> and ename = #{ename} </if> <if test="job != null and job != ''"> and job = #{job} </if> <if test="mgr != null "> and mgr = #{mgr} </if> <if test="hiredate != null "> and hiredate = #{hiredate} </if> <if test="sal != null"> and sal = #{sal} </if> <if test="comm != null "> and comm = #{comm} </if> <if test="deptno != null "> and deptno = #{deptno} </if> </trim> </select>
-
-
6_bind标签
-
7_sql标签
-
代码展示
<sql id="empColumn">empno,ename,job,mgr,hiredate,sal,comm,deptno</sql> <sql id="baseSelect">select <include refid="empColumn"></include> from emp</sql> <!--List<Emp> findByCondition(Emp emp);--> <select id="findByCondition" resultType="emp"> <include refid="baseSelect"></include> <trim prefix="where" prefixOverrides="and"> <if test="empno != null"> and empno = #{empno} </if> <if test="ename != null and ename != ''"> <bind name="likePattern" value="'%'+ename+'%'"/> and ename like #{likePattern} </if> <if test="job != null and job != ''"> and job = #{job} </if> <if test="mgr != null"> and mgr = #{mgr} </if> <if test="hiredate != null"> and hiredate = #{hiredate} </if> <if test="sal != null"> and sal = #{sal} </if> <if test="comm != null"> and comm = #{comm} </if> <if test="deptno != null"> and deptno = #{deptno} </if> </trim> </select>
-
-
8_foreach标签
-
代码展示
<!-- List<Emp> findByEmpnos1(int[] empnos); collection="" 遍历的集合或者是数组 参数是数组,collection中名字指定为array 参数是List集合,collection中名字指定为list separator="" 多个元素取出的时候 用什么文字分隔 open="" 以什么开头 close="" 以什么结尾 item="" 中间变量名 for(Person per:PersonList) --> <select id="findByEmpnos1" resultType="emp"> select * from emp where empno in <foreach collection="array" separator="," open="(" close=")" item="deptno"> #{deptno} </foreach> </select> <!-- List<Emp> findByEmpnos2(List<Integer> empnos);--> <select id="findByEmpnos2" resultType="emp"> select * from emp where empno in <foreach collection="list" separator="," open="(" close=")" item="deptno"> #{deptno} </foreach> </select>
-
8_MyBatis实现多表查询
-
1_关联查询
-
1_手动处理映射关系
-
实体类
public class Emp implements Serializable { private Integer empno; private String name; private String job; private Integer mgr; private Date hiredate; private Double sal; private Double comm; private Integer deptno; -
映射文件
<mapper namespace="com.xxx.mapper.EmpMapper"> <!-- 手动处理数据库查询字段和封装实体类属性之间的映射关系 1 主键一般使用id属性 2 当属性名和查询出的数据表字段名相同 可以不写映射关系 --> <resultMap id="empMap" type="emp"> <!--<id property="empno" column="empno"></id>--> <result property="name" column="ename"></result> <!-- <result property="job" column="job"></result> <result property="sal" column="sal"></result> <result property="hiredate" column="hiredate"></result> <result property="mgr" column="mgr"></result> <result property="comm" column="comm"></result> <result property="deptno" column="deptno"></result> --> </resultMap> <select id="findByEmpno" resultMap="empMap" > select * from emp where empno = #{empno} </select> </mapper>
-
-
2_一对一关联查询
-
数据准备: 创建项目表和项目记录表

CREATE TABLE `projects` ( `pid` int(2) NOT NULL AUTO_INCREMENT, `pname` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `money` int(11) NULL DEFAULT NULL, PRIMARY KEY (`pid`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; INSERT INTO `projects` VALUES (1, ' ***大学OA', 500000); INSERT INTO `projects` VALUES (2, '学生选课系统', 100000); INSERT INTO `projects` VALUES (3, '讲师测评系统', 20000); INSERT INTO `projects` VALUES (4, '线上问答系统 ', 20000); CREATE TABLE `projectrecord` ( `empno` int(4) NOT NULL, `pid` int(2) NOT NULL, PRIMARY KEY (`empno`, `pid`) USING BTREE, INDEX `fk_project_pro`(`pid`) USING BTREE, CONSTRAINT `fk_emp_pro` FOREIGN KEY (`empno`) REFERENCES `emp` (`EMPNO`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `fk_project_pro` FOREIGN KEY (`pid`) REFERENCES `projects` (`pid`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; INSERT INTO `projectrecord` VALUES (7369, 1); INSERT INTO `projectrecord` VALUES (7521, 1); INSERT INTO `projectrecord` VALUES (7369, 2); INSERT INTO `projectrecord` VALUES (7499, 2); INSERT INTO `projectrecord` VALUES (7521, 2); INSERT INTO `projectrecord` VALUES (7369, 3); INSERT INTO `projectrecord` VALUES (7499, 3); INSERT INTO `projectrecord` VALUES (7521, 3); INSERT INTO `projectrecord` VALUES (7369, 4); INSERT INTO `projectrecord` VALUES (7499, 4); -
需求: 根据编号查询员工信息及所在的部门信息
@AllArgsConstructor @NoArgsConstructor @Data public class Emp implements Serializable { private Integer empno; private String ename; private String job; private Integer mgr; private Date hiredate; private Double sal; private Double comm; private Integer deptno; // 组合一个Dept对象作为自己的属性 private Dept dept; }public interface EmpMapper { /** * 根据员工编号查询员工的所有信息并携带所在的部门信息 * @param empno 要查询的员工编号 * @return Emp对象, 组合了Dept对象作为属性, 对部门信息进行存储 */ Emp findEmpJoinDeptByEmpno(int empno); }<?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.msb.mapper.EmpMapper"> <!--Emp findEmpJoinDeptByEmpno(int empno);--> <resultMap id="empJoinDept" type="emp"> <!--设置emp本身的八个属性的映射关系--> <id property="empno" column="empno"></id> <result property="ename" column="ename"></result> <result property="job" column="job"></result> <result property="sal" column="sal"></result> <result property="hiredate" column="hiredate"></result> <result property="mgr" column="mgr"></result> <result property="comm" column="comm"></result> <result property="deptno" column="deptno"></result> <!-- association 处理一对一 封装一对一信息关系的标签 property emp类的属性名 javaType 用哪个类的对象给属性赋值 --> <association property="dept" javaType="dept"> <id column="deptno" property="deptno"></id> <result column="dname" property="dname"></result> <result column="loc" property="loc"></result> </association> </resultMap> <select id="findEmpJoinDeptByEmpno" resultMap="empJoinDept" > select * from emp e left join dept d on e.deptno = d.deptno where empno = #{empno} </select> </mapper> -
测试代码
@Test public void testOneToOne() throws ParseException { EmpMapper mapper = sqlSession.getMapper(EmpMapper.class); Emp emp = mapper.findEmpJoinDeptByEmpno(7499); System.out.println(emp); }
-
-
3_一对多关联查询
-
根据部门号查询部门信息及该部门的所有员工信息
-
实体类
@Data @AllArgsConstructor @NoArgsConstructor public class Dept implements Serializable { private Integer deptno; private String dname; private String loc; // 组合一个Emp的List集合作为属性 private List<Emp> empList; } -
接口
package com.xxx.mapper; import com.xxx.pojo.Dept; public interface DeptMapper { /** * 根据部门编号查询部门信息及该部分的所有员工信息 * @param deptno 要查询的部门编号 * @return Dept对象, 内部组合了一个Emp的List属性用于封装部门的所有员工信息 */ Dept findDeptJoinEmpsByDeptno(int deptno); } -
映射文件
<?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.xxx.mapper.DeptMapper"> <!--Dept findDeptJoinEmpsByDeptno(int deptno);--> <resultMap id="deptJoinEmps" type="dept"> <id column="deptno" property="deptno"></id> <result column="dname" property="dname"></result> <result column="loc" property="loc"></result> <!--处理一对多关系的标签--> <collection property="empList" ofType="emp" > <!--设置emp本身的八个属性的映射关系--> <id property="empno" column="empno"></id> <result property="ename" column="ename"></result> <result property="job" column="job"></result> <result property="sal" column="sal"></result> <result property="hiredate" column="hiredate"></result> <result property="mgr" column="mgr"></result> <result property="comm" column="comm"></result> <result property="deptno" column="deptno"></result> </collection> </resultMap> <select id="findDeptJoinEmpsByDeptno" resultMap="deptJoinEmps"> select * from dept d left join emp e on d.deptno =e.deptno where d.deptno =#{deptno} </select> </mapper> -
测试代码
@Test public void testOneToMany() throws ParseException { DeptMapper mapper = sqlSession.getMapper(DeptMapper.class); Dept dept = mapper.findDeptJoinEmpsByDeptno(20); System.out.println(dept); System.out.println("---------"); List<Emp> empList = dept.getEmpList(); empList.forEach(System.out::println); }
-
-
4_多对多关联查询
-
根据项目编号查询项目信息, 以及参与到该项目之中的所有的员工信息
-
实体类
@NoArgsConstructor @AllArgsConstructor @Data public class Project implements Serializable { private Integer pid; private String pname; private Integer money; // 组合一个ProjectRecord对象集合作为属性 private List<ProjectRecord> projectRecords; } @Data @AllArgsConstructor @NoArgsConstructor public class ProjectRecord implements Serializable { private Integer empno; private Integer pid; // 组合一个Emp对象作为属性 private Emp emp; } -
接口
package com.xxx.mapper; import com.xxx.pojo.Emp; import com.xxx.pojo.Project; public interface ProjectMapper { /** * 根据项目编号查询一个项目信息及参与该项目的所有员工信息 * @param pid 项目编号 * @return 所有信息封装的Project对象 */ Project findProjectJoinEmpsByPid(int pid); } -
映射文件
<?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.msb.mapper.ProjectMapper"> <!--Project findProjectJoinEmpsByPid(int pid);--> <resultMap id="projectJoinEmps" type="project"> <id column="pid" property="pid"></id> <result column="pname" property="pname"></result> <result column="money" property="money"></result> <!--一对多 集合属性 collection--> <collection property="projectRecords" ofType="projectRecord"> <id column="empno" property="empno"></id> <id column="pid" property="pid"></id> <!--一对一 --> <association property="emp" javaType="emp"> <id property="empno" column="empno"></id> <result property="ename" column="ename"></result> <result property="job" column="job"></result> <result property="sal" column="sal"></result> <result property="hiredate" column="hiredate"></result> <result property="mgr" column="mgr"></result> <result property="comm" column="comm"></result> <result property="deptno" column="deptno"></result> </association> </collection> </resultMap> <select id="findProjectJoinEmpsByPid" resultMap="projectJoinEmps"> select * from project p left join projectrecord pr on p.pid = pr.pid left join emp e on e.empno = pr.empno where p.pid= #{pid} </select> </mapper> -
测试代码
@Test public void testManyToMany() throws ParseException { ProjectMapper mapper = sqlSession.getMapper(ProjectMapper.class); Project project = mapper.findProjectJoinEmpsByPid(2); System.out.println(project.getPid()); System.out.println(project.getPname()); System.out.println(project.getMoney()); List<ProjectRecord> projectRecords = project.getProjectRecords(); for (ProjectRecord projectRecord : projectRecords) { Emp emp = projectRecord.getEmp(); System.out.println(emp); } }
-
-
-
2_级联查询
-
概念
-
1_立即加载
-
功能1:查询所有员工的信息(多对一关联)
-
功能2:查询10号部门及其该部门员工信息
@Data @AllArgsConstructor @NoArgsConstructor public class Dept implements Serializable { private Integer deptno; private String dname; private String loc; // 当前部门下的所有员工对象的List集合 private List<Emp> empList; } @Data @AllArgsConstructor @NoArgsConstructor public class Emp implements Serializable { private Integer empno; private String ename; private String job; private Integer mgr; private Date hiredate; private Double sal; private Double comm; private Integer deptno; }package com.xxx.mapper; import com.xxx.pojo.Dept; public interface DeptMapper { Dept findDeptByDeptno(int deptno); } package com.xxx.mapper; import com.xxx.pojo.Emp; import java.util.List; public interface EmpMapper { List<Emp> findEmpsByDeptno(int deptno); }
-
-
2_延迟加载 (按需加载)
-
-
3_总结
-
resultMap中的常见属性
属性 描述 property 需要映射到 JavaBean 的属性名称 javaType property 的类型,一个完整的类名,或者是一个类型别名。如果你匹配的是一个JavaBean,那 MyBatis 通常会自行检测到 column 数据表的列名或者列别名 jdbcType column 在数据库表中的类型。这个属性只在 insert、update 或 delete 的时候针对允许空的列有用。JDBC 需要这项,但 MyBatis 不需要 typeHandler 使用这个属性可以覆写类型处理器,实现 javaType、jdbcType 之间的相互转换。一般可以省略,会探测到使用的什么类型的 typeHandler 进行处理 fetchType 自动延迟加载 select association、collection的属性,使用哪个查询属性的值,要求指定namespace+id的全名称 ofType collection的属性,指明集合中元素的类型(即泛型类型) -
级联查询和多表查询的比较及其选择
对比项 级联查询 多表查询 SQL语句数 多条 一条 性能 性能低 性能高 延迟加载 立即加载、延迟加载 只有立即加载 灵活性 更灵活 不灵活 SQL难易度 简单 复杂 选择依据 简单、灵活 高性能 -
ResultType 和 ResultMap 使用场景
-
一对一关联映射的实现
-
多对多映射的实现
-
自关联映射
-
9_MyBatis注解开发
-
代码展示
public interface DeptMapper { Dept findDeptByDeptno(int deptno); @Select("select * from dept where deptno =#{deptno}") Dept findByDeptno(int deptno); @Update("update dept set dname =#{dname}, loc =#{loc} where deptno =#{deptno}") int updateDept(Dept dept); @Insert("insert into dept values(DEFAULT,#{dname},#{loc})") int addDept(Dept dept); @Delete("delete from dept where deptno =#{deptno}") int removeDept(int deptno); } -
注解和XML的优缺点
维度 XML 注解 (Annotation) 优点 1 类和类之间的解耦 简化配置 优点 2 利于修改。直接修改 XML 文件,无需到源代码中修改。 使用起来直观且容易,提升开发效率 优点 3 配置集中在 XML 中,对象间关系一目了然,利于快速了解项目和维护 类型安全,编译器进行校验,不用等到运行期才会发现错误。 优点 4 容易和其他系统进行数据交换 注解的解析可以不依赖于第三方库,可以直接使用 Java 自带的反射
更多推荐
所有评论(0)