ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

mybait多表联查

2022-02-23 20:03:31  阅读:205  来源: 互联网

标签:mybait 映射 List dept emp 多表 联查 id user


1. 动态Sql

1.1 动态Sql-where条件

1.1.1 业务需求
  • 需求:根据对象中不为null的数据,充当where条件 进行查询

例子:根据属性来查询

  • 	User user = new User();
    	user.setId(null).setName(null).setAge(100).setSex("男")
    	Sql: select * from demo_user where 
    		age = #{age} 
    		and sex = #{sex}
    
1.1.2 编辑测试类
  • @SpringBootTest
    public class TestMybatis2 {
    
        @Autowired  依赖注入 多态代理
        private UserMapper2 userMapper;
    
        /**
         * 案例1: 测试动态sql
         */
        @Test
        public void testDemo1(){
          //pojo对象对应数据库中的查询表
            User user = new User(); 
          //根据字段设置查询条件
            user.setAge(18).setSex("女"); //动态变化的数据
            List<User> userList = userMapper.findUserList(user);
            System.out.println(userList);
        }
    }
    
    
1.1.3 编辑UserMapper接口
  • @Mapper
    public interface UserMapper2 {
    
        List<User> findUserList(User user);
    }
    
    
1.1.4 编辑UserMapper.xml映射文件
  • 满足if判断,进行拼接sql,不满足则不拼接;

  • <?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.jt.mapper.UserMapper2">
    
        <!--
            动态Sql:根据对象中不为null的属性当作where条件
            语法:
                   1.如果判断成立,则动态拼接条件
                   <if test="id !=null ">条件</if>
                   2.where标签  去除where后边多余的一个and/or
        -->
        <select id="findUserList" resultType="User">
            select * from demo_user
            <where>
                <if test="id !=null ">id = #{id}</if>
                <if test="name !=null">and name = #{name}</if>
                <if test="age !=null ">and age = #{age}</if>
                <if test="sex !=null ">and sex = #{sex}</if>
            </where>
        </select>
    </mapper>
    
    

1.2 动态Sql-set条件

1.2.1 编辑测试类
  • 执行动态的更新操作

  • 
        //根据对象中不为null的元素,充当set条件. where id=xxx
        @Test
        public void testDemo2(){
            User user = new User();
          //将表中id为231的信息进行替换
            user.setId(231).setName("冬天").setAge(18);
            userMapper.updateUser(user);
            System.out.println("更新成功!!!");
        }
    
    
    1.2.2 编辑业务接口
  • 	void updateUser(User user);
    
    
1.2.3 编辑xml映射文件
  • 标签可以自动的去除多余逗号

  • <!--根据对象中不为null的元素,充当set条件.-->
        <update id="updateUser">
            update demo_user
                <set>
                    <if test="name !=null">name = #{name},</if>
                    <if test="age !=null">age = #{age},</if>
                    <if test="sex !=null">sex = #{sex}</if>
                </set>
                where id = #{id}
        </update>
    
    

1.3 动态Sql-choose、when、otherwise

1.3.1 业务需求
  • 说明: 如果不想使用所有的条件可以使用choose 类似于java中的switch 语法:
  • 如果name有值,则按照name查询,否则按照sex查询数据
1.3.2 编辑测试类
  • @Test
        public void testDemo3(){
            User user = new User();
            user.setName(null).setAge(null).setSex("女");
            List<User> userList = userMapper.findUserByNS(user);
            System.out.println(userList);
        }
    
    
  • 1.3.3 编辑业务接口
  •  List<User> findUserByNS(User user);
      
    
1.3.4 编辑Mapper 映射文件
  • 类似java中if elseif else的关系;

  •  <select id="findUserByNS" resultType="User">
            select * from demo_user
                <where>
                    <choose>
                        <when test="name !=null">
                            name = #{name}
                        </when>
                        <when test="age !=null">
                            age = #{age}
                        </when>
                        <otherwise>
                            sex = #{sex}
                        </otherwise>
                    </choose>
                </where>
        </select>
      
    

1.4 resultMap

1.4.1 需求说明
  • 当表中的字段与POJO中的属性名称不一致时,需要使用resultMap的方式进行映射.
1.4.3 创建POJO对象
  • @Data
    @Accessors(chain = true)
    @NoArgsConstructor
    @AllArgsConstructor
    public class Dog implements Serializable {
        private Integer dogId;
        private String  dogName;
        private Integer age;
    }
    
    
1.4.4 测试结果
  • 表中的字段名称与对象中的属性名称不一致. 结果:数据不能映射.
1.4.4 关于返回属性的说明
  • resultType : 只能支持字段名称属性的名称一致时才能自动映射.
  • resultMap: 可以支持 任意类型的映射 万能的结构
1.4.5 编辑测试类
  •  @Test
        public void testDog(){
            List<Dog> dogList = dogMapper.findAll();
            System.out.println(dogList);
        }
      
    
  • 1.4.6 编辑Mapper接口
  • @Mapper
    public interface DogMapper {
        List<Dog> findAll();
    }
    
    
    
1.4.7 编辑Mapper 映射文件
  • 就是为了让pojo对象中的属性与表中属性名进行匹配

  • <?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">
    //一个接口对应一个xml文件
    <mapper namespace="com.jt.mapper.DogMapper">
    
        <select id="findAll" resultMap="dogRM">
            select * from dog
        </select>
    
        <resultMap id="dogRM" type="Dog">
            <!--ID:代表主键-->
            <id column="dog_id" property="dogId"/>
            <!--结果集-->
            <result column="dog_name" property="dogName"/>
            <!--<result column="age" property="age"/>-->
        </resultMap>
    </mapper>
    
    

1.5 开启驼峰规则映射

  • 说明: 在业务中经常出现该现象. 字段 user_id 属性:userId 属性和字段有驼峰映射规则.但是采用resultType的方式进行映射.则不能正常赋值.

  • 解决方案:

  • 1**.resultMap** :步骤比较繁琐

  • 2.resultType+开启驼峰映射规则(配置yml文件)

    • mybatis:
        #定义别名包
        type-aliases-package: com.jt.pojo
        #将所有的映射文件全部加载
        mapper-locations: classpath:/mappers/*.xml
        #开启驼峰映射
        configuration:
          map-underscore-to-camel-case: true
      
      

2 Mybatis 关联查询

2.1 常见关联关系

  • 一对一 一个员工对应一个部门
  • 一对多 一个部门对应多个员工
  • 多对多:
  • 双向的一对多 1.一个老师对应多个学生,2.一个学生对应多个老师

2.2 创建数据表

  • 说明: 一个员工emp对应一个部门dept

  • 1.emp表:

  • img

  • \2. 部门表dept:

  • img

2.3 关联查询Sql

2.3.1 笛卡尔积的方式

特点: 只获取2张表的 交集

  • SELECT * FROM emp,dept 
    WHERE emp.dept_id = dept.dept_id
    

2.3.2 连接查询

分类: 1.左连接 2.内连接 3.右连接

  • /*左连接  emp表当作主表 */
    SELECT * FROM 
    	emp 
    		LEFT JOIN
    	dept
    		ON
    	emp.dept_id = dept.dept_id
    
    

2.4 封装关联关系

2.4.1 封装Emp对象
  • 注意:关联关系: 一个员工对应一个部门

  • 在员工类中封装部门的对象;

  • 
    import java.io.Serializable;
    
    @Data
    @Accessors(chain = true)
    @NoArgsConstructor
    @AllArgsConstructor
    public class Emp implements Serializable {
        private Integer id;
        private String name;
        private Integer age;
        //关联关系: 一个员工对应一个部门
        private Dept dept;
        //private Integer deptId;
    }
    
    
    

2.4.2 封装Dept对象

  • 注意:关联 一个部门下有多个员工

  • 在部门的类中创建一个list集合存放员工对象;

  • package com.jt.pojo;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import lombok.experimental.Accessors;
    
    import java.io.Serializable;
    import java.util.List;
    @Data
    @Accessors(chain = true)
    @NoArgsConstructor
    @AllArgsConstructor
    public class Dept implements Serializable {
        private Integer deptId;
        private String deptName;
        //关联 一个部门下有多个员工
        private List<Emp> emps;
    }
    
    

2.5 一对一封装

2.5.1 编辑测试类
  • 通过迪卡尔积查询2张表的信息

  • 
    import java.util.List;
    
    @SpringBootTest
    public class TestMybatis3 {
    
        @Autowired
        private EmpMapper empMapper;
    
        @Test
        public void testOneToOne(){
    
            List<Emp> empList = empMapper.findAll();
            System.out.println(empList);
        }
    }
    
2.5.2 编辑测试接口
  • @Mapper
    public interface EmpMapper {
    
        List<Emp> findAll();
    }
    
    

2.5.3 编辑xml映射文件

  • 注意:主键必填项

  • 1.如果进行关联操作,使用resultMap

  • 2.如果是多表关联操作,则不允许出现重名字段.否则映射失败.

  • ​ 所以在连接查询时,不能使用 select *

  • ​ 需要使用 SELECT emp.*,dept.dept_name 来去除一个dept.dept_id

  • 3.如果有关联映射: 则需要添加自动映射的开关autoMapping="true"

  • ​ 该注解只对当前对象有效 如果有多个对象,则需要添加多次

  • 4.一对一关联封装 association标签

  • 必须指定属性的类型 javaType属性

  • 对应的是Emp类中的:private Dept dept;

  • <?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.jt.mapper.EmpMapper">
        <!--
            规则:
                1.如果操作单表 一般使用resultType
                2.如果进行关联操作,使用resultMap
                3.如果是多表关联操作,则不允许出现重名字段.否则映射失败.
        -->
        <select id="findAll" resultMap="empRM">
            SELECT emp.id,emp.name,emp.age,dept.dept_id,
    	    dept.dept_name
    	    FROM emp,dept
    	    WHERE emp.dept_id = dept.dept_id
        </select>
    
        <!--
            关于自动映射规则:
                1.没有关联映射时: 如果属性和字段同名,则可以省略不写.
                2.如果有关联映射: 则需要添加自动映射的开关autoMapping="true"
                               该注解只对当前对象有效 如果有多个对象,则需要添加多次
        -->
        <resultMap id="empRM" type="Emp" autoMapping="true">
            <!--主键是必填项-->
            <id column="id" property="id"/>
            <!--
                知识点:
                    1.一对一关联封装 association标签
                    2.必须指定属性的类型 javaType属性
                    3.autoMapping="true" 自动映射
             -->
            <association property="dept" javaType="Dept" autoMapping="true">
                <!--主键必填项-->
                <id column="dept_id" property="deptId"/>
                <!--由于一起开启驼峰规则映射.所以下列的操作可以省略-->
                <!--<result column="dept_name" property="deptName"/>-->
            </association>
        </resultMap>
    </mapper>
    
    

2.5 一对多封装

  • 需求:查询每个部门员工

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M8dBcZLf-1645617048586)(C:\Users\86131\Desktop\学习图库\左连接.png)]

  • SELECT dept.dept_name,emp.* FROM dept LEFT JOIN emp
    ON emp.dept_id=dept.dept_id
    
    2.5.1 关联说明
  • 一个部门下,对应多个员工, 主对象是Dept

  •  //一个部门存在多个员工 一对多的关系
        List<Emp> emps;
    
2.5.2 编辑测试类
  •     @Test
        public void test2(){
            List<Dept> list=deptMapper.findAll();
            System.out.println(list);
        }
    
    
2.5.3 编辑测试接口
  • @Mapper
    public interface DeptMapper {
        List<Dept> findAll();
    }
    
    

2.5.4 编辑xml映射文件

  • 步骤

  • 1.一个接口对应一个映射文件

  • 2.id代表方法名 resultMap 名称随意

  • 3.type 代表List list=deptMapper.findAll();方法中返回的对象

  • 4.必须设置主键

  • 5.对于一对多的封装 需要使用collection标签

  • 6.设置主键

  • 1.一个接口对应一个映射文件
    <mapper namespace="com.jt.mapper.DeptMapper">
      2.id代表接口中方法名 resultMap 名称随意
        <select id="findAll" resultMap="deptRM">
            SELECT dept.dept_name,emp.* FROM
            dept LEFT JOIN emp
            ON emp.dept_id=dept.dept_id
        </select>
      3.type 代表List<Dept> findAll();方法中返回的对象
        <resultMap id="deptRM" type="Dept" autoMapping="true">
          4.必须设置主键
            <id column="dept_id" property="deptId"></id>
          5.对于一对多的封装 需要使用collection标签
             property和ofType 对应的是Dept类中定义的:List<Emp> emps;
            <collection property="emps" ofType="Emp" autoMapping="true">
              6.设置主键
                <id column="id" property="id"></id>
            </collection>
        </resultMap>
    </mapper>
    

t LEFT JOIN emp
ON emp.dept_id=dept.dept_id

3.type 代表List findAll();方法中返回的对象

4.必须设置主键

5.对于一对多的封装 需要使用collection标签
property和ofType 对应的是Dept类中定义的:List emps;

6.设置主键





标签:mybait,映射,List,dept,emp,多表,联查,id,user
来源: https://blog.csdn.net/lilang001/article/details/123097838

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有