JavaWeb企业级开发---Mybatis

记录在听黑马课的时候的笔记以及课堂上练习的代码,文章图源于我在听课的时候所截的屏,所以有些不清晰,请见谅。下面是课程链接,可点击自行跳转。

【黑马程序员JavaWeb开发教程,实现javaweb企业开发全流程(涵盖Spring+MyBatis+SpringMVC+SpringBoot等)】 https://www.bilibili.com/video/BV1m84y1w7Tb/?share_source=copy_web&vd_source=d521b664e1113402904fa9336bd1d0ac


目录

介绍

快速入门

配置SQL提示

JDBC介绍

数据库连接池

Lombok

基础操作

环境准备

删除

删除(预编译SQL)

新增员工

新增(主键返回)

更新

查询(根据ID查询)

查询(条件查询)

XML映射文件

Mybatis动态SQL

if

if案例--Set标签实现更新

foreach标签

sql&include--解决SQL语句重复,增强复用性


介绍

快速入门

快速入门实现:

bash 复制代码
// application.properties
#下面这些内容是为了让MyBatis映射
#指定Mybatis的Mapper文件
mybatis.mapper-locations=classpath:mappers/*xml
#指定Mybatis的实体目录
mybatis.type-aliases-package=com.jianglin.mybatis.entity
#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://localhost:3306/sd2
#连接数据库的用户名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=123456
java 复制代码
//User.java
package com.jianglin.pojo;

public class User {
    private Integer id;
    private String name;
    private Short age;
    private Short gender;
    private String phone;


    public User() {
    }

    public User(Integer id, String name, Short age, Short gender, String phone) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.phone = phone;
    }

    /**
     * 获取
     * @return id
     */
    public Integer getId() {
        return id;
    }

    /**
     * 设置
     * @param id
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public Short getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(Short age) {
        this.age = age;
    }

    /**
     * 获取
     * @return gender
     */
    public Short getGender() {
        return gender;
    }

    /**
     * 设置
     * @param gender
     */
    public void setGender(Short gender) {
        this.gender = gender;
    }

    /**
     * 获取
     * @return phone
     */
    public String getPhone() {
        return phone;
    }

    /**
     * 设置
     * @param phone
     */
    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String toString() {
        return "User{id = " + id + ", name = " + name + ", age = " + age + ", gender = " + gender + ", phone = " + phone + "}";
    }
}
//UserMapper.java
package com.jianglin.mapper;

import com.jianglin.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

@Mapper //在运行时,会自动生成该接口的实现类对象(代理对象), 并且将该对象交给IOC容器管理
public interface UserMapper {
    //查询全部用户信息
    @Select("select * from user")
    public List<User> list();
}
//testListUser.java
package com.jianglin;

import com.jianglin.mapper.UserMapper;
import com.jianglin.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest //测试
class MybatisStartApplicationTests {

    @Autowired
    private UserMapper userMapper;
    @Test
    public void testListUser(){
        List<User> list = userMapper.list();
        list.forEach(
                user -> {
                    System.out.println(user);
                }
        );
    }

}

配置SQL提示

JDBC介绍

JDBC实现:

java 复制代码
@Test
public void testJdbc() throws Exception {
    //1. 注册驱动
    Class.forName("com.mysql.cj.jdbc.Driver");

    //2. 获取连接对象
    String url = "jdbc:mysql://localhost:3306/mybatis";
    String username = "root";
    String password = "1234";
    Connection connection = DriverManager.getConnection(url, username, password);

    //3. 获取执行SQL的对象Statement,执行SQL,返回结果
    String sql = "select * from user";
    Statement statement = connection.createStatement();
    ResultSet resultSet = statement.executeQuery(sql);

    //4. 封装结果数据
    List<User> userList = new ArrayList<>();
    while (resultSet.next()){
        int id = resultSet.getInt("id");
        String name = resultSet.getString("name");
        short age = resultSet.getShort("age");
        short gender = resultSet.getShort("gender");
        String phone = resultSet.getString("phone");

        User user = new User(id,name,age,gender,phone);
        userList.add(user);
    }

    //5. 释放资源
    statement.close();
    connection.close();
}

JDBC是sun公司提供的一套操作关系型数据库的api,它仅仅是一套接口,是一套规范,各个数据库厂商来提供对应的实现,而数据库厂商提供的这套实现,又有一个非常高大上的名字叫数据库的驱动,但是由于sun公司提供的这套原始的JDBC的api操作起来比较繁琐,而且开发效率低下,所以现在市面上就出现了一些类似于Mybatis这样的持久层框架,用来对JDBC程序进行封装,从而来简化开发,提高性能,那日后的企业级开发也都会使用mybatis这样的框架进行,而不会直接基于原始的gdbc来操作。

数据库连接池

导入的依赖:

java 复制代码
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
        </dependency>

Lombok

引入Lombok实现:

java 复制代码
package com.jianglin.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Integer id;
    private String name;
    private Short age;
    private Short gender;
    private String phone;


//    public User() {
//    }
//
//    public User(Integer id, String name, Short age, Short gender, String phone) {
//        this.id = id;
//        this.name = name;
//        this.age = age;
//        this.gender = gender;
//        this.phone = phone;
//    }
//
//    /**
//     * 获取
//     * @return id
//     */
//    public Integer getId() {
//        return id;
//    }
//
//    /**
//     * 设置
//     * @param id
//     */
//    public void setId(Integer id) {
//        this.id = id;
//    }
//
//    /**
//     * 获取
//     * @return name
//     */
//    public String getName() {
//        return name;
//    }
//
//    /**
//     * 设置
//     * @param name
//     */
//    public void setName(String name) {
//        this.name = name;
//    }
//
//    /**
//     * 获取
//     * @return age
//     */
//    public Short getAge() {
//        return age;
//    }
//
//    /**
//     * 设置
//     * @param age
//     */
//    public void setAge(Short age) {
//        this.age = age;
//    }
//
//    /**
//     * 获取
//     * @return gender
//     */
//    public Short getGender() {
//        return gender;
//    }
//
//    /**
//     * 设置
//     * @param gender
//     */
//    public void setGender(Short gender) {
//        this.gender = gender;
//    }
//
//    /**
//     * 获取
//     * @return phone
//     */
//    public String getPhone() {
//        return phone;
//    }
//
//    /**
//     * 设置
//     * @param phone
//     */
//    public void setPhone(String phone) {
//        this.phone = phone;
//    }
//
//    public String toString() {
//        return "User{id = " + id + ", name = " + name + ", age = " + age + ", gender = " + gender + ", phone = " + phone + "}";
//    }
}

基础操作

环境准备

删除

根据id实现删除信息:

java 复制代码
//EmpMapper.java
package com.jianglin.mapper;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface EmpMapper {

    //根据id实现删除数据
    @Delete("delete from emp where id = #{id}")
    public void deleteByEmpId(Integer id);
}
//MybatisLevelApplicationTests.java
package com.jianglin;

import com.jianglin.mapper.EmpMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class MybatisLevelApplicationTests {

    @Autowired
    private EmpMapper empMapper;
    @Test
    public void deleteByEmpId() {
        empMapper.deleteByEmpId(17);
    }

}

删除、添加、修改实际上是有返回值的,返回值就是影响了几条记录,但我们一般不会去获取它。

删除(预编译SQL)

SQL注入的核心原理

通过在用户输入的参数中插入恶意SQL片段,改变原SQL语句的逻辑,使其执行非预期的操作。

案例解析(登录场景)

1.正常SQL逻辑

假设登录验证的原始SQL为:

sql 复制代码
SELECT COUNT(*) FROM user WHERE username = '输入的用户名' AND password = '输入的密码'

意图:只有用户名和密码都匹配时,查询结果计数(COUNT)才会大于0,允许登录。

  1. 注入后的恶意逻辑

当用户输入的密码包含恶意片段(如 ' OR 1=1 --),SQL会被拼接为:

sql 复制代码
SELECT COUNT(*) FROM user WHERE username = 'xxx' AND password = '' OR 1=1 --'

○ OR 1=1:1=1 永远为真,导致整个条件恒成立(只要前面的条件有一个满足即可)。

○ --:注释掉后续多余的单引号,使SQL语法合法。

  1. 结果

该SQL执行后会返回表中所有记录的计数(如15条),因计数大于0,系统误判为"登录成功",无需正确密码即可绕过验证。

新增员工

用SQL来实现插入数据:

sql 复制代码
insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)
values ('Tom','汤姆',1,'1.jpg',1,'2005-01-01',1,now(),now());

新增员工实现:

java 复制代码
//EmpMapper.java
package com.jianglin.mapper;

import com.jianglin.pojo.Emp;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface EmpMapper {

    //根据id实现删除数据
    @Delete("delete from emp where id = #{id}")
    public void deleteByEmpId(Integer id);

    @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)" +
            "values (#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime}); ")
    public void insert(Emp emp);
}
//MybatisLevelApplicationTests.java
package com.jianglin;

import com.jianglin.mapper.EmpMapper;
import com.jianglin.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.LocalDate;
import java.time.LocalDateTime;

@SpringBootTest
class MybatisLevelApplicationTests {

    @Autowired
    private EmpMapper empMapper;
    @Test
    public void deleteByEmpId() {
        empMapper.deleteByEmpId(17);
    }

    @Test
    public void testInsert() {
        //构造员工对象
        Emp emp = new Emp();
        emp.setUsername("Tom");
        emp.setName("汤姆");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000, 1, 1));
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);

        //执行新增员工信息操作
        empMapper.insert(emp);
    }
}

新增(主键返回)

如果我们在插入完成之后,需要获取返回的组件,需要在上面加上一个注解options,然后指定两个属性useGeneratedKeys代表的是我们要获取返回回来的主件,然后keyProperty代表的是返回回来的主键,往emp对象的哪个属性当中来封装,那指定需要往emp的id属性当中来封装。

更新

实现更新员工信息:

java 复制代码
//EmpMapper.java
package com.jianglin.mapper;

import com.jianglin.pojo.Emp;
import org.apache.ibatis.annotations.*;

@Mapper
public interface EmpMapper {

    //根据id实现删除数据
    @Delete("delete from emp where id = #{id}")
    public void deleteByEmpId(Integer id);

    //实现插入数据,并返回主键id
    @Options(keyProperty = "id", useGeneratedKeys = true)
    @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)" +
            "values (#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime}); ")
    public void insert(Emp emp);

    //更新数据
    @Update("update emp set username=#{username},name=#{name},gender=#{gender},image=#{image}," +
            "job=#{job},entrydate=#{entrydate},dept_id=#{deptId},update_time=#{updateTime} where id=#{id}")
    public void update(Emp emp);
}
//MybatisLevelApplicationTests.java
package com.jianglin;

import com.jianglin.mapper.EmpMapper;
import com.jianglin.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.LocalDate;
import java.time.LocalDateTime;

@SpringBootTest
class MybatisLevelApplicationTests {

    @Autowired
    private EmpMapper empMapper;
    @Test
    public void deleteByEmpId() {
        empMapper.deleteByEmpId(17);
    }

    @Test
    public void testInsert() {
        //构造员工对象
        Emp emp = new Emp();
        emp.setUsername("Jennie");
        emp.setName("珍妮");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000, 1, 1));
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);

        //执行新增员工信息操作
        empMapper.insert(emp);
        System.out.println(emp.getId());
    }

    //更新员工
    @Test
    public void testUpdate() {
        //构造员工对象
        Emp emp = new Emp();
        emp.setId(18);
        emp.setUsername("Tom1");
        emp.setName("汤姆1");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000, 1, 1));
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);

        //执行更新员工操作
        empMapper.update(emp);
    }
}

查询(根据ID查询)

可用这两个方案来解决不一致问题。

但上述两个方案过于繁琐,所以我们直接在配置文件中开启mybatis的驼峰命名自动映射开关即可。

根据ID查询:

java 复制代码
//EmpMapper.java
package com.jianglin.mapper;

import com.jianglin.pojo.Emp;
import org.apache.ibatis.annotations.*;

@Mapper
public interface EmpMapper {

    //根据id实现删除数据
    @Delete("delete from emp where id = #{id}")
    public void deleteByEmpId(Integer id);

    //实现插入数据,并返回主键id
    @Options(keyProperty = "id", useGeneratedKeys = true)
    @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)" +
            "values (#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime}); ")
    public void insert(Emp emp);

    //更新数据
    @Update("update emp set username=#{username},name=#{name},gender=#{gender},image=#{image}," +
            "job=#{job},entrydate=#{entrydate},dept_id=#{deptId},update_time=#{updateTime} where id=#{id}")
    public void update(Emp emp);

    /* 根据id查询 */
    @Select("select * from emp where id=#{id}")
    public Emp getEmpById(Integer id);

    //方案一:给字段起别名,让别名与实体类属性一致
    //@Select("select id, username, password, name, gender, image, job, entrydate, " +
    //        "dept_id deptId, create_time createTime, update_time updateTime from emp where id = #{id}")
    //public Emp getEmpById(Integer id);

    //方案二:通过@Results, @Result注解手动映射封装
//    @Results({
//            @Result(column = "dept_id", property = "deptId"),
//            @Result(column = "create_time", property = "createTime"),
//            @Result(column = "update_time", property = "updateTime")
//    })
//    @Select("select * from emp where id = #{id}")
//    public Emp getEmpById(Integer id);
}
//MybatisLevelApplicationTests.java
package com.jianglin;

import com.jianglin.mapper.EmpMapper;
import com.jianglin.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.LocalDate;
import java.time.LocalDateTime;

@SpringBootTest
class MybatisLevelApplicationTests {

    @Autowired
    private EmpMapper empMapper;
    @Test
    public void deleteByEmpId() {
        empMapper.deleteByEmpId(17);
    }

    @Test
    public void testInsert() {
        //构造员工对象
        Emp emp = new Emp();
        emp.setUsername("Jennie");
        emp.setName("珍妮");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000, 1, 1));
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);

        //执行新增员工信息操作
        empMapper.insert(emp);
        System.out.println(emp.getId());
    }

    //更新员工
    @Test
    public void testUpdate() {
        //构造员工对象
        Emp emp = new Emp();
        emp.setId(18);
        emp.setUsername("Tom1");
        emp.setName("汤姆1");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000, 1, 1));
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);

        //执行更新员工操作
        empMapper.update(emp);
    }

    //查询员工信息
    @Test
    public void testgetEmpById() {
        Emp emp = empMapper.getEmpById(18);
        System.out.println(emp);
    }
}

查询(条件查询)

条件查询:

java 复制代码
//mapper层
//条件查询员工
    @Select("select * from emp where name like '%${name}%' and gender=#{gender} and " +
            "entrydate between #{begain} and #{end} order by update_time desc")
    public List<Emp> list(String name, Short gender, LocalDate begain, LocalDate end);
//条件查询测试
//条件查询员工
    @Test
    public void testList() {
        List<Emp> empList = empMapper.list("张", (short) 1, LocalDate.of(2000, 1, 1), LocalDate.of(2025, 1, 1));
        System.out.println(empList);
    }

条件查询员工信息:

java 复制代码
//EmpMapper.java
package com.jianglin.mapper;

import com.jianglin.pojo.Emp;
import org.apache.ibatis.annotations.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

@Mapper
public interface EmpMapper {

    //根据id实现删除数据
    @Delete("delete from emp where id = #{id}")
    public void deleteByEmpId(Integer id);

    //实现插入数据,并返回主键id
    @Options(keyProperty = "id", useGeneratedKeys = true)
    @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)" +
            "values (#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime}); ")
    public void insert(Emp emp);

    //更新数据
    @Update("update emp set username=#{username},name=#{name},gender=#{gender},image=#{image}," +
            "job=#{job},entrydate=#{entrydate},dept_id=#{deptId},update_time=#{updateTime} where id=#{id}")
    public void update(Emp emp);

    /* 根据id查询 */
    @Select("select * from emp where id=#{id}")
    public Emp getEmpById(Integer id);

    //方案一:给字段起别名,让别名与实体类属性一致
    //@Select("select id, username, password, name, gender, image, job, entrydate, " +
    //        "dept_id deptId, create_time createTime, update_time updateTime from emp where id = #{id}")
    //public Emp getEmpById(Integer id);

    //方案二:通过@Results, @Result注解手动映射封装
//    @Results({
//            @Result(column = "dept_id", property = "deptId"),
//            @Result(column = "create_time", property = "createTime"),
//            @Result(column = "update_time", property = "updateTime")
//    })
//    @Select("select * from emp where id = #{id}")
//    public Emp getEmpById(Integer id);

//    //条件查询员工
//    @Select("select * from emp where name like '%${name}%' and gender=#{gender} and " +
//            "entrydate between #{begin} and #{end} order by update_time desc")
//    public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);

    //条件查询员工(推荐)
    @Select("select * from emp where name like concat('%',#{name},'%') and gender=#{gender} and " +
            "entrydate between #{begin} and #{end} order by update_time desc")
    public List<Emp> list(@Param("name") String name,
                          @Param("gender") Short gender,
                          @Param("begin") LocalDate begin,
                          @Param("end") LocalDate end);
}
//MybatisLevelApplicationTests.java
package com.jianglin;

import com.jianglin.mapper.EmpMapper;
import com.jianglin.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

@SpringBootTest
class MybatisLevelApplicationTests {

    @Autowired
    private EmpMapper empMapper;
    @Test
    public void deleteByEmpId() {
        empMapper.deleteByEmpId(17);
    }

    @Test
    public void testInsert() {
        //构造员工对象
        Emp emp = new Emp();
        emp.setUsername("Jennie");
        emp.setName("珍妮");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000, 1, 1));
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);

        //执行新增员工信息操作
        empMapper.insert(emp);
        System.out.println(emp.getId());
    }

    //更新员工
    @Test
    public void testUpdate() {
        //构造员工对象
        Emp emp = new Emp();
        emp.setId(18);
        emp.setUsername("Tom1");
        emp.setName("汤姆1");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000, 1, 1));
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);

        //执行更新员工操作
        empMapper.update(emp);
    }

    //查询员工信息
    @Test
    public void testgetEmpById() {
        Emp emp = empMapper.getEmpById(18);
        System.out.println(emp);
    }

    //条件查询员工
    @Test
    public void testList() {
        List<Emp> empList = empMapper.list("张", (short) 1, LocalDate.of(2000, 1, 1), LocalDate.of(2025, 1, 1));
        System.out.println(empList);
    }
}

XML映射文件

利用xml映射实现SQL:

XML 复制代码
//EmpMapper.xml
<?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.jianglin.mapper.EmpMapper">
<!--    resultType:单条记录所封装的类型-->
    <select id="list" resultType="com.jianglin.pojo.Emp">
        select * from emp where name like concat('%',#{name},'%') and gender=#{gender} and
        entrydate between #{begin} and #{end} order by update_time desc
    </select>
</mapper>
java 复制代码
//EmpMapper.java
package com.jianglin.mapper;

import com.jianglin.pojo.Emp;
import org.apache.ibatis.annotations.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

@Mapper
public interface EmpMapper {

    //根据id实现删除数据
    @Delete("delete from emp where id = #{id}")
    public void deleteByEmpId(Integer id);

    //实现插入数据,并返回主键id
    @Options(keyProperty = "id", useGeneratedKeys = true)
    @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)" +
            "values (#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime}); ")
    public void insert(Emp emp);

    //更新数据
    @Update("update emp set username=#{username},name=#{name},gender=#{gender},image=#{image}," +
            "job=#{job},entrydate=#{entrydate},dept_id=#{deptId},update_time=#{updateTime} where id=#{id}")
    public void update(Emp emp);

    /* 根据id查询 */
    @Select("select * from emp where id=#{id}")
    public Emp getEmpById(Integer id);

    //方案一:给字段起别名,让别名与实体类属性一致
    //@Select("select id, username, password, name, gender, image, job, entrydate, " +
    //        "dept_id deptId, create_time createTime, update_time updateTime from emp where id = #{id}")
    //public Emp getEmpById(Integer id);

    //方案二:通过@Results, @Result注解手动映射封装
//    @Results({
//            @Result(column = "dept_id", property = "deptId"),
//            @Result(column = "create_time", property = "createTime"),
//            @Result(column = "update_time", property = "updateTime")
//    })
//    @Select("select * from emp where id = #{id}")
//    public Emp getEmpById(Integer id);

//    //条件查询员工
//    @Select("select * from emp where name like '%${name}%' and gender=#{gender} and " +
//            "entrydate between #{begin} and #{end} order by update_time desc")
//    public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);

    //条件查询员工(推荐)
//    @Select("select * from emp where name like concat('%',#{name},'%') and gender=#{gender} and " +
//            "entrydate between #{begin} and #{end} order by update_time desc")
//    public List<Emp> list(@Param("name") String name,
//                          @Param("gender") Short gender,
//                          @Param("begin") LocalDate begin,
//                          @Param("end") LocalDate end);

    public List<Emp> list(@Param("name") String name,
                          @Param("gender") Short gender,
                          @Param("begin") LocalDate begin,
                          @Param("end") LocalDate end);
}
//MybatisLevelApplicationTests.java
package com.jianglin;

import com.jianglin.mapper.EmpMapper;
import com.jianglin.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

@SpringBootTest
class MybatisLevelApplicationTests {

    @Autowired
    private EmpMapper empMapper;
    @Test
    public void deleteByEmpId() {
        empMapper.deleteByEmpId(17);
    }

    @Test
    public void testInsert() {
        //构造员工对象
        Emp emp = new Emp();
        emp.setUsername("Jennie");
        emp.setName("珍妮");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000, 1, 1));
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);

        //执行新增员工信息操作
        empMapper.insert(emp);
        System.out.println(emp.getId());
    }

    //更新员工
    @Test
    public void testUpdate() {
        //构造员工对象
        Emp emp = new Emp();
        emp.setId(18);
        emp.setUsername("Tom1");
        emp.setName("汤姆1");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000, 1, 1));
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);

        //执行更新员工操作
        empMapper.update(emp);
    }

    //查询员工信息
    @Test
    public void testgetEmpById() {
        Emp emp = empMapper.getEmpById(18);
        System.out.println(emp);
    }

    //条件查询员工
    @Test
    public void testList() {
        List<Emp> empList = empMapper.list("张", (short) 1, LocalDate.of(2000, 1, 1), LocalDate.of(2025, 1, 1));
        System.out.println(empList);
    }
}

可以实现跳转至mapper中的方法。

如果说我们执行的是一些简单的增删改查操作,我们推荐使用注解,如果我们要执行一些比较复杂的sql语句,那我们推荐使用xml来配置sql语句。

Mybatis动态SQL

if

拿我们前面所实现的条件查询员工的这个需求来说,对于这类的系统来说,表格上面的这些查询条件我不指定,如果不指定,就代表没有限制条件,是不是就是查询全部的员工信息,那我可不可以只是指定其中的一个,或者是两个条件来进行查询,可以,那我能不能三个条件全部指定了来查询,当然也可以,但是大家再反过来看一下,我们之前所编写的sql语句,在我们之前编写的sql语句当中,我们将这三个条件直接固定死了,那也就是说即使我上面什么条件都没有指定,他也要根据这三个字段进行查询,而此时传递进来的这几个参数值,是不是都是null,是查不到数据的。

MyBatis <where> 标签

核心作用一:动态生成 WHERE 关键字

包裹查询条件子标签(如 <if>),判断内部条件是否成立。

若内部所有条件都不成立,则不生成 WHERE 关键字,避免 SQL 语法错误。

若内部至少一个条件成立,则自动生成 WHERE 关键字,拼接合法查询条件。

核心作用二:自动处理多余逻辑运算符

自动去除条件前面多余的 AND 或 OR,无需手动调整条件顺序来避免语法问题。

动态SQL实现:

XML 复制代码
//EmpMapper.xml
<?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.jianglin.mapper.EmpMapper">
<!--    resultType:单条记录所封装的类型-->
    <select id="list" resultType="com.jianglin.pojo.Emp">
        select *
        from emp
        <where>
            <if test="name != null">
                name like concat('%', #{name}, '%')
            </if>
            <if test="gender != null">
                and gender = #{gender}
            </if>
            <if test="begin!=null and end != null">
                and entrydate between #{begin} and #{end}
            </if>
        </where>
        order by update_time desc
    </select>
</mapper>
java 复制代码
//EmpMapper.java
package com.jianglin.mapper;

import com.jianglin.pojo.Emp;
import org.apache.ibatis.annotations.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

@Mapper
public interface EmpMapper {

    //根据id实现删除数据
    @Delete("delete from emp where id = #{id}")
    public void deleteByEmpId(Integer id);

    //实现插入数据,并返回主键id
    @Options(keyProperty = "id", useGeneratedKeys = true)
    @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)" +
            "values (#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime}); ")
    public void insert(Emp emp);

    //更新数据
    @Update("update emp set username=#{username},name=#{name},gender=#{gender},image=#{image}," +
            "job=#{job},entrydate=#{entrydate},dept_id=#{deptId},update_time=#{updateTime} where id=#{id}")
    public void update(Emp emp);

    /* 根据id查询 */
    @Select("select * from emp where id=#{id}")
    public Emp getEmpById(Integer id);

    //方案一:给字段起别名,让别名与实体类属性一致
    //@Select("select id, username, password, name, gender, image, job, entrydate, " +
    //        "dept_id deptId, create_time createTime, update_time updateTime from emp where id = #{id}")
    //public Emp getEmpById(Integer id);

    //方案二:通过@Results, @Result注解手动映射封装
//    @Results({
//            @Result(column = "dept_id", property = "deptId"),
//            @Result(column = "create_time", property = "createTime"),
//            @Result(column = "update_time", property = "updateTime")
//    })
//    @Select("select * from emp where id = #{id}")
//    public Emp getEmpById(Integer id);

//    //条件查询员工
//    @Select("select * from emp where name like '%${name}%' and gender=#{gender} and " +
//            "entrydate between #{begin} and #{end} order by update_time desc")
//    public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);

    //条件查询员工(推荐)
//    @Select("select * from emp where name like concat('%',#{name},'%') and gender=#{gender} and " +
//            "entrydate between #{begin} and #{end} order by update_time desc")
//    public List<Emp> list(@Param("name") String name,
//                          @Param("gender") Short gender,
//                          @Param("begin") LocalDate begin,
//                          @Param("end") LocalDate end);

    //动态条件查询
    public List<Emp> list(@Param("name") String name,
                          @Param("gender") Short gender,
                          @Param("begin") LocalDate begin,
                          @Param("end") LocalDate end);
}

if案例--Set标签实现更新

实现动态更新:

XML 复制代码
//EmpMapper.xml
<?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.jianglin.mapper.EmpMapper">
    <!-- 动态更新员工-->
    <update id="update2">
        update emp
        <set>
            <if test="username != null">username = #{username},</if>
            <if test="name != null">name = #{name},</if>
            <if test="gender != null">gender = #{gender},</if>
            <if test="image != null">image = #{image},</if>
            <if test="job != null">job = #{job},</if>
            <if test="entrydate != null">entrydate = #{entrydate},</if>
            <if test="deptId != null">dept_id = #{deptId},</if>
            <if test="updateTime != null">update_time = #{updateTime}</if>
        </set>
        where id = #{id}
    </update>
    <!--    resultType:单条记录所封装的类型-->
    <select id="list" resultType="com.jianglin.pojo.Emp">
        select *
        from emp
        <where>
            <if test="name != null">
                name like concat('%', #{name}, '%')
            </if>
            <if test="gender != null">
                and gender = #{gender}
            </if>
            <if test="begin!=null and end != null">
                and entrydate between #{begin} and #{end}
            </if>
        </where>
        order by update_time desc
    </select>
</mapper>
java 复制代码
//EmpMapper.java
package com.jianglin.mapper;

import com.jianglin.pojo.Emp;
import org.apache.ibatis.annotations.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

@Mapper
public interface EmpMapper {

    //根据id实现删除数据
    @Delete("delete from emp where id = #{id}")
    public void deleteByEmpId(Integer id);

    //实现插入数据,并返回主键id
    @Options(keyProperty = "id", useGeneratedKeys = true)
    @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)" +
            "values (#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime}); ")
    public void insert(Emp emp);

    //更新数据
    @Update("update emp set username=#{username},name=#{name},gender=#{gender},image=#{image}," +
            "job=#{job},entrydate=#{entrydate},dept_id=#{deptId},update_time=#{updateTime} where id=#{id}")
    public void update(Emp emp);

    /* 根据id查询 */
    @Select("select * from emp where id=#{id}")
    public Emp getEmpById(Integer id);

    //方案一:给字段起别名,让别名与实体类属性一致
    //@Select("select id, username, password, name, gender, image, job, entrydate, " +
    //        "dept_id deptId, create_time createTime, update_time updateTime from emp where id = #{id}")
    //public Emp getEmpById(Integer id);

    //方案二:通过@Results, @Result注解手动映射封装
//    @Results({
//            @Result(column = "dept_id", property = "deptId"),
//            @Result(column = "create_time", property = "createTime"),
//            @Result(column = "update_time", property = "updateTime")
//    })
//    @Select("select * from emp where id = #{id}")
//    public Emp getEmpById(Integer id);

//    //条件查询员工
//    @Select("select * from emp where name like '%${name}%' and gender=#{gender} and " +
//            "entrydate between #{begin} and #{end} order by update_time desc")
//    public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);

    //条件查询员工(推荐)
//    @Select("select * from emp where name like concat('%',#{name},'%') and gender=#{gender} and " +
//            "entrydate between #{begin} and #{end} order by update_time desc")
//    public List<Emp> list(@Param("name") String name,
//                          @Param("gender") Short gender,
//                          @Param("begin") LocalDate begin,
//                          @Param("end") LocalDate end);

    //动态条件查询
    public List<Emp> list(@Param("name") String name,
                          @Param("gender") Short gender,
                          @Param("begin") LocalDate begin,
                          @Param("end") LocalDate end);

    //实现动态SQL更新
    public void update2(Emp emp);
}
//MybatisLevelApplicationTests.java
package com.jianglin;

import com.jianglin.mapper.EmpMapper;
import com.jianglin.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

@SpringBootTest
class MybatisLevelApplicationTests {

    @Autowired
    private EmpMapper empMapper;
    @Test
    public void deleteByEmpId() {
        empMapper.deleteByEmpId(17);
    }

    @Test
    public void testInsert() {
        //构造员工对象
        Emp emp = new Emp();
        emp.setUsername("Jennie");
        emp.setName("珍妮");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000, 1, 1));
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);

        //执行新增员工信息操作
        empMapper.insert(emp);
        System.out.println(emp.getId());
    }

    //更新员工
    @Test
    public void testUpdate() {
        //构造员工对象
        Emp emp = new Emp();
        emp.setId(18);
        emp.setUsername("Tom1");
        emp.setName("汤姆1");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000, 1, 1));
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);

        //执行更新员工操作
        empMapper.update(emp);
    }

    //查询员工信息
    @Test
    public void testgetEmpById() {
        Emp emp = empMapper.getEmpById(18);
        System.out.println(emp);
    }

    //条件查询员工
    @Test
    public void testList() {
//        List<Emp> empList = empMapper.list("张", (short) 1, LocalDate.of(2000, 1, 1), LocalDate.of(2025, 1, 1));
        List<Emp> empList = empMapper.list(null, (short) 2,null,null);
        System.out.println(empList);
    }

    //动态更新员工 - 更新ID为18的员工 username 更新为 Tom111, name更新为 汤姆111, gender更新为2
    @Test
    public void testUpdate2() {
        //构造员工对象
        Emp emp = new Emp();
        emp.setId(18);
        emp.setUsername("Tom111");
        emp.setName("汤姆111");
        emp.setGender((short)2);
        emp.setUpdateTime(LocalDateTime.now());

        //执行更新员工操作
        empMapper.update2(emp);
    }
}

foreach标签

这个问题是因为 MyBatis 对集合类型参数的默认命名规则导致的。

原因分析:

  1. 默认参数命名规则

当 MyBatis 接收到以下类型的参数时,会使用默认的名称:

List 类型 → 默认名称:list

数组类型 → 默认名称:array

Collection 类型 → 默认名称:collection

  1. 代码情况

在Mapper 接口中,方法是:

java 复制代码
//实现动态SQL批量删除根据id
public void deleteByIds(List<Integer> ids);

虽然传递的参数名叫 ids,但 MyBatis 在解析时:

识别到参数类型是 List

自动使用默认名称 list,而不是参数名 ids。

解决方案:

方案1:使用默认名称

复制代码
<foreach collection="list" item="id" separator="," open="(" close=")">
  #{id}
</foreach>

方案2:使用 @Param 注解指定名称(推荐)

在 Mapper 接口方法上添加注解:

java 复制代码
int deleteByIds(@Param("ids") List<Integer> ids);

然后在 XML 中使用想要的名称:

XML 复制代码
<foreach collection="ids" item="id" separator="," open="(" close=")">
  #{id}
</foreach>

方案3:在配置文件中开启实际参数名支持

在 application.properties 中添加:

bash 复制代码
mybatis.configuration.use-actual-param-name=true
java 复制代码
//EmpMapper.java
<?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.jianglin.mapper.EmpMapper">
    <!-- 动态更新员工-->
    <update id="update2">
        update emp
        <set>
            <if test="username != null">username = #{username},</if>
            <if test="name != null">name = #{name},</if>
            <if test="gender != null">gender = #{gender},</if>
            <if test="image != null">image = #{image},</if>
            <if test="job != null">job = #{job},</if>
            <if test="entrydate != null">entrydate = #{entrydate},</if>
            <if test="deptId != null">dept_id = #{deptId},</if>
            <if test="updateTime != null">update_time = #{updateTime}</if>
        </set>
        where id = #{id}
    </update>

    <!--    resultType:单条记录所封装的类型-->
    <select id="list" resultType="com.jianglin.pojo.Emp">
        select *
        from emp
        <where>
            <if test="name != null">
                name like concat('%', #{name}, '%')
            </if>
            <if test="gender != null">
                and gender = #{gender}
            </if>
            <if test="begin!=null and end != null">
                and entrydate between #{begin} and #{end}
            </if>
        </where>
        order by update_time desc
    </select>

    <!--批量删除员工 (18,19,20)-->
    <!--
        collection: 遍历的集合
        item: 遍历出来的元素
        separator: 分隔符
        open: 遍历开始前拼接的SQL片段
        close: 遍历结束后拼接的SQL片段
    -->
    <delete id="deleteByIds">
#         delete from emp where id in (18,19,20) 原SQL语句
        delete from emp where id in
        <foreach collection="list" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>
</mapper>
//EmpMapper.java
package com.jianglin.mapper;

import com.jianglin.pojo.Emp;
import org.apache.ibatis.annotations.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

@Mapper
public interface EmpMapper {

    //根据id实现删除数据
    @Delete("delete from emp where id = #{id}")
    public void deleteByEmpId(Integer id);

    //实现插入数据,并返回主键id
    @Options(keyProperty = "id", useGeneratedKeys = true)
    @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)" +
            "values (#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime}); ")
    public void insert(Emp emp);

    //更新数据
    @Update("update emp set username=#{username},name=#{name},gender=#{gender},image=#{image}," +
            "job=#{job},entrydate=#{entrydate},dept_id=#{deptId},update_time=#{updateTime} where id=#{id}")
    public void update(Emp emp);

    /* 根据id查询 */
    @Select("select * from emp where id=#{id}")
    public Emp getEmpById(Integer id);

    //方案一:给字段起别名,让别名与实体类属性一致
    //@Select("select id, username, password, name, gender, image, job, entrydate, " +
    //        "dept_id deptId, create_time createTime, update_time updateTime from emp where id = #{id}")
    //public Emp getEmpById(Integer id);

    //方案二:通过@Results, @Result注解手动映射封装
//    @Results({
//            @Result(column = "dept_id", property = "deptId"),
//            @Result(column = "create_time", property = "createTime"),
//            @Result(column = "update_time", property = "updateTime")
//    })
//    @Select("select * from emp where id = #{id}")
//    public Emp getEmpById(Integer id);

//    //条件查询员工
//    @Select("select * from emp where name like '%${name}%' and gender=#{gender} and " +
//            "entrydate between #{begin} and #{end} order by update_time desc")
//    public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);

    //条件查询员工(推荐)
//    @Select("select * from emp where name like concat('%',#{name},'%') and gender=#{gender} and " +
//            "entrydate between #{begin} and #{end} order by update_time desc")
//    public List<Emp> list(@Param("name") String name,
//                          @Param("gender") Short gender,
//                          @Param("begin") LocalDate begin,
//                          @Param("end") LocalDate end);

    //动态条件查询
    public List<Emp> list(@Param("name") String name,
                          @Param("gender") Short gender,
                          @Param("begin") LocalDate begin,
                          @Param("end") LocalDate end);

    //实现动态SQL更新
    public void update2(Emp emp);

    //实现动态SQL批量删除根据id
    public void deleteByIds(List<Integer> ids);
}
//MybatisLevelApplicationTests.java
package com.jianglin;

import com.jianglin.mapper.EmpMapper;
import com.jianglin.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

@SpringBootTest
class MybatisLevelApplicationTests {

    @Autowired
    private EmpMapper empMapper;
    @Test
    public void deleteByEmpId() {
        empMapper.deleteByEmpId(17);
    }

    @Test
    public void testInsert() {
        //构造员工对象
        Emp emp = new Emp();
        emp.setUsername("Jennie");
        emp.setName("珍妮");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000, 1, 1));
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);

        //执行新增员工信息操作
        empMapper.insert(emp);
        System.out.println(emp.getId());
    }

    //更新员工
    @Test
    public void testUpdate() {
        //构造员工对象
        Emp emp = new Emp();
        emp.setId(18);
        emp.setUsername("Tom1");
        emp.setName("汤姆1");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000, 1, 1));
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);

        //执行更新员工操作
        empMapper.update(emp);
    }

    //查询员工信息
    @Test
    public void testgetEmpById() {
        Emp emp = empMapper.getEmpById(18);
        System.out.println(emp);
    }

    //条件查询员工
    @Test
    public void testList() {
//        List<Emp> empList = empMapper.list("张", (short) 1, LocalDate.of(2000, 1, 1), LocalDate.of(2025, 1, 1));
        List<Emp> empList = empMapper.list(null, (short) 2,null,null);
        System.out.println(empList);
    }

    //动态更新员工 - 更新ID为18的员工 username 更新为 Tom111, name更新为 汤姆111, gender更新为2
    @Test
    public void testUpdate2() {
        //构造员工对象
        Emp emp = new Emp();
        emp.setId(18);
        emp.setUsername("Tom111");
        emp.setName("汤姆111");
        emp.setGender((short)2);
        emp.setUpdateTime(LocalDateTime.now());

        //执行更新员工操作
        empMapper.update2(emp);

    }

    //测试动态SQL实现批量删除操作
    @Test
    public void deleteByIds() {
        List<Integer> ids = Arrays.asList(18,19);
        empMapper.deleteByIds(ids);
    }
}

sql&include--解决SQL语句重复,增强复用性

定义可重用实现:

XML 复制代码
//EmpMapper.xml
<?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.jianglin.mapper.EmpMapper">
    <sql id="CommentSelect">
        select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp
    </sql>


    <!--    resultType:单条记录所封装的类型-->
    <select id="list" resultType="com.jianglin.pojo.Emp">
        <include refid="CommentSelect"/>
        <where>
            <if test="name != null">
                name like concat('%', #{name}, '%')
            </if>
            <if test="gender != null">
                and gender = #{gender}
            </if>
            <if test="begin!=null and end != null">
                and entrydate between #{begin} and #{end}
            </if>
        </where>
        order by update_time desc
    </select>

    <!-- 动态更新员工-->
    <update id="update2">
        update emp
        <set>
            <if test="username != null">username = #{username},</if>
            <if test="name != null">name = #{name},</if>
            <if test="gender != null">gender = #{gender},</if>
            <if test="image != null">image = #{image},</if>
            <if test="job != null">job = #{job},</if>
            <if test="entrydate != null">entrydate = #{entrydate},</if>
            <if test="deptId != null">dept_id = #{deptId},</if>
            <if test="updateTime != null">update_time = #{updateTime}</if>
        </set>
        where id = #{id}
    </update>

    <!--批量删除员工 (18,19,20)-->
    <!--
        collection: 遍历的集合
        item: 遍历出来的元素
        separator: 分隔符
        open: 遍历开始前拼接的SQL片段
        close: 遍历结束后拼接的SQL片段
    -->
    <delete id="deleteByIds">
#         delete from emp where id in (18,19,20) 原SQL语句
        delete from emp where id in
        <foreach collection="list" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>
</mapper>
java 复制代码
//MybatisLevelApplicationTests.java
package com.jianglin;

import com.jianglin.mapper.EmpMapper;
import com.jianglin.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

@SpringBootTest
class MybatisLevelApplicationTests {

    @Autowired
    private EmpMapper empMapper;
    @Test
    public void deleteByEmpId() {
        empMapper.deleteByEmpId(17);
    }

    @Test
    public void testInsert() {
        //构造员工对象
        Emp emp = new Emp();
        emp.setUsername("Jennie");
        emp.setName("珍妮");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000, 1, 1));
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);

        //执行新增员工信息操作
        empMapper.insert(emp);
        System.out.println(emp.getId());
    }

    //更新员工
    @Test
    public void testUpdate() {
        //构造员工对象
        Emp emp = new Emp();
        emp.setId(18);
        emp.setUsername("Tom1");
        emp.setName("汤姆1");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000, 1, 1));
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);

        //执行更新员工操作
        empMapper.update(emp);
    }

    //查询员工信息
    @Test
    public void testgetEmpById() {
        Emp emp = empMapper.getEmpById(18);
        System.out.println(emp);
    }

    //条件查询员工
    @Test
    public void testList() {
//        List<Emp> empList = empMapper.list("张", (short) 1, LocalDate.of(2000, 1, 1), LocalDate.of(2025, 1, 1));
        List<Emp> empList = empMapper.list(null, (short) 2,null,null);
        System.out.println(empList);
    }

    //动态更新员工 - 更新ID为18的员工 username 更新为 Tom111, name更新为 汤姆111, gender更新为2
    @Test
    public void testUpdate2() {
        //构造员工对象
        Emp emp = new Emp();
        emp.setId(18);
        emp.setUsername("Tom111");
        emp.setName("汤姆111");
        emp.setGender((short)2);
        emp.setUpdateTime(LocalDateTime.now());

        //执行更新员工操作
        empMapper.update2(emp);

    }

    //测试动态SQL实现批量删除操作
    @Test
    public void deleteByIds() {
        List<Integer> ids = Arrays.asList(18,19);
        empMapper.deleteByIds(ids);
    }
}

这篇文章就先更到这里,接下来的内容可查看我的下一篇博客,感谢观看,希望对你有帮助。

相关推荐
bing.shao1 小时前
golang 做AI任务链的优势和场景
开发语言·人工智能·golang
我是一只小青蛙8881 小时前
位图与布隆过滤器:高效数据结构解析
开发语言·c++·算法
好好研究2 小时前
SpringBoot注解的作用
java·spring boot·spring
Object~2 小时前
4.const和iota
开发语言·前端·javascript
Libby博仙2 小时前
Spring Boot 条件化注解深度解析
java·spring boot·后端
willingli2 小时前
c语言经典100题 61-70题
c语言·开发语言·算法
我是小疯子662 小时前
深入解析C++右值引用与移动语义
java·开发语言·算法
Ethan Wilson2 小时前
VS2019 C++20 模块相关 C1001: 内部编译器错误
开发语言·c++·c++20