Springboot——SB整合Mybatis的CURD(基于注解进行开发)

此处是根据需求实现基本操作

 

 上面这里涉及到了条件分页查询,还有增加和批量删除员工信息,右边编辑就是先查询后更新操作,叫做查询回显,然后在原有基础上进行更新

环境准备 

 在下面的入门案例的整体环境下把数据库表换成empSpringBoot——基于SpringBoot整合Mybatis的入门案例+sql提示配置+lombok工具包介绍_北岭山脚鼠鼠的博客-CSDN博客

使用如下的建表语句


-- 部门管理
create table dept(
                     id int unsigned primary key auto_increment comment '主键ID',
                     name varchar(10) not null unique comment '部门名称',
                     create_time datetime not null comment '创建时间',
                     update_time datetime not null comment '修改时间'
) comment '部门表';

insert into dept (id, name, create_time, update_time) values(1,'学工部',now(),now()),(2,'教研部',now(),now()),(3,'咨询部',now(),now()), (4,'就业部',now(),now()),(5,'人事部',now(),now());


-- 员工管理
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,'jinyong','123456','金庸',1,'1.jpg',4,'2000-01-01',2,now(),now()),
                                                                                                    (2,'zhangwuji','123456','张无忌',1,'2.jpg',2,'2015-01-01',2,now(),now()),
                                                                                                    (3,'yangxiao','123456','杨逍',1,'3.jpg',2,'2008-05-01',2,now(),now()),
                                                                                                    (4,'weiyixiao','123456','韦一笑',1,'4.jpg',2,'2007-01-01',2,now(),now()),
                                                                                                    (5,'changyuchun','123456','常遇春',1,'5.jpg',2,'2012-12-05',2,now(),now()),
                                                                                                    (6,'xiaozhao','123456','小昭',2,'6.jpg',3,'2013-09-05',1,now(),now()),
                                                                                                    (7,'jixiaofu','123456','纪晓芙',2,'7.jpg',1,'2005-08-01',1,now(),now()),
                                                                                                    (8,'zhouzhiruo','123456','周芷若',2,'8.jpg',1,'2014-11-09',1,now(),now()),
                                                                                                    (9,'dingminjun','123456','丁敏君',2,'9.jpg',1,'2011-03-11',1,now(),now()),
                                                                                                    (10,'zhaomin','123456','赵敏',2,'10.jpg',1,'2013-09-05',1,now(),now()),
                                                                                                    (11,'luzhangke','123456','鹿杖客',1,'11.jpg',5,'2007-02-01',3,now(),now()),
                                                                                                    (12,'hebiweng','123456','鹤笔翁',1,'12.jpg',5,'2008-08-18',3,now(),now()),
                                                                                                    (13,'fangdongbai','123456','方东白',1,'13.jpg',5,'2012-11-01',3,now(),now()),
                                                                                                    (14,'zhangsanfeng','123456','张三丰',1,'14.jpg',2,'2002-08-01',2,now(),now()),
                                                                                                    (15,'yulianzhou','123456','俞莲舟',1,'15.jpg',2,'2011-05-01',2,now(),now()),
                                                                                                    (16,'songyuanqiao','123456','宋远桥',1,'16.jpg',2,'2010-01-01',2,now(),now()),
                                                                                                    (17,'chenyouliang','123456','陈友谅',1,'17.jpg',NULL,'2015-03-21',NULL,now(),now());

 准备一个对应的实体类,实体类当中有三个属性要使用驼峰命名法,因为在数据库当中有三个属性名中有下划线

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Emp {
    private Integer id; //ID
    private String username; //用户名
    private String password; //密码
    private String name; //姓名
    private Short gender; //性别, 1 男, 2 女
    private String image; //图像url
    private Short job; //职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师'
    private LocalDate entrydate; //入职日期
    private Integer deptId; //部门ID
    private LocalDateTime createTime; //创建时间
    private LocalDateTime updateTime; //修改时间
}

准备一个EmpMapper接口

@Mapper
public interface EmpMapper {


}

运行单元测试如果出现如下错误

Lombok requires enabled annotation processing

lombok 需要启用注释处理

首先可以在下面这里勾选启用注解处理然后重启IDEA

 其次不行就去插件哪里更新lombok

增删改查的通用流程

在EmpMapper中新建一个方法定义sql语句——>在test目录下进行测试

删除

 这个就是根据每个员工的id删除。

注意事项:如果这里的方法形参中只有一个属性,可以直接用属性名写在参数占位符#{}里面,当有多个参数时需要用到一个@Param()注解

错误的信息,只有在springboot1.X版本或者单独使用mybatis时才需要使用@Param注解。

因为在对mapper接口编译时不会保留方法的形参名称

 

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



 @Delete("delete from emp where id = #{id} and name= #{name}")
    public int delete(@Param("id") Integer id,@Param("name") String name);

delete的单元测试

此处可以设置返回值为int,删除成功就返回1,删除失败就返回0,返回的是受影响的行数

 @Test
    public void testDelete(){
        System.out.println(empMapper.delete(17));
    }

要想看见上面操作的过程,可以配置日志输出

 

mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

在预编译SQL中的?就是EmpMapper中的#{},下面的17就是要传进去的参数。

最后整条一起发给数据库去执行。

然后测试就可以看见控制台输出如下 

优势:

 原本的sql语句执行会先检查缓存是否存在同样的语句,有就直接执行,没有就编译后缓存,比如上面的三条就要编译三次,而预编译如图很明显了,只需要编译一次。

安全性

 

密码如上进行输入时执行了下面这条sql语句

此时整条sql语句已经发生了变化,添加了一个新的或条件'1'='1',这样无论怎么样都可以返回结果为1,太好玩了。

 SQL注入能够成功的原因就是参数被直接拼接在了sql语句当中,用了预编译sql就可以用?防止sql注入

参数占位符

 

增加 

增加一个新的员工时主键的值是不需要设定的,而且这里传进来的参数可以是一个对象,参数占位符里面直接写属性名就可以了

//新增员工
    @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);

 单元测试类当中

  @Test
    public void testInsert(){
        //构造员工对象
        Emp emp = new Emp();
        emp.setUsername("北岭山脚鼠鼠");
        emp.setName("yhy");
        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());
    }

 控制台输出如下(已经添加了@Options注解)

新增(主键返回) 

加上一个@Options注解,里面有两个属性可以把获取到的主键再封装会对象当中 

更新 

这种情况通常都要先根据id查询用于页面回写,然后再将更新的数据写进去

更新数据

 @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查询)

Mapper内

@Select("select * from emp where id = #{id}")
    public Emp getById(Integer id);

单元测试

   //根据ID查询员工
    @Test
    public void testGetById(){
        Emp emp = empMapper.getById(18);
        System.out.println(emp);
    }

在下面的输出中可以看见有三个名称里有下划线的没有查询到,但是在数据库里面是有值的。 

mybatis的数据封装 

解决方案一 (起别名)

//    方案一: 给字段起别名, 让别名与实体类属性一致  
  @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 getById(Integer id);

解决方案二(通过@Results,@Result注解手动映射封装)

//方案二: 通过@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 getById(Integer id);

解决方案三(开启mybatis的驼峰命名自动映射开关)

在配置文件中加上这一句

mybatis.configuration.map-underscore-to-camel-case=true

然后就可以用回最开始的方法了

 查询(条件查询)

有如下需要

 

Mapper中

这里使用对象传参的话没有开始时间和结束时间这两个属性,其中name要用到模糊查询,不能让#{}生成的?出现在'%?%'之内,所以这里就用了字符串拼接的${}

解决方案一(使用${})

  //  条件查询员工
 //   方式一
    @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);

 单元测试

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

解决方案二(concat函数){推荐使用}

为了解决上面的sql注入问题可以使用一个字符串拼接函数concat()

    //方式二
    @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);

 

到此结束

下面是基于XML映射文件开发CURD的链接

未完待续

猜你喜欢

转载自blog.csdn.net/m0_62327332/article/details/129753902
今日推荐