学习mybatis3的第5天

学习mybatis3的第5天

在这里插入图片描述

场景二:之前是查员工的时候,顺序得到这个员工所在的部门。(一对一)现在变一下,是查部门的时候,把这个部门的所有员工查出来。(一对多)

Collection的讲解。

使用多表联查的形式:

SELECT 
	d.id did, d.dept_name dept_name,
	e.id eid,e.last_name last_name,
	e.email email, e.gender gender
FROM `tbl_dept` d
LEFT JOIN `tbl_employee` e
ON d.id = e.d_id
WHERE d.id = 1;

在这里插入图片描述

这些就是现在查出来的列。
did  dept_name     eid  last_name  email   gender  

下面这些是javaBean的属性名。
在这里插入图片描述
1、写接口:DepartmentMapper

public interface DepartmentMapper {
   public Department getDeptById(Integer id);

	//根据部门id,查出这个部门信息,以及该部门对应的所有员工信息。
   public Department getDeptByIdPlus(Integer id);

}

在这里插入图片描述
2、对应的sql映射配置文件:(关键)

方式一:使用collection嵌套的意思。

 <resultMap id="MyDept" type="com.rtl.mybatis.bean.Department">
        <id column="did" property="id"></id>
        <result column="dept_name" property="departmentName"></result>
        <collection property="emps" ofType="com.rtl.mybatis.bean.Employee">
            <id column="eid" property="id"></id>
            <result column="last_name" property="lastName"></result>
            <result column="email" property="email"></result>
            <result column="gender" property="gender"></result>
        </collection>
    </resultMap>

    <select id="getDeptByIdPlus" resultMap="MyDept">
        SELECT
            d.id did, d.dept_name dept_name,
            e.id eid,e.last_name last_name,
            e.email email, e.gender gender
        FROM `tbl_dept` d
        LEFT JOIN `tbl_employee` e
        ON d.id = e.d_id
        WHERE d.id = #{id};
    </select>

在这里插入图片描述

方式二:使用collection分步查询。

sql:

第一步:
SELECT * FROM tbl_dept WHERE id = 1;

第二步:
SELECT * FROM tbl_employee WHERE d_id = 1;

1、先在接口里面去声明方法:DepartmentMapper

public Department getDeptByIdStep(Integer id);

在这里插入图片描述
2、去写sql映射配置文件DepartmentMapper.xml
因为分步查询里面的第二步就是按照部门id去查这个部门对应的所有的员工。
3、所以要先在EmployeeMapperPlus这里面去添加方法。

public List<Employee> getEmpsByDeptId(Integer deptId);

在这里插入图片描述
4、去完善EmployeeMapperPlus.xml

<select id="getEmpsByDeptId" resultType="com.rtl.mybatis.bean.Employee">
        select * from tbl_employee where d_id = #{deptId}
    </select>

5、写好这些之后,再来完善:DepartmentMapper.xml(关键!!)
使用collection实现分布查询。

<resultMap id="MyDeptStep" type="com.rtl.mybatis.bean.Department">
        <id column="id" property="id"></id>
        <result column="dept_name" property="departmentName"></result>
        <collection property="emps" select="com.rtl.mybatis.dao.EmployeeMapperPlus.getEmpsByDeptId" column="id"></collection>
    </resultMap>
    <select id="getDeptByIdStep" resultMap="MyDeptStep">
        SELECT id,dept_name FROM tbl_dept WHERE id = #{id};
    </select>

在这里插入图片描述
6、测试类:


    //测试查询:写的是resultMap,查询一个部门的所有员工(一对多)的时候,使用collection标签。分步查询的形式
    @Test
    public void test16() throws IOException {
        //(16,17,18行)1、根据这个全局的mybatis-config.xml配置文件生成一个SqlSessionFactory对象。
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2、根据SqlSessionFactory对象获取sqlSession实例,整个实例可以执行已经映射的sql语句。
        SqlSession openSession = sqlSessionFactory.openSession();
        try {
            //获取接口EmployeeMapper的实现类对象
            DepartmentMapper mapper = openSession.getMapper(DepartmentMapper.class);
            Department department = mapper.getDeptByIdStep(1);
            System.out.println(department);
            List<Employee> emps = department.getEmps();
            for (Employee emp : emps) {
                System.out.println(emp);
            }
        }finally {
            openSession.close();
        }
    }

在这里插入图片描述
注意。xml的内容这样也是可以的:

 <resultMap id="MyDeptStep" type="com.rtl.mybatis.bean.Department">
        <id column="id" property="id"></id>
        <result column="dept_name" property="departmentName"></result>
        <collection property="emps" select="com.rtl.mybatis.dao.EmployeeMapperPlus.getEmpsByDeptId" column="{deptId=id}"></collection>
    </resultMap>

在这里插入图片描述
在这里插入图片描述
其中这里的column的意思就是,它前面的select标签里面的查询语句需要的参数,都是由这个column来提供。
假设前面的查询语句需要两个参数的话,那就以map的形式传递过来。
clomun={deptId=id}
右边的id是第一步从部门表里面查出来的实际值。部门id
赋值给第二部查询需要的参数。
这样中间的查询方法,里面的参数才有值了。

动态SQL

之前的拼串SQL非常的复杂。
需要学习以下几个标签:
if
choose(when otherwise)
trim (where set)
foreach

1、创建接口:EmployeeMapperDynamicSQL
在这里插入图片描述

package com.rtl.mybatis.dao;

public interface EmployeeMapperDynamicSQL {

}

在这里插入图片描述

2、创建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.rtl.mybatis.dao.EmployeeMapperDynamicSQL">

</mapper>

在这里插入图片描述

学习if标签 判断

需求:
要求查询的时候,携带了哪个字段就带上这个字段的值。如果是null,就不要。
1、在接口EmployeeMapperDynamicSQL里面提供方法。

 public List<Employee> getEmpsByConditionIf(Employee employee);

在这里插入图片描述
2、修改EmployeeMapperDynamicSQL.xml

<select id="getEmpsByConditionIf" resultType="com.rtl.mybatis.bean.Employee">
        select * from tbl_employee
        where id=#{id} and last_name=#{lastName}
          and email=#{email} and gender=#{gender}
    </select>

在这里插入图片描述
改进:
where后面的东西不能写死。

 <select id="getEmpsByConditionIf" resultType="com.rtl.mybatis.bean.Employee">
        select * from tbl_employee
        where
            <if test="id!=null">
                id=#{id}
            </if>

            <if test="last_name!=null and last_name!=''">
               and last_name like #{lastName}
            </if>
            <if test="email!=null and email.trim()!=''">
                and email=#{email}
            </if>
            <if test="gender==0 or gender == 1">
                and gender=#{gender}
            </if>
    </select>

在这里插入图片描述
在这里插入图片描述
我们发现gender在javaBean里面是String数据类型,但是写的时候可以直接
gender == 0 or gender == 1
因为OGNL会默认进行字符串和数字的转换操作。
3、现在去写测试类。

 @Test
    public void test17() throws IOException {
        //(16,17,18行)1、根据这个全局的mybatis-config.xml配置文件生成一个SqlSessionFactory对象。
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2、根据SqlSessionFactory对象获取sqlSession实例,整个实例可以执行已经映射的sql语句。
        SqlSession openSession = sqlSessionFactory.openSession();
        try {
            //获取接口EmployeeMapper的实现类对象
            EmployeeMapperDynamicSQL mapper = openSession.getMapper(EmployeeMapperDynamicSQL.class);
            Employee employee = new Employee(1, "jerry", null, null);
            List<Employee> emps = mapper.getEmpsByConditionIf(employee);
            for (Employee emp : emps) {

                System.out.println(emp);
            }
        }finally {
            openSession.close();
        }
    }

但是这样写会有问题。
问题:当第一个id 是null的时候
那么sql就变成这样了:
select * from tbl_emp
where and last_name lile “jerry”
直接就报语法错误了。
最终版:建议加上where 标签比较好。

<select id="getEmpsByConditionIf" resultType="com.rtl.mybatis.bean.Employee">
        select * from tbl_employee
        <where>
            <if test="id!=null">
                id=#{id}
            </if>

            <if test="lastName!=null and lastName!=''">
               and last_name like #{lastName}
            </if>
            <if test="email!=null and email.trim()!=''">
                and email=#{email}
            </if>
            <if test="gender==0 or gender == 1">
                and gender=#{gender}
            </if>
        </where>
    </select>

在这里插入图片描述

学习set标签。

1、在接口里面定义一个更新方法。
不要全字段的更新,而是,你带了哪一列的值就更新哪一列。如果这一列是null,那就维持原先的值。

public void updateEmp(Employee employee);

在这里插入图片描述

2、使用set标签:

 <update id="updateEmp">
        update tbl_employee
        <set>
            <if test="lastName!=null">
                last_name=#{lastName},
            </if>
            <if test="email!=null">
                email=#{email},
            </if>
            <if test="gender!=null">
                gender=#{gender}
            </if>
        </set>
            where id = #{id}
    </update>

测试类:

    @Test
    public void test18() throws IOException {
        //(16,17,18行)1、根据这个全局的mybatis-config.xml配置文件生成一个SqlSessionFactory对象。
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2、根据SqlSessionFactory对象获取sqlSession实例,整个实例可以执行已经映射的sql语句。
        SqlSession openSession = sqlSessionFactory.openSession();
        try {
            //获取接口EmployeeMapper的实现类对象
            EmployeeMapperDynamicSQL mapper = openSession.getMapper(EmployeeMapperDynamicSQL.class);
            Employee employee = new Employee(1, "jerry1", "jerry@163.com", null);
            mapper.updateEmp(employee);
            openSession.commit();
        }finally {
            openSession.close();
        }


    }

使用foreach查询id是给定的集合中

就是 where id in(1,2,3)这种
1、接口中添加方法。

public List<Employee> getEmpsByConditionForeach(@Param("ids") List<Integer> ids);

在这里插入图片描述

2、修改xml
普通写法:不使用foreach进行遍历。

<select id="getEmpsByConditionForeach" resultType="com.rtl.mybatis.bean.Employee">
        select * from tbl_employee where id in(1,2,3)
    </select>

使用foreach进行遍历。

 <select id="getEmpsByConditionForeach" resultType="com.rtl.mybatis.bean.Employee">
        select * from tbl_employee where id in(
            <foreach collection="ids" item="item_id" separator=",">
                #{item_id}
            </foreach>
            )
    </select>

在这里插入图片描述

collection代表指定要遍历的集合。
item将当前遍历的元素赋值给指定的变量。
separator代表每个元素之间的分隔符
写得好看一点,把两边的括号去掉。

<select id="getEmpsByConditionForeach" resultType="com.rtl.mybatis.bean.Employee">
        select * from tbl_employee where id in
            <foreach collection="ids" item="item_id" separator="," open="(" close=")">
                #{item_id}
            </foreach>
    </select>

在这里插入图片描述
open:遍历出所有结果拼接一个开始的字符。
close:遍历出所有结果拼接一个结束的字符。

使用foreach进行批量插入数据。(难度)

1、修改接口

 public void addEmps(@Param("emps") List<Employee> emps);

在这里插入图片描述
2、修改mapper.xml
正常的sql;

INSERT INTO `tbl_employee`(last_name,email,gender,d_id)  
	VALUES("tom","tom@123.com",'1',1),("frank","frank@123.com",'0',1);

使用foreach版本的:

 <insert id="addEmps">
        INSERT INTO `tbl_employee`(last_name,email,gender,d_id)
        VALUES
               <foreach collection="emps" item="emp" separator=",">
                   (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
               </foreach>
    </insert>

在这里插入图片描述
测试类:

//测试 使用foreach实现 批量插入数据
    @Test
    public void test20() throws IOException {
        //(16,17,18行)1、根据这个全局的mybatis-config.xml配置文件生成一个SqlSessionFactory对象。
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2、根据SqlSessionFactory对象获取sqlSession实例,整个实例可以执行已经映射的sql语句。
        SqlSession openSession = sqlSessionFactory.openSession();
        try {
            //获取接口EmployeeMapper的实现类对象
            EmployeeMapperDynamicSQL mapper = openSession.getMapper(EmployeeMapperDynamicSQL.class);
            List<Employee> list = Arrays.asList(
                    new Employee(null, "tom1", "tom2@123.com", "1",new Department(1,"开发部")),
                    new Employee(null, "tom2", "tom2@123.com", "1",new Department(2,"测试部")));
            mapper.addEmps(list);
            openSession.commit();
        }finally {
            openSession.close();
        }
    }

mybatis里面两个重要的内置参数。

1、_parameter

代表接口方法里面的整个参数
add(Integer id) _parameter代表id
adds(List emps) _parameter代表emps

这就代表,传过来的整个参数不允许为空。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/1a7b7721a95c45159501b67638d74ffe.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pyJ5LiK6L-b5b-D55qE6Zi_6b6Z,size_20,color_FFFFFF,t_70,g_se,x_16)

2、_databaseId

学习与select,insert,delete,update同级的标签-sql标签

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值