摘要:本篇博客将介绍如何使用Spring Boot和MyBatis Plus框架来构建农牧会项目中的围栏管理模块。我们将通过实现多条件查询、添加、更新、删除等功能,为围栏管理模块提供完整的CRUD操作。同时,我们将介绍如何使用Controller、Service、Mapper等组件来组织和实现代码逻辑,并使用MyBatis Plus的强大功能简化数据库操作。
正文:
1.概述
1.需求和功能
农牧会项目中的围栏管理模块负责管理和维护各个围栏的信息,包括围栏名称、牧场名称、圈舍名称、启用状态等。本模块旨在提供对围栏数据的CRUD操作,同时支持多条件查询,方便用户根据需要过滤和检索围栏数据。
2.为什么使用mybatisplus
对于MyBatis Plus,它提供了一种便捷的方式来进行数据库操作,可以省去编写繁琐的XML映射文件。MyBatis Plus推崇使用注解方式来进行数据库操作,简化了开发流程并提高了开发效率。
使用MyBatis Plus注解方式,你可以直接使用实体类以及提供的便捷方法进行数据库操作。不再需要手写XML映射文件,数据操作逻辑可以直接在Service层中进行编写,提高了开发效率。
当然,如果你需要更复杂的数据库操作,MyBatis Plus也提供了XML映射文件的支持,可以根据实际需求选择使用。但在许多情况下,使用注解方式已经足够满足大部分的数据库操作需求。
2.环境搭建
在开始之前,需要进行以下环境搭建工作:
- 安装Java开发环境:确保已安装Java JDK,并设置好JAVA_HOME环境变量。
- 安装开发工具:选择一个集成开发环境,如IntelliJ IDEA或Eclipse。
- 创建Spring Boot项目:使用Spring Initializr创建一个新的Spring Boot项目,选择所需的依赖和设置。
3.数据库设计
CREATE TABLE fence (
fenceid INT PRIMARY KEY AUTO_INCREMENT,
ranchname VARCHAR(100),
shedname VARCHAR(100),
fencename VARCHAR(100),
stocklevel INT,
enablestatus VARCHAR(10),
lastmodified TIMESTAMP
);
INSERT INTO fence (ranchname, shedname, fencename, stocklevel, enablestatus, lastmodified) VALUES
('Ranch A', 'Shed 1', 'Fence 1', 50, 'Enabled', NOW()),
('Ranch B', 'Shed 2', 'Fence 2', 30, 'Enabled', NOW()),
('Ranch C', 'Shed 3', 'Fence 3', 20, 'Disabled', NOW()),
('Ranch D', 'Shed 4', 'Fence 4', 10, 'Enabled', NOW());
4.配置MyBatis Plus
1.引入MyBatis Plus的依赖,数据库等依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter-test</artifactId>
<version>2.3.1</version>
<scope>test</scope>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
2.配置数据源和MyBatis Plus相关的配置信息application.yml。
server:
port: 8080
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC
username: root
password: 123456
5.实体类与Mapper
1.创建与数据库表对应的实体类
import lombok.Data;
import java.util.Date;
@Data
public class Fence {
private Integer fenceId;
private String ranchName;
private String shedName;
private String fenceName;
private Integer stockLevel;
private String enableStatus;
private Date lastModified;
}
2。启动类标记扫描。
package com.cqie;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
// 加入注解
@MapperScan("com.cqie.*.mapper")
public class Demo6Application {
public static void main(String[] args) {
SpringApplication.run(Demo6Application.class, args);
}
}
6.Mapper XML文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cqie.system.mapper.FenceMapper">
</mapper>
7.Service层
1.接口
package com.cqie.system.service;
import com.cqie.system.entity.Fence;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cqie.system.entity.Ranch;
import java.util.List;
/**
* <p>
* 服务类
* </p>
*
* @author Gabriel
* @since 2023-08-16
*/
public interface IFenceService extends IService<Fence> {
//新增围栏
void addFence(Fence fence);
//修改围栏
void updateFence(Fence fence);
//查询围栏
List<Fence> searchFences(String ranchName, String shedName, String fenceName, String enableStatus);
//启用围栏
void enableFence(Long fenceId);
//禁用围栏
void disableFence(Long fenceId);
}
2.实现类
package com.cqie.system.service.impl;
import com.cqie.system.entity.Fence;
import com.cqie.system.mapper.FenceMapper;
import com.cqie.system.service.IFenceService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class FenceServiceImpl extends ServiceImpl<FenceMapper, Fence> implements IFenceService {
@Override
public void addFence(Fence fence) {
// 校验字段是否为空
if (fence.getRanchid() == null || fence.getShedid() == null || StringUtils.isEmpty(fence.getFencename())) {
throw new IllegalArgumentException("必填字段不能为空");
}
// 校验围栏名称长度
if (fence.getFencename().length() > 20) {
throw new IllegalArgumentException("围栏名称长度不能超过20个字符");
}
// 校验围栏名称在同一圈舍下是否重复
QueryWrapper<Fence> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("shedid", fence.getShedid());
queryWrapper.eq("fencename", fence.getFencename());
Long count = count(queryWrapper);
if (count > 0) {
throw new IllegalArgumentException("同一圈舍下不能有重复的围栏名称");
}
// 设置默认值
fence.setEnablestatus(true);
fence.setLastmodified(LocalDateTime.now());
// 插入围栏数据
save(fence);
}
@Override
public void updateFence(Fence fence) {
// 根据围栏ID获取旧的围栏数据
Fence oldFence = getById(fence.getFenceid());
if (oldFence == null) {
throw new IllegalArgumentException("找不到指定的围栏");
}
// 只允许修改围栏名称和所属圈舍
oldFence.setFencename(fence.getFencename());
oldFence.setShedid(fence.getShedid());
oldFence.setLastmodified(LocalDateTime.now());
// 更新围栏数据
updateById(oldFence);
}
@Override
public List<Fence> searchFences(String ranchName, String shedName, String fenceName, String enableStatus) {
// 构建查询条件
QueryWrapper<Fence> queryWrapper = new QueryWrapper<>();
// 根据牧场名称进行查询
if (!StringUtils.isEmpty(ranchName)) {
queryWrapper.eq("ranchid", ranchName);
}
// 根据棚舍名称进行查询
if (!StringUtils.isEmpty(shedName)) {
queryWrapper.eq("shedid", shedName);
}
// 根据围栏名称进行查询
if (!StringUtils.isEmpty(fenceName)) {
queryWrapper.eq("fencename", fenceName);
}
// 根据启用状态进行查询
if (!StringUtils.isEmpty(enableStatus)) {
queryWrapper.eq("enablestatus", enableStatus);
}
// 执行查询
return list(queryWrapper);
}
//启用围栏
@Override
public void enableFence(Long fenceId) {
// 根据围栏ID获取围栏数据
Fence fence = getById(fenceId);
if (fence == null) {
throw new IllegalArgumentException("找不到指定的围栏");
}
// 设置启用状态为true
fence.setEnablestatus(true);
fence.setLastmodified(LocalDateTime.now());
// 更新围栏数据
updateById(fence);
}
//禁用围栏
@Override
public void disableFence(Long fenceId) {
// 根据围栏ID获取围栏数据
Fence fence = getById(fenceId);
if (fence == null) {
throw new IllegalArgumentException("找不到指定的围栏");
}
// 设置启用状态为false
fence.setEnablestatus(false);
fence.setLastmodified(LocalDateTime.now());
// 更新围栏数据
updateById(fence);
}
}
8.Controller层
package com.cqie.system.controller;
import com.cqie.system.entity.Fence;
import com.cqie.system.service.impl.FenceServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/system/fence")
public class FenceController {
private FenceServiceImpl fenceService;
@Autowired
public FenceController(FenceServiceImpl fenceService){
this.fenceService=fenceService;
}
@PostMapping("/update")
public void addOrUpdateFence(@RequestBody Fence fence) {
if (fence.getFenceid() == null) {
// 添加新的围栏
fenceService.addFence(fence);
} else {
// 更新现有的围栏
fenceService.updateFence(fence);
}
}
@GetMapping("search")
public List<Fence> searchFences(@RequestParam(required = false) String ranchName,
@RequestParam(required = false) String shedName,
@RequestParam(required = false) String fenceName,
@RequestParam(required = false) String enableStatus) {
return fenceService.searchFences(ranchName, shedName, fenceName, enableStatus);
}
@PutMapping("/{fenceId}/enable")
public void enableFence(@PathVariable Long fenceId) {
fenceService.enableFence(fenceId);
}
@PutMapping("/{fenceId}/disable")
public void disableFence(@PathVariable Long fenceId) {
fenceService.disableFence(fenceId);
}
}
8.测试与验证
使用Postman等工具进行接口的测试和验证。
###
POST http://localhost:8080/system/fence/update
###
GET http://localhost:8080/system/fence/search
###
PUT http://localhost:8080/system/fence/{{fenceId}}/enable
###
PUT http://localhost:8080/system/fence/{{fenceId}}/disable
希望大家都能在在实际项目中开发高效、可靠的功能。欢迎大家提问和交流