后端之路(集合项目)——结合案例正式搭建项目

在前面学完java后端的Maven、spring boot、Mysql、Mybatis之后,我们现在就应该集合它们开始搭建一个项目试试手了

这里我还是跟着黑马程序员的步骤来走好每一步,也给各位讲清楚怎么弄

先看一下这个图,觉得太笼统不明白的话不着急,我们接下来一步一步往下走。

一、第一步:搭建数据库资源

首先,先创建一个叫【tlias】的数据库,并创建一个【部门表dept】一个【员工表emp】,建表的代码在下面,直接复制即可

-- 部门管理
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());

二、第二步:创建spring boot工程,并引入依赖

这里我就直接在我的 “Springboot_Mybatis” 这个大工程目录下创建一个【spring boot工程

这里我需要纠正一个误区:我一开始新建项目叫 “Springboot_Mybatis” 的这个项目不是【spring boot工程】!!这是一个maven工程,在这个工程里我才可以方便地创建【spring boot工程】,并给我这个【spring boot工程】引入依赖啥的

我们就给这个【spring boot工程】起名为:tlias-web-management

引入依赖的时候注意,我们讲《spring boot》的时候讲要引入【spring web】依赖,然后讲《Mybatis》的时候讲要引入【MyBatis Framework】和【MySQL Driver】这两个依赖,那么我们这里是集合spring boot跟Mybatis的集合项目,这三个依赖就要一次性都引入!!!

那么有的伙计估计跟我一样,点完创建后那个页面怪怪的,都没有那些花里胡哨的颜色区分java、resource、test......(像下图,这是我之前一个项目的截图)

那还是老方法,手动给他们调成我们熟悉的“颜色”

过程我这讲过,这里不多说:后端之路第三站(Mybatis)——入门配置_mybatis url配置-CSDN博客

最后到pom.xml文件里把其余的一些依赖引入(MySQL、Mybatis...啥的不用了,刚刚创建的时候已经引入,把下面代码块这两引入就行了)

<!--druid连接池-->
<dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.8</version>
</dependency><!--lombok依赖-->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.30</version>
</dependency>

要是还是感觉怪怪的,记得区右边侧边点开maven,确认你的项目在maven的管理下,如果没有,那么手动点加号把maven添加进去,不要只点这个【spring boot工程】,要点它的pom.xml

三、准备好对应数据库表的实体类

一般存放实体类的包我们叫【pojo】,所有创建一个【pojo】目录,然后再往里建类

这里我直接把代码给各位准备好

部门表的实体类

//这里写你们自己的包路径
//package com.czm.tliaswebmanagement.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;/*** 部门实体类*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Dept {private Integer id; //IDprivate String name; //部门名称private LocalDateTime createTime; //创建时间private LocalDateTime updateTime; //修改时间
}

员工表的实体类

//这里写你们自己的包路径
//package com.czm.tliaswebmanagement.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
import java.time.LocalDateTime;/*** 员工实体类*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Emp {private Integer id; //IDprivate String username; //用户名private String password; //密码private String name; //姓名private Short gender; //性别 , 1 男, 2 女private String image; //图像urlprivate Short job; //职位 , 1 班主任 , 2 讲师 , 3 学工主管 , 4 教研主管 , 5 咨询师private LocalDate entrydate; //入职日期private Integer deptId; //部门IDprivate LocalDateTime createTime; //创建时间private LocalDateTime updateTime; //修改时间
}

四、接下来把三层架构、Mapper接口目录都创建好

首先我们刚学完后端Mybatis,还有一个【mapper】这个接口目录要创建,这时执行sql语句的地方,并在里面对应Dept、Emp两个表创建两个mapper接口

然后之前学spring boot我们学过有个什么【三层架构】,没了解过的去我的文章看看:后端之路第二站(正片)——SprintBoot之:分层解耦_后端分层-CSDN博客

还是不了解的话不要紧,因为我自己都忘了这是干啥的哈哈,但是别管这么多,把对应的【controller】和【service】层的目录创建好,为什么【Dao】不用创建?我也不知道,我暂时忘了,可能后面回想起来吧

然后【controller】里对应Dept、Emp两个表创建两个controller类

然后【service】里对应Dept、Emp两个表创建两个service接口,还有新建一个【impl】目录,里面是实现这两个service接口的类

然后思考我们之前讲的“控制反转和注入依赖”,它们对应的注解应该是

五、别忘了配置application.properties

#连接数据库的【四要素】
#1、数据库的驱动类名
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver#2、数据库的Url
spring.datasource.url = jdbc:mysql://localhost:3306/tlias#3、数据库的账户名
spring.datasource.username = r**t#4、数据库的密码
spring.datasource.password = 1****6#配置mybatis的日志,指定输出到控制台
mybatis.configuration.log-impl = org.apache.ibatis.logging.stdout.StdOutImpl#开启mybatis的驼峰命名自动映射开关
mybatis.configuration.map-underscore-to-camel-case = true

六、配置前后端相应返回的数据规范

前面学spring boot的时候我们学过,后端响应返回的数据格式是有规范的,那么我们就要封装好一个Result类(封装完放到pojo目录下就好)

完整代码在这:

//这里写你们自己的包路径
//package com.czm.tliaswebmanagement.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {private Integer code;//响应码,1 代表成功; 0 代表失败private String msg;  //响应信息 描述字符串private Object data; //返回的数据//增删改 成功响应public static Result success(){return new Result(1,"success",null);}//查询 成功响应public static Result success(Object data){return new Result(1,"success",data);}//失败响应public static Result error(String msg){return new Result(0,msg,null);}
}

七、开始写项目

这里我把黑马这个项目的大概业务需求资源发到这,应该是在页面顶部有,可以自行下载来看,每一个页面都有怎样的需求

1、查询

以上是部门查询的业务需求,那么根据这个我们要思考下一步该做什么

【三层架构】就来了!!!

首先前端发送请求,后端在Controller层接收到请求——>然后Controller层调用service查询部门——>service要执行逻辑操作,也就是完成查询的操作,那查询是sql的范围,就得去“求”mapper接口——>那现在应该就能明白Dao层是谁了吧?mapper接口就是Dao层,通过它的sql语句操作来解析获取到数据库的资源数据——>然后返回到数据库数据后给回service——>service给回Controller层——>Controller层最终再通过Result规范类返回一个规范的响应回前端

(1)先编写controller代码

~ 先编写接收请求的接口(接口注解 + 接口方法)

在controller接口里我们要写的是“接收请求”的操作,那么我们之前学《spring boot》学过如何写一个请求接口:后端之路第二站(正片)——SprintBoot之:设置请求接口_springboot如何添加接口请求ip显示-CSDN博客

因为【@RestController】注解包含了【@Controller】注解,还包含了【@Component】这个“控制反转”注解,那么我们就直接用【@RestController】

然后用【RequestMapping("/接口路径")】注解来规定接口路径是啥,接着写上跟“接口路径”同名的方法,这个方法的就是接收到前端请求之后反送给service的逻辑,返回值是最后返回给前端的数据响应

还要注意两点:

1、我们的方法的返回值类型应该是【Result】这个【规范响应类】,return的结果就是Result.成功响应或者Result.失败响应,这里我们可以先用第一个Result.success()来测试可以接通接口不

Result类:

Controller接口

2、我们通常会用System.out.println("...");来测试是否成功

但是实际开发中不建议用System.out.println("...");而是要采用【日志方式】,日志方式有两种

第一种是在方法外写下面这个代码(别记,直接复制),在方法里再log.info("想输出的内容")就行了

private static Logger log = LoggerFactory.getLogger(你这个controller类名.class);

注意Logger导入的是org.slf4j这个包

第二种是加一个【@Slf4j】这个注解,因为它就包含了上面那一长串代码,下面直接log.info()就行

3、【RequestMapping("接口路径")】这里的接口路径由前后端讨论后决定的接口文档里获得

现在就可以运行当前项目,结合apifox测试接口能否成功接收请求了

注意:这里的域名里,本地域名的话,localhost等于127.0.0.1,然后别忘了带上 “:端口”,我这的端口是8080

但是还有一个问题,无论这样写我们无论是get还是post方法都可以请求成功,可是接口文档规定了这个是get方法,怎么办?

只需要在【RequestMapping()】注解,在“/接口路径”后面再加一个“method”参数,设置为【RequestMethod.请求方式】就行

只要设置了method,就会自动变成这样

还有一种写法是【@方式Mapping】这种注解,比如get:

~ 然后将service的bean对象【注入依赖】,然后调用service对象来进行逻辑操作

首先先【注入依赖】,使用【Autowired】注解,然后定义Service接口的实例对象

然后开始进行调用Service对象的方法,让service进行逻辑操作

可以这么理解:这里就是我们学《Mybatis》时,在【test】目录的【ApplicationTests】干的事,(间接)调用Mapper的接口方法来进行sql操作,只不过这里隔了一层service:我们是先调用service的方法,然后因为service层不能直接操作sql,所以service要再调用mapper的接口方法,所以我们只是多了一层service而已,干的事是一样的

那么这里就要调用service的一个方法返回结果数据,根据这个数据类型定义一个变量接收,然后这就是结果了,把它返回给前端就行了

(2)现在到service层编写逻辑代码

根据刚刚在controller里我们写的list方法,对应在service的接口里生成并补全这个方法内容

然后到这个service的impl目录下,对应这个接口的【实现类】里【重写】这个抽象方法的完整内容

这里我要先给各位区分一下:

【@service】注解是service将自己作为bean对象放入IOC容器的注解方法,但是【bean对象】【bean对象】,啥是对象?是类的实例化!!!所以【@service】写在service的接口的实现类那,不是写在接口那!!!!

然后回到service的接口的实现类的代码里

【Alt + 回车】可以快捷键重写父接口里的抽象方法

然后因为service不能直接操作sql语句,所以还得调用mapper的接口方法来操作

(3)现在到Mapper接口去完成sql语句的操作,并返回最终结果

大功告成,现在重新启动服务,然后用apifox测试一下

成功返回数据库里所有部门信息!!!!

总结:

经过刚刚那么一大串操作,各位老兄们可能已经懵逼了,大部分人应该也没兴致看完,那这里我做一个简短的概括

首先,基础的项目搭建以及配置好之后,分好你项目的结构,一共四个:【controller】【mapper】【pojo】【service】

【pojo】:放你对应数据库那些表的实体类,还得放一个Result类,用于最终规范格式返回前端结果的

【controller】:放对应pojo的实体类的controller类(每个类都要加【@RestController】注解)

【service】:放对应pojo的实体类的service接口,还得有一个【impl】目录放对应这几个service接口的实现类(在这些实现类里加【@Service】注解,就可以“控制反转”,被当作bean对象放入IOC容器)

【mapper】:放对应操作数据库表sql语句的mapper接口,供service调用执行sql语句(每个mapper接口都要加【@Mapper】注解)

然后它们之间的逻辑就是:

controller层要写好请求接口(接口注解 + 接口方法)来接收前端请求

然后【@Autowired】注解注入依赖,调用service层来执行逻辑操作

在方法中间调用service的方法,并获取方法返回的值作为结果,返回给前端

然后service层在接口对应写好controller刚刚调用、需要的那个方法

然后到service的impl目录的实现子类里重写实现接口里的方法,但是因为service不能直接操作sql语句,所以还要用【@Autowired】注解注入依赖,调用mapper接口来执行sql语句

最后把mapper接口返回的结果return回controller

最后到mapper接口里执行sql语句操作

最后mapper接口结果返回给service,service返回给controller,controller返回给前端

2、删除

现在有删除部门这个业务,那么我们后端的逻辑就是根据前端发送的请求,前端给我们一个部门id,然后我们根据部门id删除这个部门的信息

那么大致的【三层架构】流程就是这样:

那么查看接口文档可以看到规范如下图:

那么注意这里,{id}这个参数是通过 “/” 路径拼接的,那么路径参数需要用到的注解是【@PathVariable】

(下图是我之前spring boot的笔记)

现在就可以直接写代码了

controller

service的接口和实现类

mapper的操作

然后前端测试一下请求

但是要注意用路径参数的测试apifox前端发送请求的方式:

成功

3、新增

现在有新增部门这个业务,那么我们后端的逻辑就是根据前端发送的请求,前端只给我们一个部门名字name,然后我们根据这个部门名字name新增一个部门的信息

那么大致的【三层架构】流程就是这样:

那么查看接口文档可以看到规范如下图:

那么这里要注意一点,因为请求方式是post,可以留意到这里接口文档要求我们传的参数形式,是以【json】的格式传给我们后端

那么我们就要在接口方法的参数那里用【@RequestBody】来将【json转化成实体类对象形式】给回后端

我们在《spring boot》:《后端之路第二站(正片)——SprintBoot之:设置响应-CSDN博客》讲了【@RequestBody】是啥:

但是我在这说声对不起,【@RequestBody】不单单只是把【对象转成json】给前端,还可以【json转成对象】给后端(我现在应该已经在那篇原文章修改了这部分)

那么只需要在controller的接口方法的参数那,定义1个对象形参,并用@RequestBody把接收到的json参数转化成对象,让这个对象形参接收

controller层代码

.

service层的接口跟实现类代码

这里注意一点:因为我们前端只传了【姓名name】,但是看数据库表会发现其实还有【创建时间create_time】、【更新时间update_ime】这两个数据,这就需要我们后端不齐全

再【实现类】补全对象的【create_time】、【update_ime】

然后再将补全的dept对象给到mapper执行sql语句(插入信息)

.

最后Mapper接口执行sql插入语句

然后重新启动,去apifox发送请求

(记住post请求是在body那传参,而不是params;然后参数是json格式的)

4、简约化封装接口

在完成了这么多个功能之后,我们会发现我们这些【部门接口】都有一个共同的【路径】:/depts

那么我们应该把它抽取出来,我们本来就是在【DeptController】这一个单独的controller文件里写接口,那就直接把用【@RequestMapping()】写上共有的这个接口路径

然后下面每一个不同的接口都用【@请求方式Mapping】这种对应不同方式的接口注解,没有路径参数的就不用带 “()” ;有路径参数的就带 “()” ,里面接上参数路径

我这里dept部门的完整controller层代码如下

//注释的导包不要用,导入你们自己的包路径
//package com.czm.tliaswebmanagement.controller;//import com.czm.tliaswebmanagement.pojo.Dept;
//import com.czm.tliaswebmanagement.pojo.Result;
//import com.czm.tliaswebmanagement.service.DeptService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;@Slf4j
@RestController
@RequestMapping("/depts")
public class DeptController {@Autowiredprivate DeptService deptService;/*** 查询部门的接口* @return*/@GetMappingpublic Result dept(){log.info("部门接口测试成功");//调用deptService接口的list方法(现在DeptService接口还没有,等会再去那补上这个方法)//还要用一个集合接收这个list方法的返回值List<Dept> deptList = deptService.list();//然后这个deptList装的就是DeptService的list方法返回的通过sql查询到的数据,把这个结果返回给前端return Result.success(deptList);}/*** 删除部门的接口*/@DeleteMapping("/{id}")public Result delete(@PathVariable Integer id){log.info("根据id删除部门:{}",id);//调用service根据id删除部门deptService.delete(id);//因为没有数据返回,所以直接调用Result的success的空参方法就行return Result.success();}/*** 新增部门信息*/@PostMappingpublic Result add(@RequestBody Dept dept){ //用一个对象接收前端传过来的json数据,@RequestBody注解把json转化成对象log.info("新增部门信息:{}",dept);//调用service新增部门deptService.add(dept);//因为没有数据返回,所以直接调用Result的success的空参方法就行return Result.success();}
}

5、更新

现在实现更新功能,前端点击部门,然后输入要改成什么名字

 那么查看接口文档可以看到规范如下图:

那么这里要注意:前端传过来的两个值,其中id是给后端找是哪个部门的,name姓名是后端要改成什么的部门名字

所以我们要根据id找到是哪个部门,然后修改部门名,然后还要记住是put方法,然后还要注意前端传过来的是json格式的数据,还得转成对象再处理

 controller层代码

.

service层的接口跟实现类代码

【实现类】

.

最后Mapper接口执行sql插入语句

然后这里我遇到一个问题,我根据黑马提供的资料,在apifox发送请求时的参数是

但是报了这么个错

其实是因为数据库中已经有了“教研部”,部门名字name这个字段,我们在建表的时候设置了唯一约束,所以不应该有相同的部门名字,比如我们换一个

成功了

6、复杂的查询

(1)(传统的方法)员工表【分页查询】

有的时候看一些后台管理系统可以发现,有成千上百条数据,你一页根本看不完,就像你们晚上偷偷看的小网站,要是全在一个页面不得往下翻到死

——前期分析

—那就需要设置分页查询,下面有对应的1~n页,点那一页就显示一部分数据

—然后前端有时还要统计总共有多少条数据

那么回顾一下sql语法,分页查询的代码是

select * from 表 limit 起始索引,要查几条数据; 

查询数据总数的sql代码是

select count(*) from 表;

那么后端需要的参数就是【页码】和【每页显示几条数据】

而前端需要的则是【整个数据列表】和【一共有多少条数据】

整体逻辑就是下图:

那么这里又要返回给前端的数据里,又要【数据总数】、又要返回【每一页的数据列表】,一个返回的是List<E>集合类型,一个返回的是Integer数字类型

然而一个请求方法只能返回一个类型咋办?

那就把这两个类型都封装到一个实体类,那请求方法就可以返回一个对象了。只要传多个数据就用对象装起来!!!!

三层架构逻辑:

controller层

要注意两点:

1、记住前端用不同方式传参,后端要怎么对应获取参数:

——当前端在Paramas传数据,以这种【网址域名?参数1=值1&参数2=值2...】形式传参的时候,后端的controller请求方法里( )对应写上参数,后端就会自动获得参数

(参数名字一定要一样,比如前端:【http:localhost:8080/emps?page=1&pageSize=10】,后端就要【public Result select(Integer page, Integer pageSize)】)

——当前端传数据json格式,后端就用@RequestBody解析参数,并给到对象参数(【public Result select(@RequestBody  某对象  形参变量)】)

——当前端在传路径形式参数【网址域名/参数1/参数2...】形式的时候,后端的controller请求方法里( )对应每个参数前加@PathVariable来解析参数

(比如前端:【http:localhost:8080/emps/1/10】,后端就要【public Result select(@PathVariable Integer page, @PathVariable Integer pageSize)】)

2、如果前端有可能不传参数,而后端又必须要用参数,就得给参数设置默认值

 比如:当前端页面刚加载进来的时候,肯定还没有点击下面的页码,那这个时候在没有传递【页码:page】和【每页显示几条数据:pageSize】的时候,我们得先设置默认值:【第一页】和【每页查询10条】

那么就要用到【@RequestParam( defualtValue = "默认值" )

.

以上知识点我都在《springboot》文章讲过:

后端之路第二站(正片)——SprintBoot之:设置请求接口_可以发送接口的软件-CSDN博客

代码:

service层

这里要注意的是三点:

1、因为我们要的返回给前端的是装着【整个数据列表】和【一共有多少条数据】的对象(pageBean),那么我们就在service实现类创建一个pageBean对象,把最后sql查询到的两个结果装进pageBean对象里

2、因为前端要的是两个数据,所以得执行两个不同的sql查询语句,那就调用两个mapper的查询方法,并用对应的数据类型的变量接收

3、因为前端要做的只是点击传送页码(1-n),还有传每页要查几条,而假设我们每页要查5条,那么第1页就应该是从第1条(索引位0)数据开始查到第5条(索引位4),第2页就应该是从第6条(索引位5)数据开始查到第11条(索引位10)

那么【查询的起始索引】的公式就应该是:【(页码 - 1) * 每页查几条】,然后传给sql做查询时就应该是传这个【查询的起始索引】,而不是查【page】

mapper层

分别执行两个sql语句就行了

发送请求,成功

(2)快捷分页查询

上面那是老传统手搓代码方法,当然也有更快捷的方法,叫【PageHelper插件】

要用它只需要完成下面几步:

只需记住:【controller】不变,因为前后端联调不影响;变的是后端的处理逻辑,所以只变【mapper】跟【service】

第一步:pom.xml文件引入依赖
<!-- PageHelper的依赖 -->
<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.2</version>
</dependency>
第二步,mapper里去掉麻烦的分页查询、统计数据

啥也别管直接【select * from 表】

第三步,接下来就是在service里使用PageHelper来帮我们完成分页的功能

我们首先用【PageHelper.startPage( )】方法,配置PageHelper插件的参数:【页码】【每页查几条】(直接传)

接着我们调用mapper获得查询返回的所有员工列表信息,然后PageHelper提供了一个【Page类】,我们只需要把返回的【所有员工列表信息】强制转换成这个【Page类】,就可以任意用这个【Page类】的方法来得到我们我们想要的结果(数据总数、整个数据列表信息......等等)

总结

(3)配合PageHelper,既分页查询又条件查询

那么我们之前在讲:《后端之路第三站(Mybatis)——动态操作sql-CSDN博客》的时候讲过XML文件来进行复杂的动态条件查询

不过这里还要搭配PageHelper进行一个分页查询,那么就把二者结合起来就行了

比如还是这个:要么只根据姓名模糊查询、要么只根据性别查询、要么只根据入职时间范围查询、要么都查询、要么根据其中两个条件查

那就必须得用XML映射文件来进行查询了,我的之前文章讲过怎么用,这里不再说:

后端之路第三站(Mybatis)——XML文件操作sql_mybatis 如何读区xml中的sql-CSDN博客

那么只用在上面的基础做两个改动:

1、把所有方法里的参数(在page和pageSize之后),都再加上四个参数(姓名、性别、入职起始时间、入职结束时间)

注意【时间参数】用【@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")】

mapper里多个参数要用【@Param(" ")】

后端controller层请求方法里定义的参数,前端可以不用全都传,不影响(前提是后端mapper接口要有id判断条件)

2、mapper层接口要用XML映射文件进行动态判断条件的sql语句

controller层代码

service层代码

mapper接口代码

发送请求,成功

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/371915.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows系统本地端口被占用的问题

第一步&#xff1a;查找所有运行的端口 按住“WindowsR”组合键&#xff0c;打开命令窗口&#xff0c;输入【cmd】命令&#xff0c;回车。在弹出的窗口中输入 命令【netstat -ano】&#xff0c;再按一下回车键 Win系统端口被占用-查找所有运行的端口 第二步&#xff1a;查看…

数组算法(二):交替子数组计数

1. 官方描述 给你一个二进制数组nums 。如果一个子数组中 不存在 两个 相邻 元素的值 相同 的情况&#xff0c;我们称这样的子数组为 交替子数组 。 返回数组 nums 中交替子数组的数量。 示例 1&#xff1a; 输入&#xff1a; nums [0,1,1,1] 输出&#xff1a; 5 解释&#…

wait和sleep在同步方面的区别

在 Java 中&#xff0c;wait 和 sleep 都用于让线程进入等待状态&#xff0c;但它们在同步操作和线程管理方面有显著区别。以下是它们的主要区别&#xff1a; 1. 所属的类 wait 是 Object 类的方法。sleep 是 Thread 类的静态方法。 2. 使用场景 wait 用于线程间通信&#…

智能家居安防系统教学解决方案

前言 随着科技的不断进步和智能家居概念的深入人心&#xff0c;智能家居安防系统作为智能家居领域的重要组成部分&#xff0c;其重要性日益凸显。智能家居安防系统不仅能够提供环境和人员的监测功能&#xff0c;还能够采取措施降低或避免人员伤亡及财产损失。因此&#xff0c;…

第十一节 动态面板加密解密显示

在原型中我们经常会遇到文件加密与解密显示问题&#xff0c;下面以一个简单案例来说明实现怎么切换明文与密文不同显示方式案例说明&#xff1b; 1、添加动态面板 2、设置加密与不加密 3、添加动作事项 注意为可见时要设置面板状态向前循环&#xff0c;上一项&#xff0c;否则…

网络安全--计算机网络安全概述

文章目录 网络信息系统安全的目标网络安全的分支举例P2DR模型信息安全模型访问控制的分类多级安全模型 网络信息系统安全的目标 保密性 保证用户信息的保密性&#xff0c;对于非公开的信息&#xff0c;用户无法访问并且无法进行非授权访问&#xff0c;举例子就是&#xff1a;防…

如何在 Odoo 16 中对 Many2Many 字段使用 Group by

Many2many 字段与 Many2one 字段类似&#xff0c;因为它们在模型之间建立了新的关系。在Odoo 16中&#xff0c;您无法按 many2many 字段分组&#xff0c;因为可以使用 many2many 记录选择任何记录。当您使用 many2many 字段给出 group by 过滤器时&#xff0c;您将遇到断言错误…

基于Java+SpringMvc+Vue技术的实验室管理系统设计与实现(6000字以上论文参考)

博主介绍&#xff1a;硕士研究生&#xff0c;专注于信息化技术领域开发与管理&#xff0c;会使用java、标准c/c等开发语言&#xff0c;以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年&#xff0c;拥有近12年的管理工作经验&#xff0c;拥有较丰富的技术架…

权限维持-Linux-内核加载 LKM-Rootkit 后门

免责声明:本文仅做技术交流与学习... 目录 权限维持-Linux-内核加载 LKM-Rootkit 后门 项目地址: 安装: 隐藏用法: 将 root 权限授予非特权用户 隐藏文件、目录和内核模块 隐藏进程 隐藏 TCP 和 UDP 连接 高级玩法(c/s) 攻击机上(客户端)安装: 设置连接配置 权限维持…

html+js+css做的扫雷

做了个扫雷&#x1f4a3; 88大小 源代码在文章最后 界面 先点击蓝色开局按钮 然后就可以再扫雷的棋盘上玩 0代表该位置没有雷 其他数字代表周围雷的数量 源代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8&qu…

【Go】常见的变量与常量

变量 常见的变量声明方式 一、声明单个变量的多种方式 1.声明一个变量初始化一个值 //声明变量 默认值是0&#xff0c;var a int//初始化一个值a 1fmt.Println(a) 2. 在初始化的时候省去数据类型&#xff0c;通过值自动匹配当前的变量的数据类型 var b 2fmt.Println(&quo…

国内采用docker部署open-metadata

背景 最近看看开源的元数据管理项目&#xff0c;比较出名点的有open-metadata、datahub、OpenLineage、atlas。 open-metadata有1千多的贡献者&#xff0c;4.8K的stars&#xff0c;社区现在也比较活跃&#xff0c;支持的数据库类型还蛮多&#xff0c;基本市面上常见的都有支持…

rocketmq实现限流

目录 问题背景 技术方向 方案确认 消息队列&#xff08;√&#xff09; 分布式锁&#xff08;&#xff09; 方案实现 监控方向 业务方向 问题背景 公司邮件服务token有 分钟内超200封的熔断机制&#xff0c;当前token被熔断后&#xff0c;系统发邮件操作会被忽略&…

充电桩一般使用哪种倾倒检测传感器

充电桩通常采用光电倾倒开关作为倾倒检测传感器。这种传感器结构精巧&#xff0c;内置红外发光二极管和光敏接收器&#xff0c;利用光的传输来判断倾倒状态。 光电倾倒开关的设计非常小巧&#xff0c;这使得它可以轻松安装在充电桩的关键部位&#xff0c;无论是垂直、水平还是…

Pandas 学习笔记(四)--CSV文件

CSV文件 CSV&#xff08;Comma-Separated Values&#xff0c;逗号分隔值&#xff0c;有时也称为字符分隔值&#xff0c;因为分隔字符也可以不是逗号&#xff09;&#xff0c;其文件以纯文本形式存储表格数据&#xff08;数字和文本&#xff09;。 读取与写入 读取csv文件 i…

用PlantUML可视化显示JSON

概述 PlantUML除了绘制UML中的一些标准图之外&#xff0c;也可以以图形化的方式显示一些其他图形或数据形式的结构&#xff0c;这其中就包括JSON。 它以一种简单且优美的图形形式&#xff0c;表达了JSON的结构。你可以用它来作为设计JSON数据文件的依据&#xff0c;辅助设计或…

LeetCode刷题之搜索二维矩阵

2024 7/5 一如既往的晴天&#xff0c;分享几张拍的照片嘿嘿&#xff0c;好几天没做题了&#xff0c;在徘徊、踌躇、踱步。蝉鸣的有些聒噪了&#xff0c;栀子花花苞也都掉落啦&#xff0c;今天给他剪了枝&#xff0c;接回一楼来了。ok&#xff0c;做题啦&#xff01; 图1、宿舍…

Python采集京东标题,店铺,销量,价格,SKU,评论,图片

京东的许多数据是通过 JavaScript 动态加载的&#xff0c;包括销量、价格、评论和评论时间等信息。我们无法仅通过传统的静态网页爬取方法获取到这些数据。需要使用到如 Selenium 或 Pyppeteer 等能够模拟浏览器行为的工具。 另外&#xff0c;京东的评论系统是独立的一个系统&a…

【力扣高频题】014.最长公共前缀

经常刷算法题的小伙伴对于 “最长”&#xff0c;“公共” 两个词一定不陌生。与此相关的算法题目实在是太多了 &#xff01;&#xff01;&#xff01; 之前的 「动态规划」 专题系列文章中就曾讲解过两道相关的题目&#xff1a;最长公共子序列 和 最长回文子序列 。 关注公众…

O2OA(翱途)开发平台 V9.1 即将发布,更安全、更高效、更开放

尊敬的O2OA(翱途)平台合作伙伴、用户以及亲爱的开发小伙伴们&#xff0c;O2OA(翱途)平台 V9.1将于7月3日正式发布&#xff0c;届时欢迎大家到O2OA官网部署下载及体验最新版本。新版本我们在如下方面做了更大的努力&#xff1a; 1.扩展数据库兼容性和功能范围&#xff1a;在O2OA…