基于注解实现Mybatis的基础CRUD

作为后端开发人员,通常使用Java程序来完成对数据库的操作。目前使用Java程序操作数据库的主流方式是Mybatis。

1. 认识Mybatis

Mybatis是一款优秀的持久层框架,用于简化JDBC的开发。

持久层:数据访问层(dao),用来操作数据库

框架:是一个半成品软件,属于一套可重用的、通用的软件基础代码模型。基于框架进行软件开发更加高效、规范、通用及可扩展。

官网:MyBatis 中文网 官网 (p2hp.com)

2. 使用Myabtis实现基础的增删改查

2.1 准备工作

2.1.1 创建SpringBoot工程

打开IDEA,创建Springboot工程,输入基本的创建信息,点击下一步

导入Mybatis的起步依赖、mysql的驱动包,点击创建

2.1.2 数据准备

启动并连接mysql数据库,这里采用IDEA中内置的图形化数据库操作页面,新建一个名为mybatis数据库。

在数据库中创建一张emp表,并向表中插入一些测试数据。

create table emp
(
    id          int unsigned primary key auto_increment comment 'ID',
    username    varchar(20)      not null unique comment '用户名',
    password    varchar(32) default '123456' comment '密码',
    name        varchar(10)      not null comment '姓名',
    gender      tinyint unsigned not null comment '性别, 说明: 1 男, 2 女',
    image       varchar(300) comment '图像',
    job         tinyint unsigned comment '职位, 说明: 1 初级教师,2 中级教师, 3 高级教师, 4 特级教师, 5 特聘教师',
    entrydate   date comment '入职时间',
    dept_id     int unsigned comment '部门ID',
    create_time datetime         not null comment '创建时间',
    update_time datetime         not null comment '修改时间'
) comment '员工表';

INSERT INTO emp
(id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time)
VALUES (1, 'Tom', '123456', '汤姆', 1, 'Tom.jpg', 4, '2001-01-01', 2, now(), now()),
       (2, 'Jack', '123456', '杰克', 1, 'Jack.jpg', 2, '2013-01-01', 2, now(), now()),
       (3, 'Marry', '123456', '玛丽', 1, 'Marry.jpg', 2, '2011-05-01', 2, now(), now()),
       (4, 'Lucy', '123456', '路西', 1, 'Lucy.jpg', 2, '2007-01-01', 2, now(), now()),
       (5, 'Tomas', '123456', '托马斯', 1, 'Tomas.jpg', 2, '2012-12-05', 2, now(), now());

2.1.3 Mybatis连接数据库配置

打开我们创建的SpringBoot工程

在工程中找到 src - main - resources - application.properties文件,这是SpringBoot工程的配置文件,在配置文件中加入数据库连接配置信息。

#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis
#连接数据库的用户名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=1234

2.1.4 创建Emp类

打开创建的SpringBoot工程,在引导类所在的包下,创建一个pojo包,并在该包下创建实体类Emp,实体类的字段要与在数据库中创建的emp表字段名一致。

给实体类提供对应的构造器、get、set方法、重写toString()方法,这里采用Lombok注解的方式实现(需要添加Lombok依赖)。

@Data //该注解在程序编译时可自动生成getter()、setter()、toString()、equals()、hashCode()方法
@NoArgsConstructor //为实体类生成无参的构造方法
@AllArgsConstructor //为实体类生成除static修饰字段之外的全参构造方法
public class Emp {
    private Integer id;
    private String username;
    private String password;
    private String name;
    private Short gender;
    private String image;
    private Short job;
    private LocalDate entrydate;
    private Integer deptId;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
}

2.1.5 创建Mapper接口:EmpMapper

在引导类所在的包下,创建另一个包mapper,并在该包下创建一个接口EmpMapper接口,操作数据库要调用的方法会封装在这个接口中。

对EmpMapper接口添加@Mapper注解,表示当前接口是Mybatis中的Mapper接口,在程序运行时自动创建该接口的代理对象(实现类对象),并交给Spring的IOC容器管理。

@Mapper
public interface EmpMapper{

}

2.2 增删改查

2.2.1 删除

在实际功能的操作过程中,我们想要删除一条数据,需要指定相应的条件。比如在emp表中,我们可以根据id字段选择想要删除的数据,因为id字段是主键,能唯一标识一条数据。

首先在EmpMapper接口中定义一个delete()方法,我们将删除时要传给数据库的主键参数放在该方法的形参当中;在该方法上使用@Delete注解,代表该方法要执行的是一个删除操作。

在SQL语句中使用#{id}的方式可以在程序执行时动态的获取方法中传递的形参值,但要确保#{}中的参数名称与方法的传递的形参名一致。

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

我们在SpringBoot工程中提供的测试类中编写一个测试方法,对根据id删除数据的方法进行测试。

首先在测试类中定义一个EmpMapper类型的接口对象,并使用@Autowired注解;

@Autowired注解在程序执行时会从Spring的IOC容器中动态的获取指定类型的对象并注入,在这里获取的就是EmpMapper类型的对象。

@SpringBootTest
class SpringbootMybatisApplicationTests {
    @Autowired //动态的从Spring的IOC容器中,获取类型为EmpMapper的对象并注入
    private EmpMapper empMapper;

    @Test
    public void testDelete(){
        //调用删除方法,删除id为5的数据
        empMapper.delete(5);
    }

}

调用该测试方法,查看数据库中emp表数据,id为5的数据已经成功从表中删除。

2.2.2 新增

在EmpMppaer中添加一个insert()方法,用来执行新增操作;

使用@Insert注解,代表该方法要执行的是一个新增操作;

由于新增一条数据,需要填写多个字段值,在此我们选择将要填写的多个字段信息封装在Emp类型的对象中,然后给insert()方法传递一个Emp类型的形参;

在SQL语句中,我们依然使用 #{} 的方式传递参数,但是要注意,#{}中参数的名称要与Emp类中定义的属性名一致;

在数据库中,id字段为主键且自增,所以在新增数据时,我们不传递id字段的值

@Mapper
public interface EmpMapper {
    //新增数据
    //#{}中传递的参数名称要与Emp类中属性名一致
    @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);
}

我们在SpringBoot工程中提供的测试类中编写一个测试方法,对insert(Emp emp)方法进行测试。

@SpringBootTest
class SpringbootMybatisApplicationTests {
    @Autowired //动态的从Spring的IOC容器中,获取类型为EmpMapper的对象并注入
    private EmpMapper empMapper;

    @Test
    public void testInsert(){
        //创建一个Emp类型的对象,并给对象的各个属性赋值
        Emp emp = new Emp();
        emp.setUsername("Tomas");
        emp.setName("托马斯");
        emp.setGender((short)1);
        emp.setImage("Tomas.jpg");
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(1998,6,2));
        emp.setDeptId(2);
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());

        //调用新增方法
        empMapper.insert(emp);
    }

}

调用该测试方法,查看数据库emp表中数据,新增的数据已经成功添加到数据库中。

2.2.3 新增(主键回显)

在刚才的新增操作中,我们没有传递id字段的值,因为id字段在数据库中是主键,且设置了自增,所以在新增数据时,数据库会自动设置id字段的值;

但是在实际应用场景中,我们可能会涉及到某个需求场景,需要获取插入数据的主键值,那么我们就需要进行主键回显;

我们在Mapper接口中定义的insert()新增方法上添加@Options注解,并设置注解中属性useGeneratedKeys和keyProperty的值;

useGeneratedKeys=true 表示要将插入数据库中数据的主键值返回;

keyProperty="实体类属性名" 表示要将返回的主键值赋值给对象的具体属性;

@Mapper
public interface EmpMapper {
    //新增数据
    @Options(useGeneratedKeys = true, keyProperty = "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);
}

2.2.4 更新

在具体的业务场景中,我们会经常遇到对某条数据进行修改的场景,此时就要对数据库中的数据进行更新。

在EmpMapper接口中添加一个update()方法,用来执行更新操作;

使用@Update注解代表这是一个更新类型的方法;

在更新数据时同样会涉及到多个字段值的传递,在此也将要传递的字段值封装在Emp类型的对象中,然后给update()方法传递一个Emp类型的形参;

在SQL语句中,我们依然使用 #{} 的方式传递参数,但是要注意,#{}中参数的名称要与Emp类中定义的属性名一致;

@Mapper
public interface EmpMapper {
    //更新数据
    @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);
}

 在SpringBoot工程中提供的测试类中编写一个测试方法,对update(Emp emp)方法进行测试。

@SpringBootTest
class SpringbootMybatisApplicationTests {
    @Autowired //动态的从Spring的IOC容器中,获取类型为EmpMapper的对象并注入
    private EmpMapper empMapper;

    @Test
    public void testUpdate(){
        //创建一个Emp类型的对象,并给对象的各个属性赋值
        Emp emp = new Emp();
        emp.setUsername("Tomas123");
        emp.setName("托马斯123");
        emp.setGender((short)1);
        emp.setImage("Tomas123.jpg");
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(1998,6,2));
        emp.setDeptId(2);
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());

        //调用新增方法
        empMapper.update(emp);
    }

}

调用该测试方法,查看数据库emp表中数据,指定更新的数据已经成功成功更新。

2.2.5 查询(根据id查询)

在实际使用场景中,涉及最多的就是查询操作,页面展示的数据都需要从数据库中查询并进行展示。

在EmpMapper接口中定义一个getById()方法,根据id从数据库中查询数据;

使用@Select注解代表这是一个查询操作;

在getById()方法中,我们传递一个id参数,用来指明要查询具体条数据

在SQL语句中,使用 #{} 的方式传递参数,但是要注意,#{}中参数的名称要与getById()方法中形参名称一致。

@Mapper
public interface EmpMapper {
    //根据id查询数据
    @Select("select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time " +
            "from emp where id = #{id}")
    public Emp getById(Integer id);
}

在SpringBoot工程中提供的测试类中编写一个测试方法,对getById(Integer id)方法进行测试。

@SpringBootTest
class SpringbootMybatisApplicationTests {
    @Autowired //动态的从Spring的IOC容器中,获取类型为EmpMapper的对象并注入
    private EmpMapper empMapper;

    @Test
    public void testGetById(){
        Emp emp = empMapper.getById(1);
        System.out.println(emp);
    }
}

调用该测试方法,查看控制台输出,成功从数据库中查询到对应的数据。

2.2.6 查询(根据条件查询)

在实际应用场景中,经常会根据某几个条件查询数据,然后将查到的数据展示在列表中;

在这里完成一个根据name、gender、entrydate(时间范围)进行查询的例子。

在EmpMapper接口中定义一个方法list(),用来根据name、gender、entrydate(时间范围)查询数据。

使用@Select注解代表这是一个查询操作;

在list()方法中,传递name,gender、begin和end(表示时间范围)参数;

在SQL语句中,使用 #{} 的方式传递参数,但是要注意,#{}中参数的名称要与list()方法中形参名称一致。

针对参数name,由于需要实现根据name进行模糊匹配,在SQL语句中使用concat()函数;

@Mapper
public interface EmpMapper {
    //根据条件查询数据
    @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(String name, Short gender, LocalDate begin, LocalDate end);
}

在SpringBoot工程中提供的测试类中编写一个测试方法,对list()方法进行测试。

@SpringBootTest
class SpringbootMybatisApplicationTests {
    @Autowired //动态的从Spring的IOC容器中,获取类型为EmpMapper的对象并注入
    private EmpMapper empMapper;

    @Test
    public void testList(){
        List<Emp> empList = empMapper.list("汤", (short)1, LocalDate.of(1998,1,1), LocalDate.of(2020,1,1));
        System.out.println(empList);
    }

}

调用该方法,查看控制台输出,成功从数据库中查询到符合条件的数据。

仅作学习使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值