员工分页条件查询
案例中需求的是根据姓名,年龄或者入职时间进行查询,但是肯定不是每一个查询时都会有数据,比如我只想查找年龄是22岁的人,而不管姓名和入职时间,这时我们就采用动态sql的方式。
分页条件查询流程:
Controller层接收参数
当用户在界面输入查询条件并且点击查询时,请求就会传到controller层,我们就需要在controller中接收之前的分页参数,还有查询条件 。然后调用service进行条件分页查询,获取pagebean,只需要将查询条件参数传递到service。
具体实现:

还可以在日期前面添加注解@DateTimeFormat,标注日期的格式某某年某某日,yyyy-mm-dd
在Controller中写参数注解的主要原因:
-
明确性:明确参数来源和约束
-
健壮性:提供默认值,防止空指针
-
灵活性:支持可选参数,接口更易用
-
规范性:符合RESTful API设计原则
-
可维护性:代码清晰,易于理解
对于分页查询这种常见场景,使用DTO对象封装+适当注解是最佳实践,既保证了代码的清晰度,又提供了良好的开发体验。
Service代码逻辑实现
service层通过pagehelper完成分页查询,并且封装pagebean对象,返回。然后调用mapper接口。将查询条件传递给mapper接口。

XML映射文件
最终在mapper中执行查询时,根据传递进来的参数进行动态sql查询。
既然要使用动态sql,我们推荐使用xml映射文件来定义。可以在官方文档自行赋值约束。

删除员工
由于上面已经具体介绍了每步的具体实现,下面我们主要是注重思路和逻辑。
EmpController
1.接收路径参数id数组
2.调用service进行批量删除
3.响应
@DeleteMapping
@PathVariable 路径参数,指定路径,加在方法的形参上。
EmpService
1.调用mapper接口进行批量删除操作
EmpMapper
- delete from empwhere id in (?,?,?); 动态sql<foreach>
<delete id="delete">
deletefrom emp where id in
<foreach collection="ids" item="id" separator="," open=" (" close=") ">
#{id)
</foreach>
</delete>
新增员工
Cotroller
要封装JASO类型的格式,我们一般通过实体类进行封装,而且要在实体类前面加上@RequestBody
1.接收并封装参数
2.调用service方法保存数据
3.响应
@PostMapping
@RequestBody
关于调用service方法:
查询操作:需要返回数据给前端 → 需要返回值
新增/修改/删除操作:只需要知道成功/失败 → 不需要返回具体数据
@RestController
@RequestMapping("/emps")
public class EmpController {
@Autowired
private EmpService empService;
// 新增员工
@PostMapping
public Result add(@RequestBody Emp emp) {
// 直接调用Service,不接收返回值
empService.add(emp);
// 返回操作成功的统一响应
return Result.success();
}
}
Service
补充实体基础属性
调用mapper接口进行保存数据操作
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empMapper;
@Override
public void add(Emp emp) {
// 设置默认值
emp.setCreateTime(LocalDateTime.now());
emp.setUpdateTime(LocalDateTime.now());
emp.setStatus((short)1);
// 业务逻辑验证
if (emp.getName() == null || emp.getName().trim().isEmpty()) {
throw new BusinessException("员工姓名不能为空");
}
// 调用Mapper插入数据
empMapper.insert(emp);
// 没有return语句,或者返回void
}
}
Mapper
insert into emp(....)values(?,?,?);
细节:
-
接口中 :可以偷懒不写
public(写了也不扣分) -
实现类中 :必须写
public,不然可能会出访问权限问题 -
好习惯 :接口中省略
public保持简洁,实现类中加上@Override和public确保正确性
这就是为什么在Tlias案例中,Service接口的方法都没有写public,但实现类中却需要写的原因。这种设计既保持了代码的简洁性,又确保了正确的访问权限。
文件上传
文件上传,是指将本地图片、视频、音频等文件上传到服务器,供其他用户浏览或下载的过程。
文件上传在项目中应用非常广泛,我们经常发微博、发微信朋友圈都用到了文件上传功能。
前端

表单的enctype不能设置为默认值,必须设置为"multipart/form-data",否则得到的仅仅是文件名,而不是文件中的数据。
服务端

服务端我们要想接收到上传上来的文件,我们需要通过MultipartFile这个API。
然而目前上传的文件仅仅是临时文件。只要在文件上传请求结束之后,文件就会被自动删除。
文件存储
本地存储
接收到上传的文件,储存到本地磁盘目录下。
具体操作:
//获取原始文件的拓展名
//构造唯一的文件名uuid
//唯一的文件名加上拓展名

阿里云对象存储
阿里云对象存储OSs(Object Storage Service),是一款海量、安全、低成本、高可靠的云存储服务。使用OSs,您可以通过网络随时存储和调用包括文本、图片、音频和视频等在内的各种文件。
Bucket:存储空间是用户用于存储对象(Object,就是文件)的容器,所有的对象都必须隶属于某个存储空间,
SDK:Software Development Kit 的缩写,软件开发工具包,包括辅助软件开发的依赖(jar包)、
代码示例等,都可以叫做SDK。
在官方文档中导入阿里云的相关配置,新版本的acesskey 需要在系统中自行配置环境变量。
这是我利用OSS上传的第一个文件:https://web-tlias-css1.oss-cn-beijing.aliyuncs.com/1.jpg
在spring中调用工具类中的方法,不需要去new一个对象,而是把这个对象交给ioc容器管理,有四个注解,controller对应controller,mapper对应mapper,service对应service,其他的用component,在其他类中用到这个对象,直接用注解@Autowired
private Ali0SSUtils aliossUtils;
文件上传;

Emp emp作为方法参数的意思是:
-
声明一个形式参数 ,参数类型是
Emp,参数名是emp -
告诉调用者:这个方法需要接收一个Emp类的对象
-
Spring框架会:自动将请求数据(JSON/表单)转换为Emp对象
-
在方法内部:可以直接使用emp对象的所有属性和方法
核心思想:面向对象编程中,对象作为参数传递是非常常见的做法,它:
-
封装复杂数据
-
提高代码可读性
-
便于扩展维护
-
符合面向对象设计原则
所以在你的Tlias项目中,看到Emp emp作为参数,就是接收一个员工对象,包含了员工的所有信息!