西南交通大学智能监测 培训课程练习4

news/2024/11/29 0:52:31/

2023.056.07和09培训

项目实战

 

目录

 一、infracore(基础核心层)

1.1database

1.2config

1.3util

二、业务领域模块

 2.1structure模块

2.1.1domain层

2.1.2application层

2.1.3adapter层

2.2sensor模块

2.2.1domian层

2.2.2application层

2.2.3adapter层


 一、infracore(基础核心层)

编写整个项目中全部通用的部分,包括:数据库操作、配置类、工具类(随机数、随机ID生成器、格式校验器)、缓存配置......

1.1database

Mysql包:

具体模块包(一个数据表对应一个模块)

        DO数据容器(与数据表一一对应)

        Mapper(Mybatis或plus操作数据库的SQL)

        MapperEnum(字段枚举类)

        MapperHelper(面向数据库层面的缓存服务类)

 

1.2config

 

1.3util

@Slf4j
public class SnowFlakeUtil {/*** 派号器workid:0~31* 机房datacenterid:0~31*/private static Snowflake snowflake = IdUtil.createSnowflake(1, 1);public static Long nextId() {return snowflake.nextId();}
}

二、业务领域模块

 2.1structure模块

一个业务领域一个包

structure模块下的结构:

 

 

2.1.1domain层

domain领域层:

结构物基础信息 + 系统工程管理结点信息 + 文档信息 + 安全信息 + 统计信息

把零碎的、分散的基础信息,组建成完整的专业领域

 

reader

做所有的数据库读操作,组织各个数据表的数据结构,封装成专业名词,参数校验、分页、数据封装、无效数据剔除......

 专业名词封装

//专业名词
@Data
public class Structure {private String id;      // 唯一标识private String code;     // 桥梁自定义编码-用于外连接-连接到工程结构树节点中的结构物节点上private String structureCode;   // 结构物编码-数据对接专用-TDengine超级表名需要private String structureName;   // 结构物名称private double longitude;   // 经度private double latitude;    // 纬度private String structureType;   // 结构物类型-根据数据字典:桥梁、隧道、边坡、涵洞...private String address;     // 结构物准确地址描述private long sensorCount;public static Structure generateStructure(StructureDO structureDO,long sensorCount){Structure structure = new Structure();BeanUtils.copyProperties(structureDO, structure);structure.setSensorCount(sensorCount);return  structure;}}

 

 reader编写对应方法

/*** @author: yangkx* @Title: SensorReader* @ProjectName: SwjtuPeixun* @Description:* @date: 2023-06-11 10:14*/
@Component
public class SensorReader {@Autowiredprivate SensorMapper sensorMapper;@Autowiredprivate MonitorSchemeMapper monitorSchemeMapper;//获取一座桥下面的所有传感器public List<Sensor> getAllForStructure(String structureNodeCode){LambdaQueryWrapper<SensorDO> lqw = new LambdaQueryWrapper<>();lqw.eq(SensorDO::getCode, structureNodeCode);List<SensorDO> records = sensorMapper.selectList(lqw);List<Sensor> result = new ArrayList<>();for(SensorDO record : records){String monitorSchemeId = record.getMonitorSchemeId();MonitorSchemeDO monitorScheme = monitorSchemeMapper.getById(monitorSchemeId);//专业名词Sensor sensor = Sensor.generateSensor(record, monitorScheme);//System.out.println(" " + sensor);//System.out.println(record);result.add(sensor);}return result;}}

 

writer

做所有的增删改操作

 

1)在reader包里,添加StructureCreateEntity类

添加转化为DO类的方法

@Data
public class StructureCreateEntity {private String code;     // 桥梁自定义编码-用于外连接-连接到工程结构树节点中的结构物节点上private String structureCode;   // 结构物编码-数据对接专用-TDengine超级表名需要private String structureName;   // 结构物名称private String type;   // 结构物类型-例如大桥,中桥,小桥private String level;   // 结构物级别-例如2类,1类private double longitude;   // 经度private double latitude;    // 纬度private StructureType structureType;  // 结构物类型-根据数据字典:桥梁、隧道、边坡、涵洞...//private String structureImage;    // 结构物图片路径private String fileId;     // Bimface模型文件IDprivate String address;     // 结构物准确地址描述private String structureStyle;     // 结构形式,如:150m钢筋混凝土箱型肋拱private String beginYear;     // 结构物开始服役年份private String endYear;       // 结构物结束服役年份(若有预期的,可填,没有则不填)private String structureDescribe;   // 结构物描述private double bimLatitude;    // BIM三维地图坐标经度private double bimLongitude;    // BIM三维地图坐标纬度private double bimRotation;   // BIM三维地图坐标旋转角度系数private double bimHigh;      // BIM三维地图坐标高度public StructureDO toStructureDO(){StructureDO structureDO = new StructureDO();BeanUtils.copyProperties(this, structureDO);return structureDO;}
}

2) 回到database包里,在structure里新建StructureType类

public enum StructureType {BRIDGE("桥梁"),TUNNEL("隧道"),CULVERT("涵洞");private final  String value;StructureType(String value){this.value = value;}public String value(){return value;}public static StructureType parseType(String type) throws Exception{switch (type){case "桥梁":return StructureType.BRIDGE;case "隧道":return StructureType.TUNNEL;case "涵洞":return StructureType.CULVERT;default:throw new Exception("工程结构结点类型解析失败");}}}

3)修改StructureService  添加create方法

public void create(CreateInDTO param) throws Exception{structureWriter.create(param.toEntity());}

4)为writer添加相应方法

@Component
public class StructureWriter {@Autowiredprivate StructureMapper structureMapper;public boolean create(StructureCreateEntity entity) throws Exception {int insertResult = structureMapper.insert(entity.toStructureDO());if(insertResult != 1)throw new Exception("插入失败!");return true;}public boolean uploadImage(String structureNodeCode,String url) throws Exception {int var = structureMapper.uploadImageUrl(structureNodeCode, url);if(var != 1)throw new Exception("插入失败!");return true;}}

 

5)修改applivation层里的StructureService 

        添加方法

public boolean create(CreateInDTO param) throws Exception{boolean var = structureWriter.create(param.toEntity());return var;
}public boolean uploadImage(String structureNodeCode, MultipartFile file) throws Exception{//1.判断文件有效if(file == null)throw new Exception("上传的文件异常");//2.先判断这个结构物存不存在if(structureNodeCode == null || "".equals(structureNodeCode))throw  new Exception("输入结构物为空");Structure structure = structureReader.getByNodeCode(structureNodeCode);if(structure == null)throw new Exception("结构物不存在");//3.file上传到文件服务器String url = fileToHost(file);if(url == null || "".equals(url))throw new Exception("文件上传失败");boolean flag = structureWriter.uploadImage(structureNodeCode, url);return flag;
}private String fileToHost(MultipartFile file){System.out.println("文件正在上传到服务器");StringBuilder builder = new StringBuilder();builder.append("image").append(Math.random() * 1000000).append(".png");return builder.toString();}

 

 6)转到adapter里 修改controller 进行测试

 

 

2.1.2application层

应用服务层: 编写具体的业务逻辑

        event:领域时间驱动,发布器和处理器

        DTO:Data Transfer Object

        service:具体执行的业务逻辑,不关心数据,只管用

 

 StructureService:structure的业务操作

@Service
public class StructureService {@Autowiredprivate StructureReader structureReader;public StructureOutDTO getByNodeCode(QueryParamInDTO param) throws Exception {if(!param.isValid())return null;Structure structure = structureReader.getByNodeCode(param.getStructureNodeCode());System.out.println(" " + structure);System.out.println("原始经纬度:" + structure.getLatitude() + "  " + structure.getLongitude());//开始经纬度偏离业务 模拟switch(param.getIdentify()){case "超级管理员":System.out.println("超级管理员 经纬度:" + structure.getLatitude() + "  " + structure.getLongitude());break;case "普通管理员":double random = Math.random();double rate = (random - 0.5) / (double)100;structure.setLatitude(structure.getLatitude() * (1D + rate));structure.setLongitude(structure.getLongitude() * (1D + rate));System.out.println("普通管理员 经纬度:" + structure.getLatitude() + "  " + structure.getLongitude());break;case "用户":double random2 = Math.random();double rate2 = ((random2 - 0.5) / (double)100) * 2;structure.setLatitude(structure.getLatitude() * (1D + rate2));structure.setLongitude(structure.getLongitude() * (1D + rate2));System.out.println("用户 经纬度:" + structure.getLatitude() + "  " + structure.getLongitude());break;default:break;}StructureOutDTO structureOutDTO = StructureOutDTO.generate(structure, param.getIdentify());return structureOutDTO;}}

QueryParamInDTO:封装查询参数

@Data
public class QueryParamInDTO {private String structureNodeCode;private String identify="用户";public QueryParamInDTO(String structureNodeCode, String identify) {this.structureNodeCode = structureNodeCode;this.identify = identify;}public QueryParamInDTO() {}public boolean isValid(){if(structureNodeCode == null || "".equals(structureNodeCode))return false;if(identify == null || "".equals(identify))return false;return true;}}

 

StructureOutDTO:封装数据 再次添加额外数据

@Data
public class StructureOutDTO {private String id;      // 唯一标识private String code;     // 桥梁自定义编码-用于外连接-连接到工程结构树节点中的结构物节点上private String structureCode;   // 结构物编码-数据对接专用-TDengine超级表名需要private String structureName;   // 结构物名称private double longitude;   // 经度private double latitude;    // 纬度private String structureType;   // 结构物类型-根据数据字典:桥梁、隧道、边坡、涵洞...private String address;     // 结构物准确地址描述//额外信息private long sensorCount;//再加额外数据private Date queryTime;private String userIdentify;public static StructureOutDTO generate(Structure structure,String identify){StructureOutDTO structureOutDTO = new StructureOutDTO();BeanUtils.copyProperties(structure, structureOutDTO);structureOutDTO.setUserIdentify(identify);structureOutDTO.setQueryTime(new Date(System.currentTimeMillis()));return structureOutDTO;}}

 CreateInDTO:获取数据封装转化为Entity

@Data
public class CreateInDTO {private String code;     // 桥梁自定义编码-用于外连接-连接到工程结构树节点中的结构物节点上private String structureCode;   // 结构物编码-数据对接专用-TDengine超级表名需要private String structureName;   // 结构物名称private String type;   // 结构物类型-例如大桥,中桥,小桥private String level;   // 结构物级别-例如2类,1类private double longitude;   // 经度private double latitude;    // 纬度//字符串 ---> enumprivate String structureType;   // 结构物类型-根据数据字典:桥梁、隧道、边坡、涵洞...//private String structureImage;    // 结构物图片路径private String fileId;     // Bimface模型文件IDprivate String address;     // 结构物准确地址描述private String structureStyle;     // 结构形式,如:150m钢筋混凝土箱型肋拱private String beginYear;     // 结构物开始服役年份private String endYear;       // 结构物结束服役年份(若有预期的,可填,没有则不填)private String structureDescribe;   // 结构物描述private double bimLatitude;    // BIM三维地图坐标经度private double bimLongitude;    // BIM三维地图坐标纬度private double bimRotation;   // BIM三维地图坐标旋转角度系数private double bimHigh;      // BIM三维地图坐标高度public StructureCreateEntity toEntity() throws Exception{StructureCreateEntity structureCreateEntity = new StructureCreateEntity();BeanUtils.copyProperties(this, structureCreateEntity);StructureType structureType = StructureType.parseType(this.structureType);if(structureType != null)structureCreateEntity.setStructureType(structureType);return structureCreateEntity;}}

 

2.1.3adapter层

适配器:适配客户、第三方需求

        VO:

        controller:接口开放

        anticorrosive:防腐层 用于保证这个领域application层的纯洁性

 

test1: 

 编写Controller 在网页进行测试

@RestController
@RequestMapping("/structure")
public class StructureController {@Autowiredprivate StructureService structureService;@GetMapping("/query/{structureNodeCode}")public StructureOutDTO query(@PathVariable(value = "structureNodeCode") String structureNodeCode) throws Exception {QueryParamInDTO param = new QueryParamInDTO();param.setStructureNodeCode(structureNodeCode);StructureOutDTO outDTO = structureService.getByNodeCode(param);return outDTO;}}

测试结果: 

 

test2:

修改StructureContorller

测试图片插入 

@PostMapping("/create")public boolean create(@RequestBody CreateInDTO param) throws Exception{structureService.create(param);return true;
}@GetMapping("/uploadImage/{structureNodeCode}")public boolean uploadImage(@PathVariable("structureNodeCode") String structureNodeCode) throws Exception{boolean b = structureService.uploadImage(structureNodeCode,null);return b;
}

 

测试结果

 

2.2sensor模块

模块结构同structure模块,下面的模块结构也一样,就不再细说了

 

 

2.2.1domian层

domain领域层:

结构物基础信息 + 系统工程管理结点信息 + 文档信息 + 安全信息 + 统计信息

把零碎的、分散的基础信息,组建成完整的专业领域

task1:返回封装好的sensor 

在reader包下新建entity包,新建Sensor类

Sensor类 = sensorDO + monitorSchemeDO

 在Sensor类里添加generateSensor静态方法,返回封装好的Sensor对象

/*** @author: yangkx* @Title: Sensor* @ProjectName: SwjtuPeixun* @Description:* @date: 2023-06-11 10:45*/
//专业名词类
@Data
public class Sensor {private String id = SnowFlakeUtil.nextId().toString();private String sensorId;            // 内部使用的,数据对接用的 id//private String monitorSchemeId;     // 监测方案 id,与数据字典 - 监测方案挂钩private String monitorSchemeId;     //监测方案 唯一 idprivate String monitorTypeName;         // 监测类型名private String monitorContentName;      // 监测内容名private String type;            // 一级分类,结构响应、作用...private String location;            // 位置private String sensorInstallCode;           // 设备安装代码,一般是按规范指定的传感器idprivate String componentId;             // BIM模型上的组件idprivate String sensorType;              // 传感器类型,如倾角计private String sensorName;              // 传感器名字,有需要再使用private String remark;                  // 备注public static Sensor generateSensor(SensorDO sensorDO, MonitorSchemeDO monitorSchemeDO){//sensorDO的数据Sensor sensor = new Sensor();sensor.setId(sensorDO.getId());sensor.setSensorId(sensorDO.getSensorId());sensor.setLocation(sensorDO.getLocation());sensor.setSensorInstallCode(sensorDO.getSensorInstallCode());sensor.setComponentId(sensorDO.getComponentId());sensor.setSensorType(sensorDO.getSensorType());sensor.setSensorName(sensorDO.getSensorName());sensor.setRemark(sensorDO.getRemark());//monitorSchemeDO的数据sensor.setMonitorSchemeId(monitorSchemeDO.getId());sensor.setMonitorTypeName(monitorSchemeDO.getMonitorTypeName());sensor.setMonitorContentName(monitorSchemeDO.getMonitorContentName());sensor.setType(monitorSchemeDO.getType());//返回封装好的对象return sensor;}
}

 测试专业名词

1)Reader里编写对应方法

@Component
public class SensorReader {@Autowiredprivate SensorMapper sensorMapper;@Autowiredprivate MonitorSchemeMapper monitorSchemeMapper;//获取一座桥下面的所有传感器public List<Sensor> getAllForStructure(String structureNodeCode){LambdaQueryWrapper<SensorDO> lqw = new LambdaQueryWrapper<>();lqw.eq(SensorDO::getCode, structureNodeCode);List<SensorDO> records = sensorMapper.selectList(lqw);List<Sensor> result = new ArrayList<>();for(SensorDO record : records){String monitorSchemeId = record.getMonitorSchemeId();MonitorSchemeDO monitorScheme = monitorSchemeMapper.getById(monitorSchemeId);//专业名词Sensor sensor = Sensor.generateSensor(record, monitorScheme);//System.out.println(" " + sensor);//System.out.println(record);result.add(sensor);}return result;}}

2)test类调用reader里的方法

@Component
public class TestClass {@Autowiredprivate StructureReader structureReader;@Autowiredprivate SensorReader sensorReader;@PostConstructprivate void init(){//structureReader.getAll();sensorReader.getAllForStructure("1609494584646307840");}}

 3)运行结果

 

2.2.2application层

应用服务层: 编写具体的业务逻辑

        event:领域时间驱动,发布器和处理器

        DTO:Data Transfer Object

        service:具体执行的业务逻辑,不关心数据,只管用

 

@Service
public class SensorService {@Autowiredprivate SensorReader sensorReader;public void getForStructure(String structureNodeCode){List<Sensor> records = sensorReader.getAllForStructure(structureNodeCode);return;}}

 

2.2.3adapter层

适配器:适配客户、第三方需求

        VO:

        controller:接口开放

        anticorrosive:防腐层 用于保证这个领域application层的纯洁性

 


http://www.ppmy.cn/news/329115.html

相关文章

【OpenCV】识别轮廓,画外接正矩形,保存图片

主要函数&#xff1a; findContours drawContours findContours(resultingCVMat, layerContours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); Mat imageContoursMat::zeros(resultingCVMat.size(),CV_8UC1); for (int n 0;n < layerContours.size();n) {qDebug()<<"…

mysql8查看大事务

文章目录 1、查看大事务的原因2、构建测试数据3、模拟大事务场景4、查询mysql的事务5、查询大事务的详情 1、查看大事务的原因 大事务的特点是执行时间长&#xff0c;长期占有锁不释放&#xff0c;导致其他想操作同一行数据的线程阻塞&#xff0c;如果客户端设置了超时时间&am…

4年功能庸庸碌碌,进阶自动化测试拿到了24k,测试之路不再平凡...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 手工测试如何进阶…

Vulnhub靶机渗透:MY FILE SERVER: 1

MY FILE SERVER: 1 nmap扫描端口扫描服务扫描漏洞扫描选择渗透方向 21/2121 ftp445 samba2049/20048 nfs80 http目录爆破 获得立足点提权4061140847 获取flag 靶机链接: https://www.vulnhub.com/entry/my-file-server-1,432/ 靶机IP&#xff1a;192.168.54.33 kali IP&#x…

解压密码忘记了怎么办

压缩包带有密码&#xff0c;想要解压文件就必须要输入压缩包密码才能解压出文件的。 所以建议大家&#xff0c;在给压缩包加密之后&#xff0c;一定要设置简单的密码或者是记住密码、或者把密码记录在一个地方。一个压缩包名对应一个密码&#xff0c;这样以后就算忘记了密码&a…

有了面容解锁忘记了锁屏密码

现在的苹果手机&#xff0c;大多数都是指纹解锁或者面容解锁了&#xff0c;可是苹果还是保留着密码锁&#xff0c;一般手机重启&#xff0c;面容或指纹解锁次数过多的时候需要输入密码才能解锁手机&#xff0c;对于不经常用到的屏幕密码忘记了就不方便了。 使用okfone 苹果解锁…

IDEA安装 激活 基本使用

什么是IDEA IDAE前程Intellij IDEA,是用于Java语言开发的集成环境&#xff0c;他是业界公认的目前用于Java程序开发的最好工具。 IDEA下载安装 官网&#xff1a;https://www.jetbrains.com/idea/ 官网页面点击Download 社区版免费但阉割&#xff0c;专业版可免费使用30天学…

JavaMail学习笔记(七)、帐号激活与忘记密码 实例

一、帐户激活 在很多时候&#xff0c;在某些网站注册一个用户之后&#xff0c;网站会给这个用户注册时填写的email地址发送一封帐户激活邮件&#xff0c;这封邮件的内容就是一个激活帐户的链接和一段简短的文字描述&#xff0c;如果用户没有去邮箱将帐户激活&#xff0c;可能在…