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

在前面学完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.mzph.cn/web/38811.shtml

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

相关文章

Java面试题总结

Redis篇 什么是缓存穿透 ? 怎么解决 ? 缓存穿透是指查询一个不存在的数据&#xff0c;如果从存储层查不到数据则不写入缓存&#xff0c;这将导致这个不存在的数据每次请求都要到 DB 去查询&#xff0c;可能导致 DB 挂掉。这种情况大概率是遭到了攻击。 解决方案有两种&…

Arthas实战(2)- OOM问题排查

一、 准备测试应用 新建一个 SpringBoot应用&#xff0c;写一段有 OOM bug 的代码&#xff1a; RestController RequestMapping public class JvmThreadController {List<TestWrapper> memoryList new ArrayList<>();GetMapping("/test")public Strin…

mov文件怎么转换成mp4格式?这四种转换方法超级好用!

mov文件怎么转换成mp4格式&#xff1f;在数字娱乐的世界中&#xff0c;你是否曾遇到过MOV格式的视频&#xff1f;也许&#xff0c;对于许多人来说&#xff0c;这并不是一个常见的格式&#xff0c;但这并非偶然&#xff0c;首先&#xff0c;我们来谈谈MOV的兼容性问题&#xff0…

使用python做飞机大战

代码地址: 点击跳转

不看测评盲买花了多少冤枉钱..测评希喂、爱立方、帕特看完不踩雷

主食冻在挑选主食冻干时&#xff0c;许多宠物主人都会感到头疼。尽管主食冻干相较于普通猫粮具有诸多优势&#xff0c;但其价格也相对高昂。这导致许多宠物主人担心高价购买的主食冻干可能营养价值并不理想。然而&#xff0c;在选择时&#xff0c;我们还需要考虑其他重要因素&a…

“穿越时空的机械奇观:记里鼓车的历史与科技探秘“

在人类文明的发展历程中&#xff0c;科技的创新与进步不仅仅推动了社会的进步&#xff0c;也为我们留下了丰富的文化遗产。记里鼓车&#xff0c;作为一种古老的里程计量工具&#xff0c;其历史地位和技术成就在科技史上具有重要的意义。本文将详细介绍记里鼓车的起源、结构原理…

0基础学C++ | 第10天 | 基础知识 |程序的内存模型 | 4大分区

前言 第9天是一个通讯录管理系统案例&#xff0c;现在了解程序的内存分区&#xff0c;C程序在执行时&#xff0c;将内存大方向分为了4个区域&#xff0c;分别是代码区、全局区、栈区、堆区&#xff0c;分区的目的就是为了更加灵活的编程。 代码区 and 全局区&#xff08;程序…

Echarts柱状图x轴刻度间隔显示不全/x轴文字倾斜

此情况一般是因为x轴文字过长导致&#xff0c;知道什么原因&#xff0c;就可以解决了 在xAxis里面加 xAxis: {axisLabel: {interval: 0,rotate: -45 //文字过多时&#xff0c;倾斜角度}} 控制它的属性是axisLabel&#xff0c;该属性interva设置成0则表示强制显示所有标签&a…

这所985院校不保护一志愿,18人不合格被刷!西北农林科技大学计算机考研考情分析!

西北农林科技大学(Northwest A&F University)&#xff0c;简称“西农”或“西北农林”&#xff0c;始创于1934年&#xff0c;位于中华人民共和国陕西省杨凌示范区。1999年9月11日由同处杨凌的原西北农业大学、西北林学院、中国科学院水利部水土保持研究所、水利部西北水利科…

外籍学员报到,四川眼科医院开启国际屈光手术专科医生培训

“能够来到中国、来到四川眼科医院学习&#xff0c;我真的很幸运&#xff01;”这个夏天&#xff0c;对于马来西亚眼科医生Ivan Cheng En Yoo来说&#xff0c;充满了期待和挑战。他是首位来到四川眼科医院进修学习的马来西亚籍医生&#xff0c;Ivan Cheng将在周进院长的带领下&…

Android Gradle 开发与应用 (三): 依赖管理与版本控制

目录 1. 依赖管理的重要性 1.1 依赖的类型 1.2 Gradle 中的依赖声明 2. 版本控制的策略 2.1 固定版本与动态版本 2.2 版本冲突的解决 3. Gradle 插件的使用 3.1 常用的 Gradle 插件 3.2 自定义插件 4. 多模块项目中的依赖管理 4.1 模块间依赖 4.2 公共依赖 5. 依赖…

用“文心一言”写的文章,看看AI写得怎么样?

​零售连锁店的“支付结算”业务设计 在数字化浪潮的推动下&#xff0c;连锁店零售支付结算的设计愈发重要。一个优秀的支付结算设计不仅能够提升用户体验&#xff0c;还能增强品牌竞争力&#xff0c;进而促进销售增长。 本文将围绕一个具体的连锁店零售支付结算案例&#xf…

数据结构第06节:栈

栈&#xff08;Stack&#xff09;是一种后进先出&#xff08;Last In First Out, LIFO&#xff09;的数据结构&#xff0c;它只允许在一端&#xff0c;称为栈顶&#xff08;Top&#xff09;&#xff0c;进行添加&#xff08;Push&#xff09;和移除&#xff08;Pop&#xff09;…

MySql Innodb 索引有哪些与详解

概述 对于MYSQL的INNODB存储引擎的索引&#xff0c;大家是不陌生的&#xff0c;都能想到是 B树结构&#xff0c;可以加速SQL查询。但对于B树索引&#xff0c;它到底“长”得什么样子&#xff0c;它具体如何由一个个字节构成的&#xff0c;这些的基础知识鲜有人深究。本篇文章从…

【Spring Boot】JPA 的查询方式

JPA 的查询方式 1.使用约定方法名2.用 JPQL 进行查询3.用原生 SQL 进行查询3.1 根据 ID 查询用户3.2 查询所有用户3.3 根据 email 查询用户3.4 根据 name 查询用户&#xff0c;并返回分页对象 Page3.5 根据名字来修改 email 的值3.6 使用事务 4.用 Specifications 进行查询5.用…

Mac视频下载工具,兼容14系统,Downie 4软件下载

Downie 4 是一款由James Application开发的视频下载软件&#xff0c;支持Mac操作系统。该软件允许用户从各种视频网站上下载视频内容&#xff0c;以便于在本地设备上观看&#xff0c;无需依赖互联网连接。自动下载&#xff1a;可以设置Downie 4自动下载指定网站上的视频&#x…

当+=的时候,为什么会出现NaN?

问: var textToDisplay; // "testing"; textToDisplay "testing"; textToDisplay 1; var someNumber 1; var oneMoreNumber; oneMoreNumber textToDisplay someNumber; //results in NaN console.log(oneMoreNumber); 这里的结果是NaN? 回答: 是…

【LinuxC语言】线程池的原理和实现

文章目录 前言为什么需要线程池线程池的原理总结前言 在现代计算中,多线程编程已经成为一种常见的做法,它可以帮助我们更有效地利用多核处理器的能力。然而,频繁地创建和销毁线程会带来一定的开销。为了解决这个问题,我们可以使用一种称为“线程池”的技术。线程池是一种在…

黑马点评-Redis的缓存击穿,缓存雪崩,缓存穿透,互斥锁,逻辑过期

文章目录 1.缓存穿透2.缓存雪崩3.缓存击穿3.1 互斥锁3.2 基于逻辑过期 1.缓存穿透 解决办法 写入NULL值到Redis缓存&#xff0c;以后就会命中Redis的控制缓存而不会出现请求直接打到数据库的问题&#xff01; 代码 2.缓存雪崩 这个概念很好理解&#xff0c;雪崩就是无数的…

【LLM大模型书】从零开始大模型开发与微调:基于PyTorch与ChatGLM (附PDF)

今天又来给大家推荐一本大模型方面的书籍<从零开始大模型开发与微调&#xff1a;基于PyTorch与ChatGLM>。 本书使用PyTorch 2.0作为学习大模型的基本框架&#xff0c;以ChatGLM为例详细讲解大模型的基本理论、算法、程序实现、应用实战以及微调技术&#xff0c;为读者揭…