service
- service.impl
- CategoryServiceImpl
- DataServiceImpl
- DataTableManagerServiceImpl
- FeatureManageServiceImpl
- FieldManagementServiceImpl
- FileServiceImpl
- IndicatorManagementServiceImpl
- IndicatorServiceImpl
- LogServiceImpl
- NodesServiceImpl
- NoticeServiceImpl
- PageServiceImpl
- StatisticaldDataImpl
- TableDataServiceImpl
- TableDescribeServiceImpl
- TableManagerServiceImpl
- TableServiceImpl
- TaskServiceImpl
- UserLogServiceImpl
- UserServiceImpl
service.impl
CardioTrainServiceImpl
这段代码定义了一个名为 `CardioTrainServiceImpl` 的 Service 实现类,用于对心血管训练实体 `CardioTrain` 的数据进行操作。接下来我将详细解释代码中每个部分的含义:
1. 导入了必要的类,包括了 Spring 的 `Service` 注解、MyBatis Plus 的 `ServiceImpl` 类、实体类 `CardioTrain`、Service 接口 `CardioTrainService` 以及对应的 Mapper 接口 `CardioTrainMapper`。
2. 注释部分:提供了该 Service 实现类的作者、描述、创建日期。
3. `@Service` 注解:标注该类为 Spring 的 Service 组件,用于在应用程序中进行组件扫描和依赖注入。
4. `public class CardioTrainServiceImpl extends ServiceImpl<CardioTrainMapper, CardioTrain> implements CardioTrainService`:定义了一个 Service 实现类 `CardioTrainServiceImpl`,继承了 MyBatis Plus 提供的 `ServiceImpl` 类,并指定了泛型参数为 `CardioTrainMapper` 和 `CardioTrain`,表示该 Service 操作的实体类和对应的 Mapper 接口。
5. `@Autowired private CardioTrainMapper cardioTrainMapper;`:使用 Spring 的依赖注入功能,将 `CardioTrainMapper` 接口的实例注入到 `cardioTrainMapper` 字段中,方便在类内部使用 Mapper 接口进行数据库操作。
6. `public List<CardioTrain> getAll() {...}`:定义了一个名为 `getAll` 的方法,用于获取所有心血管训练信息。在方法内部,调用了 `cardioTrainMapper` 的 `selectList` 方法查询数据库中的心血管训练信息,并返回查询结果。
通过这个 Service 实现类,可以方便地对心血管训练实体的数据进行操作,包括获取所有心血管训练信息等功能。整体设计简洁明了,符合 Spring 的规范,适合用于在应用程序中处理业务逻辑和数据操作。
package com.cqupt.software_1.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.software_1.entity.CardioTrain;
import com.cqupt.software_1.service.CardioTrainService;
import com.cqupt.software_1.mapper.CardioTrainMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author hp
* @description 针对表【cardio_train】的数据库操作Service实现
* @createDate 2023-05-16 16:16:01
*/
@Service
public class CardioTrainServiceImpl extends ServiceImpl<CardioTrainMapper, CardioTrain>
implements CardioTrainService{
@Autowired
private CardioTrainMapper cardioTrainMapper;
@Override
public List<CardioTrain> getAll() {
List<CardioTrain> cardioTrains = cardioTrainMapper.selectList(null);
return cardioTrains;
}
}
Category2ServiceImpl
这段代码中定义了一个名为 `Category2ServiceImpl` 的 Service 实现类,用于对 Category2Entity 类型的数据进行操作,并实现了 `Category2Service` 接口中定义的方法。下面我将逐个介绍代码中每个部分的功能:
1. 导入了必要的类,包括了 Spring 的 `Service` 注解、MyBatis Plus 的 `ServiceImpl` 类、实体类 `Category2Entity`、Service 接口 `Category2Service` 以及对应的 Mapper 接口 `Category2Mapper`。
2. 注释部分:使用 `TODO` 标记表示待办事项,可能是希望未来对该模块进行扩展或补充。
3. `@Service` 注解:标注该类为 Spring 的 Service 组件,用于在应用程序中进行组件扫描和依赖注入。
4. `public class Category2ServiceImpl extends ServiceImpl<Category2Mapper, Category2Entity> implements Category2Service`:定义了一个 Service 实现类 `Category2ServiceImpl`,继承了 MyBatis Plus 提供的 `ServiceImpl` 类,并指定了泛型参数为 `Category2Mapper` 和 `Category2Entity`,表示该 Service 操作的实体类和对应的 Mapper 接口。
5. `@Autowired private Category2Mapper dataManagerMapper;` 和 `@Autowired private Category2Mapper category2Mapper;`:使用 Spring 的依赖注入功能,将 `Category2Mapper` 接口的实例注入到 `dataManagerMapper` 和 `category2Mapper` 字段中,以便在类内部进行数据库操作。
6. `public List<Category2Entity> getCategory() {...}`:定义了一个名为 `getCategory` 的方法,用于获取目录行程的树形结构数据,并在内部对数据进行处理,返回处理后的结果。
7. `public List<Category2Entity> getCategory2() {...}`:定义了一个名为 `getCategory2` 的方法,类似于 `getCategory`,但在处理后将顶层以下所有元素设置为叶子节点。
8. `private List<Category2Entity> getSecondLevelChildren(String parentId) {...}`:定义了一个名为 `getSecondLevelChildren` 的私有方法,用于获取指定父节点下的第二层目录数据。
9. `@Override public void removeNode(String id) {...}`:实现了 `Category2Service` 接口中定义的移除节点操作,调用 `category2Mapper` 的 `removeNode` 方法来删除指定 id 的节点。
10. `private List<Category2Entity> getCatChildren(Category2Entity level1Cat, List<Category2Entity> categoryEntities) {...}`:定义了一个名为 `getCatChildren` 的私有方法,用于递归获取指定一级目录下的所有子结构数据,并返回处理后的子结构数据列表。
通过这个 Service 实现类,可以方便地处理目录行程数据的结构化处理和数据操作,适用于构建具有树形结构展示和操作需求的场景。整体设计较为复杂,但提供了丰富的数据处理和操作方法,能够满足较为复杂的业务逻辑需求。
package com.cqupt.software_1.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.software_1.entity.Category2Entity;
import com.cqupt.software_1.mapper.Category2Mapper;
import com.cqupt.software_1.service.Category2Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
// TODO 公共模块新增类
@Service
public class Category2ServiceImpl extends ServiceImpl<Category2Mapper, Category2Entity>
implements Category2Service {
@Autowired
Category2Mapper dataManagerMapper;
@Autowired
Category2Mapper category2Mapper;
@Override
public List<Category2Entity> getCategory() {
// 获取所有目录行程树形结构
List<Category2Entity> categoryEntities = dataManagerMapper.selectList(null);
// 获取所有级结构
List<Category2Entity> treeData = categoryEntities.stream().filter((Category2Entity) -> {
return Category2Entity.getParentId().equals("0") && Category2Entity.getIsDelete()==0;
}).map((level1Cat) -> {
level1Cat.setChildren(getCatChildren(level1Cat, categoryEntities));;
return level1Cat;
}).collect(Collectors.toList());
return treeData;
}
@Override
public List<Category2Entity> getCategory2() {
// 获取所有目录行程树形结构
List<Category2Entity> categoryEntities = dataManagerMapper.selectList(null);
// 获取所有级结构
List<Category2Entity> treeData = categoryEntities.stream().filter((Category2Entity) -> {
return Category2Entity.getParentId().equals("0") && Category2Entity.getIsDelete()==0;
}).map((level1Cat) -> {
level1Cat.setChildren(getSecondLevelChildren(level1Cat.getId()));;
return level1Cat;
}).collect(Collectors.toList());
// 顶层以下都变为叶子结点
for (Category2Entity treeDatum : treeData) {
for (Category2Entity child : treeDatum.getChildren()) {
child.setIsLeafs(1);
}
}
return treeData;
}
// 获取第二层目录
private List<Category2Entity> getSecondLevelChildren(String parentId) {
// 获取所有第二层目录
List<Category2Entity> secondLevelCategories = dataManagerMapper.selectList(null).stream()
.filter(Category2Entity -> Category2Entity.getParentId().equals(parentId) && Category2Entity.getIsDelete() == 0)
.map(level2Cat -> {
level2Cat.setChildren(new ArrayList<>()); // 第二层目录没有子目录
return level2Cat;
})
.collect(Collectors.toList());
return secondLevelCategories;
}
@Override
public void removeNode(String id) {
category2Mapper.removeNode(id);
}
// 获取1级目录下的所有子结构
private List<Category2Entity> getCatChildren(Category2Entity level1Cat, List<Category2Entity> categoryEntities) {
List<Category2Entity> children = categoryEntities.stream().filter((CategoryEntity) -> {
return CategoryEntity.getParentId().equals(level1Cat.getId()) && CategoryEntity.getIsDelete()==0; // 获取当前分类的所有子分类
}).map((child) -> {
// 递归设置子分类的所有子分类
child.setChildren(getCatChildren(child, categoryEntities));
return child;
}).collect(Collectors.toList());
return children;
}
}
Category2ServiceImpl
这段代码是一个服务实现类 `Category2ServiceImpl`,通过实现 `Category2Service` 接口来提供分类目录的相关功能。
1. `Category2ServiceImpl` 类继承了 `ServiceImpl<Category2Mapper, Category2Entity>`,表明它是一个基于 MyBatis-Plus 的 service 实现类。
2. `getCategory()` 方法用于获取所有的分类目录并构建成树形结构。首先从数据库中查询所有的目录信息,然后根据父目录为 "0"(即顶层目录)并且未被删除的条件过滤出一级目录,在此基础上通过递归方式构建子目录的树形结构,最后返回完整的树形数据。
3. `getCategory2()` 方法与 `getCategory()` 类似,不同之处在于获取第二层目录结构时调用了 `getSecondLevelChildren()` 方法,并且在最后将所有非顶层目录设置为叶子结点。
4. `getSecondLevelChildren()` 方法用于获取指定父目录下的所有第二层子目录,根据指定的 parentId 进行过滤,同时确保子目录未被删除,并将每个子目录设置为叶子结点。
5. `removeNode(String id)` 方法用于删除指定 id 的节点,实际调用了 `category2Mapper` 的 `removeNode()` 方法进行删除操作。
6. `getCatChildren()` 方法用于获取指定一级目录下的所有子目录结构,通过递归方式构建完整的子目录树形结构。首先根据指定一级目录的 id 进行过滤,然后递归获取每个子目录的子目录,最终返回完整的子目录结构。
package com.cqupt.software_1.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.software_1.entity.Category2Entity;
import com.cqupt.software_1.mapper.Category2Mapper;
import com.cqupt.software_1.service.Category2Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
// TODO 公共模块新增类
@Service
public class Category2ServiceImpl extends ServiceImpl<Category2Mapper, Category2Entity>
implements Category2Service {
@Autowired
Category2Mapper dataManagerMapper;
@Autowired
Category2Mapper category2Mapper;
@Override
public List<Category2Entity> getCategory() {
// 获取所有目录行程树形结构
List<Category2Entity> categoryEntities = dataManagerMapper.selectList(null);
// 获取所有级结构
List<Category2Entity> treeData = categoryEntities.stream().filter((Category2Entity) -> {
return Category2Entity.getParentId().equals("0") && Category2Entity.getIsDelete()==0;
}).map((level1Cat) -> {
level1Cat.setChildren(getCatChildren(level1Cat, categoryEntities));;
return level1Cat;
}).collect(Collectors.toList());
return treeData;
}
@Override
public List<Category2Entity> getCategory2() {
// 获取所有目录行程树形结构
List<Category2Entity> categoryEntities = dataManagerMapper.selectList(null);
// 获取所有级结构
List<Category2Entity> treeData = categoryEntities.stream().filter((Category2Entity) -> {
return Category2Entity.getParentId().equals("0") && Category2Entity.getIsDelete()==0;
}).map((level1Cat) -> {
level1Cat.setChildren(getSecondLevelChildren(level1Cat.getId()));;
return level1Cat;
}).collect(Collectors.toList());
// 顶层以下都变为叶子结点
for (Category2Entity treeDatum : treeData) {
for (Category2Entity child : treeDatum.getChildren()) {
child.setIsLeafs(1);
}
}
return treeData;
}
// 获取第二层目录
private List<Category2Entity> getSecondLevelChildren(String parentId) {
// 获取所有第二层目录
List<Category2Entity> secondLevelCategories = dataManagerMapper.selectList(null).stream()
.filter(Category2Entity -> Category2Entity.getParentId().equals(parentId) && Category2Entity.getIsDelete() == 0)
.map(level2Cat -> {
level2Cat.setChildren(new ArrayList<>()); // 第二层目录没有子目录
return level2Cat;
})
.collect(Collectors.toList());
return secondLevelCategories;
}
@Override
public void removeNode(String id) {
category2Mapper.removeNode(id);
}
// 获取1级目录下的所有子结构
private List<Category2Entity> getCatChildren(Category2Entity level1Cat, List<Category2Entity> categoryEntities) {
List<Category2Entity> children = categoryEntities.stream().filter((CategoryEntity) -> {
return CategoryEntity.getParentId().equals(level1Cat.getId()) && CategoryEntity.getIsDelete()==0; // 获取当前分类的所有子分类
}).map((child) -> {
// 递归设置子分类的所有子分类
child.setChildren(getCatChildren(child, categoryEntities));
return child;
}).collect(Collectors.toList());
return children;
}
}
CategoryServiceImpl
1. **CategoryServiceImpl类**:这是一个服务实现类,实现了CategoryService接口,用于处理分类相关的业务逻辑。
2. **getCategory()方法**:这个方法用于获取所有的分类信息,包括树形结构。首先从数据库中获取所有的分类实体列表,然后根据父子关系构建树形结构。同时,这个方法还过滤掉已删除的分类信息,并将"公共数据集"放在树形结构的最后。
3. **removeNode(String id)方法**:这个方法用于删除指定id的节点(即分类)。在执行删除操作之前,它记录了用户的操作日志,包括操作时间、用户名和操作类型。然后调用categoryMapper的removeNode方法执行删除操作。
4. **addParentDisease(String diseaseName)方法**:这个方法用于添加一个父病种分类。首先创建一个新的CategoryEntity实体对象,然后记录用户的操作日志,包括操作时间、用户名和操作类型。最后调用categoryMapper的insert方法将新的分类信息插入数据库。
5. **getCatChildren(CategoryEntity level1Cat, List<CategoryEntity> categoryEntities)方法**:这个方法用于获取指定一级分类下的所有子分类。它接收一个一级分类实体对象和所有分类实体的列表作为参数,然后根据父子关系过滤出当前一级分类的所有子分类,并递归地设置子分类的子分类,最终返回子分类列表。
整个类的目的是提供对分类信息的增删查改操作,并在需要时记录用户的操作日志。
package com.cqupt.software_1.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.software_1.common.UserThreadLocal;
import com.cqupt.software_1.entity.CategoryEntity;
import com.cqupt.software_1.entity.UserLog;
import com.cqupt.software_1.mapper.CategoryMapper;
import com.cqupt.software_1.service.CategoryService;
import com.cqupt.software_1.service.UserLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
// TODO 公共模块新增类
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, CategoryEntity>
implements CategoryService {
@Autowired
CategoryMapper dataManagerMapper;
@Autowired
CategoryMapper categoryMapper;
@Autowired
UserLogService userLogService;
@Override
public List<CategoryEntity> getCategory() {
// 获取所有目录行程树形结构
List<CategoryEntity> categoryEntities = dataManagerMapper.selectList(null);
// 获取所有级结构
List<CategoryEntity> treeData = categoryEntities.stream().filter((categoryEntity) -> {
return categoryEntity.getParentId().equals("0") && categoryEntity.getIsDelete()==0;
}).map((level1Cat) -> {
level1Cat.setChildren(getCatChildren(level1Cat, categoryEntities));;
return level1Cat;
}).collect(Collectors.toList());
List<CategoryEntity> publicData = treeData.stream().filter(categoryEntity -> {
return categoryEntity.getLabel().equals("公共数据集");
}).collect(Collectors.toList());
if(publicData!=null && publicData.size()>0){
treeData.remove(publicData.get(0));
treeData.add(publicData.get(0));
}
return treeData;
}
@Override
public void removeNode(String id) {
UserLog userLog = new UserLog();
userLog.setOpTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
userLog.setUsername(UserThreadLocal.get().getUsername());
userLog.setUid(UserThreadLocal.get().getUid());
userLog.setOpType("删除病种数据信息");
userLogService.save(userLog);
categoryMapper.removeNode(id);
}
@Override
public void addParentDisease(String diseaseName) {
CategoryEntity categoryEntity = new CategoryEntity(null, 1, diseaseName, "0", 0, 0, "" + diseaseName, 0, 0, null);
UserLog userLog = new UserLog();
userLog.setOpTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
userLog.setUsername(UserThreadLocal.get().getUsername());
userLog.setUid(UserThreadLocal.get().getUid());
userLog.setOpType("添加新病种");
userLogService.save(userLog);
categoryMapper.insert(categoryEntity);
}
// 获取1级目录下的所有子结构
private List<CategoryEntity> getCatChildren(CategoryEntity level1Cat, List<CategoryEntity> categoryEntities) {
List<CategoryEntity> children = categoryEntities.stream().filter((categoryEntity) -> {
return categoryEntity.getParentId().equals(level1Cat.getId()) && categoryEntity.getIsDelete()==0; // 获取当前分类的所有子分类
}).map((child) -> {
// 递归设置子分类的所有子分类
child.setChildren(getCatChildren(child, categoryEntities));
return child;
}).collect(Collectors.toList());
return children;
}
}
DataServiceImpl
这段代码是一个Java类,位于`com.cqupt.software_1.service.impl`包中,名为`DataServiceImpl`。该类实现了一个接口`DataService`。在这个类中,有一个注入`DataMapper`的实例,用于数据访问。这个类中包含了两个方法:
1. `selectListById(Set<Integer> satisfiedSamples, String tableName)`方法:这个方法接收一个`Set<Integer>`类型的参数`satisfiedSamples`和一个`String`类型的参数`tableName`。它调用`dataMapper`的`selectListById`方法来查询满足条件的样本列表,并返回一个包含Map对象的列表。这些Map对象代表数据库中对应于满足条件的样本的记录。
2. `getBarCoordinates(String tableName, String field)`方法:这个方法接收两个`String`类型的参数`tableName`和`field`。它调用`dataMapper`的`getBarCoordinates`方法来获取指定表和字段的柱状坐标数据。返回一个包含`BarCoordinate`对象的`ArrayList`,其中`BarCoordinate`对象表示柱状图中的坐标点。
package com.cqupt.software_1.service.impl;
import com.cqupt.software_1.entity.BarCoordinate;
import com.cqupt.software_1.mapper.DataMapper;
import com.cqupt.software_1.service.DataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Service
public class DataServiceImpl implements DataService {
@Autowired
private DataMapper dataMapper;
@Override
public List<Map<String, Object>> selectListById(Set<Integer> satisfiedSamples, String tableName) {
return dataMapper.selectListById(satisfiedSamples,tableName);
}
@Override
public ArrayList<BarCoordinate> getBarCoordinates(String tableName, String field) {
ArrayList<BarCoordinate> coordinates = dataMapper.getBarCoordinates(tableName,field);
return coordinates;
}
}
DataTableManagerServiceImpl
这段代码是一个Java服务实现类,实现了`DataTableManagerService`接口。首先导入了所需的包,并标注了`@Service`注解,表示这是一个Spring的服务类。
1. `upalldata()`函数:从数据库中获取所有数据表的信息并返回。
2. `deletename(String tablename)`函数:根据传入的表名删除数据库中对应的表。
3. `upname()`函数:从数据库中获取所有表名并返回。
4. `getTableData(String tableId, String tableName)`函数:根据传入的表名,从数据库中获取该表的数据并返回。
5. `updateDataTable(String table_name,String disease)`函数:根据传入的表名和疾病信息,计算样本数和特征数,并将相关信息插入数据库中的`data_table`表。
6. `calculateFeatureNumber(String tableName)`函数:根据表名,计算该表的特征数。
7. `calculateSampleSize(String tableName)`函数:根据表名,计算该表的样本数。
这些函数主要用于数据库操作,包括获取数据、删除表、获取表名、获取表数据以及更新表信息等。同时,代码中使用了JDBC连接数据库,并在每个函数中实现了异常处理逻辑。
package com.cqupt.software_1.service.impl;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.software_1.common.DataTable;
import com.cqupt.software_1.mapper.DataTableManagerMapper;
import com.cqupt.software_1.service.DataTableManagerService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@Service
public class DataTableManagerServiceImpl extends ServiceImpl<DataTableManagerMapper,DataTable> implements DataTableManagerService {
String dbUrl = "jdbc:mysql://10.16.48.219:3306/medical?characterEncoding=utf-8";
String dbUsername = "root";
String dbPassword = "111111";
@Resource
private DataTableManagerMapper dataTableManagerMapper;
@Override
public List<DataTable> upalldata() {
return dataTableManagerMapper.upalldata();
}
@Override
public void deletename(String tablename) {
dataTableManagerMapper.deletetablename(tablename);
}
@Override
public List<String> upname() {
return dataTableManagerMapper.upname();
}
@Override
public List<Map<String, Object>> getTableData(String tableId, String tableName) {
List<Map<String, Object>> tableData = dataTableManagerMapper.getTableData(tableName);
return tableData;
}
@Override
public void updateDataTable(String table_name,String disease) {
// 在这里实现计算样本数和特征数的逻辑
int featurenumber = calculateFeatureNumber(table_name);
int samplesize = calculateSampleSize(table_name);
// 创建一个新的数据对象
DataTable dataTableEntity = new DataTable();
dataTableEntity.setTable_name(table_name);
dataTableEntity.setFeaturenumber(featurenumber);
dataTableEntity.setSamplesize(samplesize);
// dataTableEntity.setTableType("Your Table Type"); // 替换为表类型信息
dataTableEntity.setDisease(disease); // 替换为疾病信息
dataTableEntity.setCreator("杨星"); // 替换为创建者信息
// 插入新样本数据到data_table表中
dataTableManagerMapper.insertDataTable(dataTableEntity);
}
private int calculateFeatureNumber(String tableName) {
try {
// 建立数据库连接
Connection connection = DriverManager.getConnection(dbUrl, dbUsername, dbPassword);
Statement statement = connection.createStatement();
// 查询表头
String query = "SELECT * FROM " +"`"+tableName+"`" + " LIMIT 1";
ResultSet resultSet = statement.executeQuery(query);
int featureNumber = resultSet.getMetaData().getColumnCount();
// 关闭连接
resultSet.close();
statement.close();
connection.close();
return featureNumber;
} catch (Exception e) {
// 处理异常情况
e.printStackTrace();
return 0; // 或者抛出异常
}
}
// 计算样本数的方法
private int calculateSampleSize(String tableName) {
try {
// 建立数据库连接
Connection connection = DriverManager.getConnection(dbUrl, dbUsername, dbPassword);
Statement statement = connection.createStatement();
// 查询数据行数
String query = "SELECT COUNT(*) AS rowCount FROM " + "`"+tableName+"`";
ResultSet resultSet = statement.executeQuery(query);
int rowCount = 0;
if (resultSet.next()) {
rowCount = resultSet.getInt("rowCount");
}
// 关闭连接
resultSet.close();
statement.close();
connection.close();
// 减去表头行数(假设第一行是表头)
return rowCount - 1;
} catch (Exception e) {
// 处理异常情况
e.printStackTrace();
return 0; // 或者抛出异常
}
}
// @Override
// public boolean save(DataTable dataTable) {
// return false;
// }
//
// @Override
// public boolean saveBatch(Collection<DataTable> collection, int i) {
// return false;
// }
//
// @Override
// public boolean saveOrUpdateBatch(Collection<DataTable> collection) {
// return false;
// }
//
// @Override
// public boolean saveOrUpdateBatch(Collection<DataTable> collection, int i) {
// return false;
// }
//
// @Override
// public boolean removeById(Serializable serializable) {
// return false;
// }
//
// @Override
// public boolean removeByMap(Map<String, Object> map) {
// return false;
// }
//
// @Override
// public boolean remove(Wrapper<DataTable> wrapper) {
// return false;
// }
//
// @Override
// public boolean removeByIds(Collection<? extends Serializable> collection) {
// return false;
// }
//
// @Override
// public boolean updateById(DataTable dataTable) {
// return false;
// }
//
// @Override
// public boolean update(DataTable dataTable, Wrapper<DataTable> wrapper) {
// return false;
// }
//
// @Override
// public boolean updateBatchById(Collection<DataTable> collection, int i) {
// return false;
// }
//
// @Override
// public boolean saveOrUpdate(DataTable dataTable) {
// return false;
// }
//
// @Override
// public DataTable getById(Serializable serializable) {
// return null;
// }
//
// @Override
// public Collection<DataTable> listByIds(Collection<? extends Serializable> collection) {
// return null;
// }
//
// @Override
// public Collection<DataTable> listByMap(Map<String, Object> map) {
// return null;
// }
//
// @Override
// public DataTable getOne(Wrapper<DataTable> wrapper, boolean b) {
// return null;
// }
//
// @Override
// public Map<String, Object> getMap(Wrapper<DataTable> wrapper) {
// return null;
// }
//
// @Override
// public Object getObj(Wrapper<DataTable> wrapper) {
// return null;
// }
//
// @Override
// public long count(Wrapper<DataTable> wrapper) {
// return 0;
// }
//
// @Override
// public List<DataTable> list(Wrapper<DataTable> wrapper) {
// return null;
// }
//
// @Override
// public IPage<DataTable> page(IPage<DataTable> iPage, Wrapper<DataTable> wrapper) {
// return null;
// }
//
// @Override
// public List<Map<String, Object>> listMaps(Wrapper<DataTable> wrapper) {
// return null;
// }
//
// @Override
// public List<Object> listObjs(Wrapper<DataTable> wrapper) {
// return null;
// }
//
// @Override
// public IPage<Map<String, Object>> pageMaps(IPage<DataTable> iPage, Wrapper<DataTable> wrapper) {
// return null;
// }
}
FeatureManageServiceImpl
这段代码是一个Java类,用于实现特征管理服务。让我逐个函数和接口详细介绍一下:
1. `FeatureManageServiceImpl` 类:
- 这是特征管理服务的实现类。
- 通过 `ServiceImpl` 类来实现 MyBatis-Plus 提供的通用服务。
- 该类标注了 `@Service` 注解,表明它是一个服务类,会被Spring框架管理。
2. `getFeatureList` 方法:
- 该方法用于获取特征列表。
- 参数 `belongType` 表示特征所属类型。
- 首先通过 `featureManageMapper` 查询数据库中的特征信息。
- 然后将查询结果封装成 `FeatureVo` 对象列表,并返回。
3. `insertFeatures` 方法:
- 该方法用于插入特征信息。
- 参数 `featureListVo` 是包含特征信息的对象。
- 首先从 `featureListVo` 中获取特征信息,并封装成 `FeatureEntity` 对象列表。
- 该方法目前被标注为作废方法,不需要实现。
这段代码中还有一些 `TODO` 注释,表示需要进一步完善的部分,比如特征的中文解释、类型等信息。
package com.cqupt.software_1.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.software_1.entity.FeatureEntity;
import com.cqupt.software_1.mapper.FeatureManageMapper;
import com.cqupt.software_1.service.FeatureManageService;
import com.cqupt.software_1.vo.FeatureClassVo;
import com.cqupt.software_1.vo.FeatureListVo;
import com.cqupt.software_1.vo.FeatureVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
// TODO 公共模块新增类
@Service
public class FeatureManageServiceImpl extends ServiceImpl<FeatureManageMapper, FeatureEntity> implements FeatureManageService {
@Autowired
FeatureManageMapper featureManageMapper;
@Override
public List<FeatureVo> getFeatureList(String belongType) {
List<FeatureEntity> featureEntities = featureManageMapper.selectFeatures(belongType);
//封装vo
ArrayList<FeatureVo> featureVos = new ArrayList<>();
for (FeatureEntity featureEntity : featureEntities) {
FeatureVo featurevVo = new FeatureVo();
featurevVo.setCharacterId(featureEntity.getCharacterId());
featurevVo.setChName(featureEntity.getChName());
featurevVo.setFeatureName(featureEntity.getFeatureName());
featurevVo.setUnit(featureEntity.getUnit());
//TODO 封装字段是否离散 离散就是discrete 连续就是continuous
//TODO 如果离散就封装取值 连续就是封装范围
featureVos.add(featurevVo);
}
return featureVos;
}
@Override
public void insertFeatures(FeatureListVo featureListVo) {
// 封装对象信息
List<FeatureClassVo> tableHeaders = featureListVo.getTableHeaders();
ArrayList<FeatureEntity> featureEntities = new ArrayList<>();
for (FeatureClassVo tableHeader : tableHeaders) {
FeatureEntity featureEntity = new FeatureEntity();
featureEntity.setChName(null);// TODO 特征中文解释
featureEntity.setFeatureName(tableHeader.getFieldName());
featureEntity.setUnit("character varying"); // TODO 特征类型
featureEntity.setDiseaseStandard(false);
if(tableHeader.getIsDiagnosis()=="1") featureEntity.setDiagnosis(true);
if(tableHeader.getIsPathology()=="1") featureEntity.setPathology(true);
if(tableHeader.getIsExamine()=="1") featureEntity.setExamine(true);
if(tableHeader.getIsLabel()=="1") featureEntity.setLabel(true);
if(tableHeader.getIsVitalSigns()=="1") featureEntity.setVitalSigns(true);
featureEntities.add(featureEntity);
}
// TODO 作废方法,不需要完成
}
}
FieldManagementServiceImpl
这段代码是另一个 Java 类,用于实现字段管理服务。让我逐个函数和接口详细介绍一下:
1. `FieldManagementServiceImpl` 类:
- 这是字段管理服务的实现类。
- 通过 `ServiceImpl` 类来实现 MyBatis-Plus 提供的通用服务。
- 该类标注了 `@Service` 注解,表明它是一个服务类,会被 Spring 框架管理。
2. `getFieldsByType` 方法:
- 该方法用于根据字段类型获取字段列表。
- 参数 `indexEnNames` 是一个包含字段英文名的列表。
- 调用 `fieldManagementMapper` 的 `getFieldsByType` 方法来查询指定类型的字段信息,并返回结果。
3. `getFiledByDiseaseName` 方法:
- 该方法用于根据疾病名称获取字段列表。
- 参数 `diseaseName` 表示疾病名称。
- 调用 `fieldManagementMapper` 的 `getFiledByDiseaseName` 方法来查询与指定疾病相关的字段信息,并返回结果。
4. `updateFieldsByDiseaseName` 方法:
- 该方法用于更新特定疾病名称相关的字段。
- 参数 `diseaseName` 表示疾病名称,`fields` 是一个包含要更新的字段名的列表。
- 调用 `fieldManagementMapper` 的 `updateFieldsByDiseaseName` 方法来更新指定疾病名称相关的字段信息。
这段代码中同样存在 `TODO` 注释,表示需要进一步完善的部分,比如新增类的信息。
package com.cqupt.software_1.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.software_1.entity.FieldManagementEntity;
import com.cqupt.software_1.mapper.FieldManagementMapper;
import com.cqupt.software_1.service.FieldManagementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
// TODO 公共模块新增类
@Service
public class FieldManagementServiceImpl extends ServiceImpl<FieldManagementMapper, FieldManagementEntity> implements FieldManagementService {
@Autowired
FieldManagementMapper fieldManagementMapper;
@Override
public List<FieldManagementEntity> getFieldsByType(List<String> indexEnNames) {
return fieldManagementMapper.getFieldsByType(indexEnNames);
}
@Override
public List<FieldManagementEntity> getFiledByDiseaseName(String diseaseName) {
List<FieldManagementEntity> res = fieldManagementMapper.getFiledByDiseaseName(diseaseName);
return res;
}
@Override
public void updateFieldsByDiseaseName(String diseaseName, List<String> fields) {
fieldManagementMapper.updateFieldsByDiseaseName(diseaseName, fields);
}
}
FileServiceImpl
这段代码是一个基于Spring框架的文件上传服务实现。让我逐步解释:
1. `FileServiceImpl` 类实现了 `FileService` 接口,该接口定义了文件上传的方法。
2. `fileUpload` 方法用于处理文件上传。它接受一个 `MultipartFile` 对象,表示上传的文件,以及一个新的表名 `newName` 和一个疾病名 `disease`。
3. 在 `fileUpload` 方法中,首先检查上传的文件是否是 CSV 格式,如果不是则抛出异常。
4. 接着从上传的 CSV 文件中读取数据,处理表头,去除空格,并保存处理后的数据行。
5. 然后,通过 JDBC 连接数据库,创建新表并插入数据。表名由参数 `newName` 决定,表结构和数据由上传的 CSV 文件确定。
6. 插入数据时,采用批处理方式,每 1000 条数据执行一次批处理,以提高效率。
7. 最后,调用 `dataTableManagerService` 的方法更新数据表,传入新创建的表名和疾病名。
8. 返回一个 `UploadResult` 对象,其中包含上传结果的相关信息,如表名、表头等。
整个过程实现了从上传文件到数据库插入数据的流程,同时保证了代码的健壮性和效率。
这段代码是用Java编写的,主要功能是生成SQL插入语句和创建数据库表。让我来逐个介绍每个函数和接口的作用:
1. `generateInsertQuery` 函数:
- 输入参数:表名 `tableName` 和列名数组 `columnNames`。
- 返回值:生成的SQL插入语句。
- 作用:根据传入的表名和列名数组,动态生成带有占位符 `?` 的SQL插入语句,用于向数据库表中插入数据。
2. `createTable` 函数:
- 输入参数:数据库连接 `connection`、表名 `tableName`、表头列表 `tableHeaders`、行数据列表 `rows`。
- 作用:根据传入的表名、表头列表和行数据列表,动态生成创建表的SQL语句,并通过数据库连接执行该语句创建表。
3. `determineColumnType` 函数:
- 输入参数:列名 `columnName`、行数据列表 `rows`、表头列表 `tableHeaders`。
- 返回值:根据数据类型判断的数据库列类型。
- 作用:根据传入的列名、行数据列表和表头列表,判断该列的数据类型(整数、浮点数、日期等),并返回相应的数据库列类型(INT、DOUBLE、DATE、VARCHAR)。
在这些函数中,使用了 `StringBuilder` 来拼接SQL语句,避免了字符串连接操作的性能消耗。另外,还用到了异常处理机制来处理数据类型转换可能出现的异常,确保程序的稳定性和可靠性。
package com.cqupt.software_1.service.impl;
import com.cqupt.software_1.common.UploadResult;
import com.cqupt.software_1.service.DataTableManagerService;
import com.cqupt.software_1.service.FileService;
import com.opencsv.CSVReader;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.List;
@Service
public class FileServiceImpl implements FileService {
@Resource
private DataTableManagerService dataTableManagerService;
@Value("${spring.datasource.url}")
private String dbUrl;
@Value("${spring.datasource.username}")
private String dbUsername;
@Value("${spring.datasource.password}")
private String dbPassword;
@Override
@Transactional
public UploadResult fileUpload(MultipartFile file, String newName, String disease) throws IOException {
System.out.println(dbUrl);
System.out.println(dbUsername);
System.out.println(dbPassword);
System.out.println("文件名字" + file.getOriginalFilename());
if (!file.getOriginalFilename().endsWith(".csv")) {
throw new IllegalArgumentException("Only CSV files are supported.");
}
String tableName = newName;
List<String> tableHeaders;
List<String[]> rows = new ArrayList<>(); // 存储处理后的数据行
try (CSVReader csvReader = new CSVReader(new InputStreamReader(file.getInputStream()))) {
String[] columnNames = csvReader.readNext();
//去空格
tableHeaders = new ArrayList<>();
for (int i = 0; i < columnNames.length; i++) {
String columnName = columnNames[i].trim();
if (!columnName.isEmpty()) {
tableHeaders.add(columnName);
}
}
String[] tableHeadersArray = tableHeaders.toArray(new String[0]);
System.out.println("表头:" + tableHeaders);
// 读取数据行并删除空表头对应的整列数据
String[] row;
while ((row = csvReader.readNext()) != null) {
String[] newRow = new String[tableHeaders.size()];
int newIndex = 0;
for (int i = 0; i < row.length; i++) {
if (!columnNames[i].trim().isEmpty()) {
newRow[newIndex++] = row[i];
}
}
rows.add(newRow);
}
System.out.println("rows: "+rows);
try (Connection connection = DriverManager.getConnection(dbUrl, dbUsername, dbPassword)) {
createTable(connection, tableName, tableHeaders, rows);
String insertQuery = generateInsertQuery(tableName, tableHeadersArray);
System.out.println(insertQuery);
int batchCount = 0;
for (String[] data : rows) {
batchCount++;
try (PreparedStatement statement = connection.prepareStatement(insertQuery)) {
for (int i = 0; i < data.length; i++) {
// 去除列名中的空格
String columnName = tableHeaders.get(i).trim();
statement.setString(i + 1, data[i]);
}
statement.addBatch();
if (batchCount % 1000 == 0) {
statement.executeBatch();
}
statement.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException("Failed to insert data into the database.", e);
}
}
} catch (SQLException e) {
throw new RuntimeException("Failed to create table or establish connection to the database.", e);
}
} catch (IOException e) {
throw new RuntimeException("Failed to read CSV file.", e);
}
dataTableManagerService.updateDataTable(tableName,disease);
// return tableName;
// 创建并返回UploadResult对象
UploadResult result = new UploadResult();
result.setTableName(tableName);
result.setTableHeaders(tableHeaders);
result.setCode(200);
return result;
}
private String generateInsertQuery(String tableName, String[] columnNames) {
StringBuilder sb = new StringBuilder();
sb.append("INSERT INTO ");
sb.append("`"); // 添加反引号(`)开始包围列名
sb.append(tableName);
sb.append("`"); // 添加反引号(`)结束包围列名
sb.append(" (");
for (int i = 0; i < columnNames.length; i++) {
sb.append("`"); // 添加反引号(`)开始包围列名
sb.append(columnNames[i]);
sb.append("`"); // 添加反引号(`)结束包围列名
if (i < columnNames.length - 1) {
sb.append(", ");
}
}
sb.append(") VALUES (");
for (int i = 0; i < columnNames.length; i++) {
sb.append("?");
if (i < columnNames.length - 1) {
sb.append(", ");
}
}
sb.append(")");
return sb.toString();
}
private void createTable(Connection connection, String tableName, List<String> tableHeaders, List<String[]> rows) {
StringBuilder createTableQuery = new StringBuilder();
createTableQuery.append("CREATE TABLE ");
createTableQuery.append("`"); // 添加反引号(`)开始包围列名
createTableQuery.append(tableName);
createTableQuery.append("`"); // 添加反引号(`)结束包围列名
createTableQuery.append(" (");
for (int i = 0; i < tableHeaders.size(); i++) {
String columnName = tableHeaders.get(i);
String columnType = determineColumnType(columnName, rows,tableHeaders);
// 使用反引号包裹列名
createTableQuery.append("`").append(columnName).append("`").append(" ").append(columnType);
if (i < tableHeaders.size() - 1) {
createTableQuery.append(", ");
}
}
createTableQuery.append(")");
try (PreparedStatement statement = connection.prepareStatement(createTableQuery.toString())) {
statement.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException("Failed to create table.", e);
}
}
private String determineColumnType(String columnName, List<String[]> rows, List<String> tableHeaders) {
// 判断数据是否为整数
boolean isInt = true;
// 判断数据是否为浮点数
boolean isDouble = true;
// 判断数据是否为日期,这里假设日期格式为"yyyy-MM-dd",你可以根据实际情况修改格式
boolean isDate = true;
for (String[] row : rows) {
String data = row[tableHeaders.indexOf(columnName)];
// 判断是否为整数
try {
Integer.parseInt(data);
} catch (NumberFormatException e) {
isInt = false;
}
// 判断是否为浮点数
try {
Double.parseDouble(data);
} catch (NumberFormatException e) {
isDouble = false;
}
// 判断是否为日期
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
try {
LocalDate.parse(data, dateFormatter);
} catch (DateTimeParseException e) {
isDate = false;
}
// 如果有一行不符合整数、浮点数、或日期的格式,则退出循环
if (!isInt && !isDouble && !isDate) {
break;
}
}
// 根据判断结果返回对应的列类型
if (isInt) {
return "INT";
} else if (isDouble) {
return "DOUBLE";
} else if (isDate) {
return "DATE";
} else {
// 如果以上条件都不满足,则返回默认的VARCHAR类型,长度为255
return "VARCHAR(255)";
}
}
}
IndicatorManagementServiceImpl
这段代码是一个Java Spring Boot服务的实现部分,主要用于管理指标(Indicator)相关的操作。以下是每个函数和接口的详细介绍:
1. `IndicatorManagementServiceImpl` 类
- `getIndicators(List<String> types, String tableName)` 方法:
- 输入参数:类型列表 `types` 和表名 `tableName`
- 输出:返回一个包含 `IndicatorManageEntity` 对象的列表
- 功能:根据检查类型获取字段以及表中每一个字段的缺失率,首先根据中文名称获取值指标类型英文名,然后获取字段管理实体列表,并根据字段的特征进行处理,设置特征名称、标签、数据类型、缺失填充方法等信息,最后计算每个字段的缺失率并返回结果。
- `getIndicatorsInfo(List<IndicatorManageEntity> checkedFeats, String tableName)` 方法:
- 输入参数:已选特征列表 `checkedFeats` 和表名 `tableName`
- 输出:返回一个包含 `IndicatorsMissDataVo` 对象的列表
- 功能:根据特征名称和表名查询有效值、缺失值个数,并返回结果,用于显示指标的详细信息。
2. 内部依赖注入的组件和接口:
- `IndicatorManagementMapper`:用于操作指标管理的数据访问层接口。
- `TableDataMapper`:用于操作表数据的数据访问层接口。
- `IndicatorService`:指标服务接口,提供获取值指标类型英文名的方法。
- `FieldManagementService`:字段管理服务接口,提供获取字段信息的方法。
- `CategoryMapper`:类别映射器,用于操作类别相关数据的接口。
- `TaskMapper`:任务映射器,用于操作任务相关数据的接口。
3. `IndicatorManageEntity` 类:指标管理实体类,用于描述指标的属性和信息,如特征名称、标签、数据类型、缺失率等。
4. `IndicatorsMissDataVo` 类:指标缺失数据信息视图对象类,用于描述指标的缺失数据信息,如有效值、缺失值个数、缺失填充方法等。
1. `IndicatorManagementServiceImpl` 类
- `getIndicators(List<String> types, String tableName)` 方法:
- 输入参数:类型列表 `types` 和表名 `tableName`
- 输出:返回一个包含 `IndicatorManageEntity` 对象的列表
- 功能:根据检查类型获取字段以及表中每一个字段的缺失率,首先根据中文名称获取值指标类型英文名,然后获取字段管理实体列表,并根据字段的特征进行处理,设置特征名称、标签、数据类型、缺失填充方法等信息,最后计算每个字段的缺失率并返回结果。
- `getIndicatorsInfo(List<IndicatorManageEntity> checkedFeats, String tableName)` 方法:
- 输入参数:已选特征列表 `checkedFeats` 和表名 `tableName`
- 输出:返回一个包含 `IndicatorsMissDataVo` 对象的列表
- 功能:根据特征名称和表名查询有效值、缺失值个数,并返回结果,用于显示指标的详细信息。
2. 内部依赖注入的组件和接口:
- `IndicatorManagementMapper`:用于操作指标管理的数据访问层接口。
- `TableDataMapper`:用于操作表数据的数据访问层接口。
- `IndicatorService`:指标服务接口,提供获取值指标类型英文名的方法。
- `FieldManagementService`:字段管理服务接口,提供获取字段信息的方法。
- `CategoryMapper`:类别映射器,用于操作类别相关数据的接口。
- `TaskMapper`:任务映射器,用于操作任务相关数据的接口。
3. `IndicatorManageEntity` 类:指标管理实体类,用于描述指标的属性和信息,如特征名称、标签、数据类型、缺失率等。
4. `IndicatorsMissDataVo` 类:指标缺失数据信息视图对象类,用于描述指标的缺失数据信息,如有效值、缺失值个数、缺失填充方法等。
总体来说,这段代码实现了根据不同检查类型获取相应字段的缺失率信息,并能够查看指标的详细缺失数据信息,用于数据管理和分析。
package com.cqupt.software_1.service.impl;
import com.alibaba.fastjson.JSON;
import com.cqupt.software_1.common.MissDataCompleteMethods;
import com.cqupt.software_1.common.RunPyEntity;
import com.cqupt.software_1.common.UserThreadLocal;
import com.cqupt.software_1.entity.FieldManagementEntity;
import com.cqupt.software_1.entity.IndicatorCategory;
import com.cqupt.software_1.entity.IndicatorManageEntity;
import com.cqupt.software_1.entity.Task;
import com.cqupt.software_1.mapper.CategoryMapper;
import com.cqupt.software_1.mapper.IndicatorManagementMapper;
import com.cqupt.software_1.mapper.TableDataMapper;
import com.cqupt.software_1.mapper.TaskMapper;
import com.cqupt.software_1.service.FieldManagementService;
import com.cqupt.software_1.service.IndicatorManagementService;
import com.cqupt.software_1.service.IndicatorService;
import com.cqupt.software_1.utils.HTTPUtils;
import com.cqupt.software_1.vo.DataFillMethodVo;
import com.cqupt.software_1.vo.IndicatorsMissDataVo;
import com.cqupt.software_1.vo.IsFillVo;
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class IndicatorManagementServiceImpl implements IndicatorManagementService {
@Autowired
IndicatorManagementMapper indicatorManagementMapper;
@Autowired
TableDataMapper tableDataMapper;
@Autowired
IndicatorService indicatorService;
@Autowired
FieldManagementService fieldManagementService;
@Autowired
CategoryMapper categoryMapper;
@Autowired
private TaskMapper taskMapper;
// TODO 根据检查类型获取字段以及表中每一个字段的缺失率
@Override
public List<IndicatorManageEntity> getIndicators(List<String> types,String tableName) {
// 跟据中文名称获取值指标类型英文名
List<IndicatorCategory> categories = indicatorService.getEnName(types);
List<IndicatorManageEntity> list = new ArrayList<>();
List<String> indexEnNames = categories.stream().map(indicatorCategory -> {
return indicatorCategory.getIndicator();
}).collect(Collectors.toList());
List<FieldManagementEntity> fieldManagementEntities = fieldManagementService.getFieldsByType(indexEnNames);
for (FieldManagementEntity fieldManagementEntity : fieldManagementEntities) {
IndicatorManageEntity indicatorManageEntity = new IndicatorManageEntity();
indicatorManageEntity.setFeatureName(fieldManagementEntity.getFeatureName());
indicatorManageEntity.setLabel(fieldManagementEntity.getChName());
indicatorManageEntity.setDiscrete(fieldManagementEntity.getDiscrete());
if(fieldManagementEntity.getUnit()!=null && !fieldManagementEntity.getUnit().equals("character varying")) {
if(fieldManagementEntity.getDiscrete()!=null && fieldManagementEntity.getDiscrete()) {
indicatorManageEntity.setFeatureDataType(2); // 数字离散
indicatorManageEntity.setMissCompleteMethod("前向填充");
}
else {
indicatorManageEntity.setFeatureDataType(1); // 数字连续
indicatorManageEntity.setMissCompleteMethod("均数替换");
}
}else {
if(indicatorManageEntity.getDiscrete()!=null && indicatorManageEntity.getDiscrete()){
indicatorManageEntity.setFeatureDataType(3); // 文本数据离散
indicatorManageEntity.setMissCompleteMethod("前向填充");
}else continue; // 文本非离散 无法分析
}
if(fieldManagementEntity.getIsDemography()) {
indicatorManageEntity.setType("diagnosis");
indicatorManageEntity.setTypeCh("人口学指标");
}else if(fieldManagementEntity.getIsPhysiological()){
indicatorManageEntity.setType("vital_sign");
indicatorManageEntity.setTypeCh("生理学指标");
}else if(fieldManagementEntity.getIsSociology()){
indicatorManageEntity.setType("pathology");
indicatorManageEntity.setTypeCh("社会学指标");
}else{
indicatorManageEntity.setType("other_index");
indicatorManageEntity.setTypeCh("其他类型指标");
}
float missRate = indicatorManagementMapper.getMissRate(indicatorManageEntity.getFeatureName(),tableName); // 缺失率
indicatorManageEntity.setMissRate(missRate);
list.add(indicatorManageEntity);
}
return list;
}
@Override
public List<IndicatorsMissDataVo> getIndicatorsInfo(List<IndicatorManageEntity> checkedFeats, String tableName) {
System.out.println("------------------------");
System.out.println("tableName:"+tableName+" cheackedFeacts:"+JSON.toJSONString(checkedFeats));
// 跟据特征名称和表名查询有效值,缺失值个数
List<IndicatorsMissDataVo> indicatorsMissDataVos = new ArrayList<>();
for (IndicatorManageEntity checkedFeat : checkedFeats) {
IndicatorsMissDataVo vo = indicatorManagementMapper.getMissDataInfo(checkedFeat,tableName);
vo.setIndex(checkedFeat.getFeatureName());
vo.setMissCompleteMethod(checkedFeat.getMissCompleteMethod());
indicatorsMissDataVos.add(vo);
}
return indicatorsMissDataVos;
}
@Override
public List<Map<String,IsFillVo>> fillData(DataFillMethodVo dataFillMethodVo) {
List<IndicatorsMissDataVo> missCompleteMethod = dataFillMethodVo.getMissCompleteMethod();
List<Map<String,IsFillVo>> res = new ArrayList<>();
List<List<IsFillVo>> tempRes = new ArrayList<>();
// 调用远程算法进行缺失值补齐 传递表名称 字段名称
try
{
for (IndicatorsMissDataVo vo : missCompleteMethod) {
System.out.println("算法为:"+vo.getMissCompleteMethod());
MissDataCompleteMethods missDataCompleteMethods = new MissDataCompleteMethods();
String path = missDataCompleteMethods.methodMap.get(vo.getMissCompleteMethod());
System.out.println("路径为:"+path);
if(path==null || path.equals("")) continue;
List<String> cols = new ArrayList<>();
cols.add(vo.getIndex());
RunPyEntity runPyEntity = new RunPyEntity(dataFillMethodVo.getTableName(),path,cols, 1); // 每一列都是不同的填充算法
JsonNode jsonNode = HTTPUtils.postRequest(runPyEntity, path);
List<String> oldData = getJsonNodeData(jsonNode,"old_data"); // 不论该列是和类型都将起数据封装成String类型
List<String> new_data = getJsonNodeData(jsonNode, "new_data");
// 封装该列数据的每一行值是否是被填充的
List<IsFillVo> isFillVos = new ArrayList<>();
for (int i=0; i<new_data.size(); i++) { // 这是某一列的插补处理
IsFillVo isFillVo = new IsFillVo();
isFillVo.setColName(vo.getIndex()); // 列名
isFillVo.setValue(new_data.get(i));
if(oldData.get(i)==null|| oldData.get(i).equals("null") || oldData.get(i).equals("NaN")) isFillVo.setFlag(true);
else isFillVo.setFlag(false);
isFillVos.add(isFillVo);
}
tempRes.add(isFillVos);
}
// 将tempRes封装到res
System.out.println("tempRes = "+JSON.toJSONString(tempRes));
int colLength = tempRes.size();
int rowlength = tempRes.get(0).size();
for(int j=0; j<rowlength; j++){ // 行
// 封装一行的数据
LinkedHashMap<String, IsFillVo> map = new LinkedHashMap<>();
for(int i=0; i<colLength; i++){ // 列
map.put(tempRes.get(i).get(j).getColName(),tempRes.get(i).get(j));
}
res.add(map);
}
// 创建任务模型
Task task = new Task();
// 获取当前时间的 LocalDateTime 对象
LocalDateTime now = LocalDateTime.now();
Timestamp timestamp = Timestamp.valueOf(now);
task.setCreatetime(timestamp);
task.setDataset(dataFillMethodVo.getTableName());
List<String> featureNames = dataFillMethodVo.getMissCompleteMethod().stream().map(indicatorsMissDataVo -> {
return indicatorsMissDataVo.getIndex();
}).collect(Collectors.toList());
String str = featureNames.stream().collect(Collectors.joining(","));
task.setFeature(str); //有哪些列
task.setTargetcolumn(str);
task.setLeader(UserThreadLocal.get().getUsername());
String models = dataFillMethodVo.getMissCompleteMethod().stream().map(indicatorsMissDataVo -> {
return indicatorsMissDataVo.getMissCompleteMethod();
}).collect(Collectors.joining(","));
task.setModel(models); // 每列的插补算法
task.setTaskname("缺失值补齐");
// 跟据表名获取父节点的名称 select label from category where "id"=(select parent_id from category where label='copd')
String label = categoryMapper.setParentLabelByLabel(dataFillMethodVo.getTableName());
task.setDisease(label);
task.setUserid(UserThreadLocal.get().getUid());
task.setLeader(UserThreadLocal.get().getUsername());
taskMapper.insert(task);
}catch (Exception e){
e.printStackTrace();
}
return res;
}
private List<String> getJsonNodeData(JsonNode jsonNode,String key){
JsonNode old_data = jsonNode.get(key);
List<String> dataList = new ArrayList<>();
if (old_data.isArray()) {
for (JsonNode row : old_data) {
if (row.isArray()){
dataList.add(row.get(0).asText());
}else{
dataList.add(row.asText());
}
}
}else{
System.out.println("不是list");
}
return dataList;
}
}
IndicatorServiceImpl
这段代码是一个基于Spring框架的服务实现类,用于管理指标类别。让我逐个解释:
1. **包声明和导入语句:**
这里声明了包名和导入了所需的类,包括FastJSON用于JSON序列化,MyBatis-Plus的`ServiceImpl`类,以及相关实体类和接口。
2. **IndicatorServiceImpl类:**
这是服务接口`IndicatorService`的实现类,使用了Spring的@Service注解来标识它是一个服务类。
3. **@Autowired注解:**
用于依赖注入,自动装配`IndicatorMapper`。
4. **getIndicatorCattegory()方法:**
这个方法用于获取指标类别的树形结构数据。首先从数据库中获取所有的指标类别数据,然后通过过滤和映射操作构建出树形结构的数据,并返回。
5. **getEnName()方法:**
这个方法用于根据传入的指标类型列表获取对应的英文名称列表。
6. **getCatChildren()方法:**
这是一个私有方法,用于递归获取指定一级目录下的所有子目录。它接收一个一级目录对象和所有类别数据列表作为参数,然后通过过滤和映射操作找到该一级目录的所有子目录,并递归调用自身以获取子目录的子目录,最后返回子目录列表。
整体来说,这个类主要提供了获取指标类别数据和相关操作的功能,其中getIndicatorCattegory()方法是最主要的,它构建了指标类别的树形结构数据。
package com.cqupt.software_1.service.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.software_1.entity.CategoryEntity;
import com.cqupt.software_1.entity.IndicatorCategory;
import com.cqupt.software_1.mapper.IndicatorMapper;
import com.cqupt.software_1.service.IndicatorService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class IndicatorServiceImpl extends ServiceImpl<IndicatorMapper,IndicatorCategory> implements IndicatorService {
@Autowired
IndicatorMapper indicatorMapper;
@Override
public List<IndicatorCategory> getIndicatorCattegory() {
List<IndicatorCategory> indicatorCategories = indicatorMapper.selectList(null);
System.out.println("service========================");
System.out.println(JSON.toJSONString(indicatorCategories));
List<IndicatorCategory> treeData = indicatorCategories.stream().filter((categoryEntity) -> {
return categoryEntity.getParentId()==0;
}).map((level1Cat) -> {
level1Cat.setChildren(getCatChildren(level1Cat, indicatorCategories));;
return level1Cat;
}).collect(Collectors.toList());
return treeData;
}
@Override
public List<IndicatorCategory> getEnName(List<String> types) {
List<IndicatorCategory> enNames = indicatorMapper.getEnNames(types);
return enNames;
}
// 获取1级目录下的所有子结构
private List<IndicatorCategory> getCatChildren(IndicatorCategory level1Cat, List<IndicatorCategory> categoryEntities) {
List<IndicatorCategory> children = categoryEntities.stream().filter((categoryEntity) -> {
return categoryEntity.getParentId()==level1Cat.getId(); // 获取当前分类的所有子分类
}).map((child) -> {
// 递归设置子分类的所有子分类
child.setChildren(getCatChildren(child, categoryEntities));
return child;
}).collect(Collectors.toList());
return children;
}
}
LogServiceImpl
这段代码是另一个基于Spring框架的服务实现类,用于管理系统日志。让我逐个解释:
1. **LogServiceImpl类:**
这是服务接口`LogService`的实现类,同样使用了Spring的@Service注解标识。
2. **@Autowired注解:**
依赖注入,自动装配`LogMapper`、`UserLogMapper`和`UserMapper`。
3. **getAllLogs()方法:**
这个方法用于获取所有系统日志数据,直接调用了`logMapper`的`getAllLogs()`方法。
4. **insertLog()方法:**
这个方法用于插入系统日志。根据传入的用户ID、角色和操作,构建一个`UserLog`对象,并设置相应属性。然后通过`DateTimeFormatter`将当前时间格式化为指定格式,设置为操作时间。最后将日志对象插入到数据库中。
整体来说,这个类提供了系统日志的获取和插入功能,其中insertLog()方法用于插入新的系统日志,将用户的操作记录到数据库中。
package com.cqupt.software_1.service.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.software_1.entity.LogEntity;
import com.cqupt.software_1.entity.User;
import com.cqupt.software_1.entity.UserLog;
import com.cqupt.software_1.mapper.LogMapper;
import com.cqupt.software_1.mapper.UserLogMapper;
import com.cqupt.software_1.mapper.UserMapper;
import com.cqupt.software_1.service.LogService;
import com.jcraft.jsch.JSch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
// TODO 公共模块新增类
@Service
public class LogServiceImpl extends ServiceImpl<LogMapper, LogEntity>
implements LogService {
@Autowired
LogMapper logMapper;
@Autowired
UserLogMapper userLogMapper;
@Autowired
UserMapper userMapper;
@Override
public List<LogEntity> getAllLogs() {
return logMapper.getAllLogs();
}
public void insertLog(String uid, Integer role, String operation) {
User user = userMapper.selectByUid(Integer.parseInt(uid));
UserLog logEntity = new UserLog();
logEntity.setUid(Integer.parseInt(uid));
logEntity.setUsername(user.getUsername());
logEntity.setOpType(operation);
// 创建 DateTimeFormatter 对象,定义日期时间的格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 创建 LocalDateTime 对象,存储当前日期和时间
LocalDateTime now = LocalDateTime.now();
// 使用 formatter 格式化 LocalDateTime 对象
String formattedDate = now.format(formatter);
logEntity.setOpTime(formattedDate);
System.out.println("要插入的日志数据为:"+JSON.toJSONString(logEntity));
userLogMapper.insert(logEntity);
}
}
NodesServiceImpl
这段代码是另一个基于Spring框架的服务实现类,用于管理系统中的节点和关系数据。让我逐个解释:
1. **NodesServiceImpl类:**
这是服务接口`NodesService`的实现类,同样使用了Spring的@Service注解标识。
2. **@Autowired注解:**
依赖注入,自动装配了`NodesMapper`。
3. **getAllNodes()方法:**
这个方法用于获取所有节点数据,直接调用了`nodesMapper`的`getAllNodes()`方法。
4. **getRelationships()方法:**
这个方法用于获取所有节点之间的关系数据,直接调用了`nodesMapper`的`getRelationships()`方法。
整体来说,这个类提供了对系统中节点和节点之间关系的管理功能,其中getAllNodes()方法用于获取所有节点数据,getRelationships()方法用于获取节点之间的关系数据。
package com.cqupt.software_1.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.software_1.entity.Nodes;
import com.cqupt.software_1.entity.Relationships;
import com.cqupt.software_1.mapper.NodesMapper;
import com.cqupt.software_1.service.NodesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class NodesServiceImpl extends ServiceImpl<NodesMapper, Nodes>
implements NodesService {
@Autowired
NodesMapper nodesMapper;
@Override
public List<Nodes> getAllNodes() {
return nodesMapper.getAllNodes();
}
@Override
public List<Relationships> getRelationships() {
return nodesMapper.getRelationships();
}
}
NoticeServiceImpl
这段代码是另一个基于Spring框架的服务实现类,用于管理系统中的通知数据。让我逐个解释:
1. **NoticeServiceImpl类:**
这是服务接口`NoticeService`的实现类,同样使用了Spring的@Service注解标识。
2. **@Autowired注解:**
依赖注入,自动装配了`NoticeMapper`。
3. **allNotices()方法:**
这个方法用于获取所有通知数据,并进行分页处理。通过`PageHelper.startPage()`设置分页参数,然后调用`noticeMapper`的`selectAllNotices()`方法查询数据,最后将结果封装到PageInfo对象中返回。
4. **saveNotification()方法:**
这个方法用于保存通知数据,接收一个包含通知信息的InsertNoticeVo对象,然后调用`noticeMapper`的`saveNotification()`方法保存通知。
5. **queryNotices()方法:**
这个方法用于查询通知数据,首先创建一个QueryWrapper对象,设置按照时间字段createTime进行降序排序,然后调用`noticeMapper`的`selectList()`方法查询符合条件的通知数据。
整体来说,这个类提供了对系统中通知数据的管理功能,包括获取所有通知并进行分页处理、保存通知、以及按照条件查询通知数据。
package com.cqupt.software_1.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.software_1.entity.Notification;
import com.cqupt.software_1.entity.User;
import com.cqupt.software_1.mapper.NoticeMapper;
import com.cqupt.software_1.mapper.UserMapper;
import com.cqupt.software_1.service.NoticeService;
import com.cqupt.software_1.service.UserService;
import com.cqupt.software_1.vo.InsertNoticeVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class NoticeServiceImpl extends ServiceImpl<NoticeMapper, Notification>
implements NoticeService {
@Autowired
private NoticeMapper noticeMapper;
@Override
public PageInfo<Notification> allNotices(Integer pageNum, Integer pageSize) {
PageHelper.startPage(pageNum, pageSize);
// 返回查询结果列表
List<Notification> notifications = noticeMapper.selectAllNotices();
// 使用 PageInfo 包装查询结果,并返回
return new PageInfo<>(notifications);
}
@Override
public void saveNotification(InsertNoticeVo notification) {
noticeMapper.saveNotification(notification);
}
@Override
public List<Notification> queryNotices() {
// 创建QueryWrapper对象
QueryWrapper queryWrapper = new QueryWrapper<>();
// 设置按照时间字段createTime进行降序排序
queryWrapper.orderByDesc("update_time");
List<Notification> notifications = noticeMapper.selectList(queryWrapper);
return notifications;
}
}
PageServiceImpl
这段代码是一个用于处理通用数据库表操作的服务实现类。让我逐个解释:
1. **PageServiceImpl类:**
这是服务接口`PageService`的实现类,使用了Spring的@Service注解标识。
2. **@Autowired注解:**
依赖注入,自动装配了`PageMapper`。
3. **getInfoByTableName()方法:**
这个方法根据传入的表名参数查询数据库中该表的所有信息,并返回一个包含查询结果的List<Map<String,Object>>对象。
4. **getInfoBySelectedFiled()方法:**
这个方法根据传入的表名和字段参数查询数据库中指定字段的信息,返回一个包含查询结果的List<Map<String,Object>>对象。
整体来说,这个类提供了对系统中通用数据库表操作的功能,包括根据表名获取所有信息以及根据字段查询信息。
package com.cqupt.software_1.service.impl;
import com.cqupt.software_1.mapper.PageMapper;
import com.cqupt.software_1.service.PageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class PageServiceImpl implements PageService {
@Autowired
private PageMapper pageMapper;
@Override
public List<Map<String, Object>> getInfoByTableName(String tableName) {
List<Map<String,Object>> res = pageMapper.getInfoByTableName(tableName);
return res;
}
@Override
public List<Map<String, Object>> getInfoBySelectedFiled(String tableName, String[] params) {
List<Map<String,Object>> res = pageMapper.getInfoBySelectedFiled(tableName,params);
return res;
}
}
StatisticaldDataImpl
这段代码是用于统计数据的服务实现类。让我逐个解释:
1. **StatisticaldDataImpl类:**
这是服务接口`StatisticaldService`的实现类,同样使用了Spring的@Service注解标识。
2. **@Autowired注解:**
依赖注入,自动装配了`StatisticalDataMapper`。
3. **getStatisticaldData()方法:**
这个方法用于获取统计数据。首先从缓存中获取数据,如果缓存中有数据,则直接返回;否则,从数据库中查询统计数据。如果数据库中有数据,则将数据存入缓存,并返回查询结果,否则返回空Map。
4. **showTableTrend()方法:**
这个方法用于展示表的趋势。根据输入的日期,查询该日期之前的所有表数量,并返回结果。
5. **calculatorMissRate4Table()方法:**
这个方法用于计算每个表的缺失总数。首先获取表的总记录数,然后获取表的所有字段名,遍历所有字段,统计为null的缺失总数,并返回结果。
整体来说,这个类提供了统计数据和展示表趋势的功能,以及计算每个表的缺失总数。
package com.cqupt.software_1.service.impl;
import com.cqupt.software_1.entity.StaticData;
import com.cqupt.software_1.mapper.StatisticalDataMapper;
import com.cqupt.software_1.service.StatisticaldService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.awt.datatransfer.FlavorEvent;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class StatisticaldDataImpl implements StatisticaldService {
@Autowired
private StatisticalDataMapper statisticaldDataMapper;
@Override
public Map<String,Object> getStatisticaldData() {
// 从缓存中获取数据
List<StaticData> staticData = statisticaldDataMapper.getStaticData();
if(staticData!=null && staticData.size()>0){
HashMap<String, Object> resMap = new HashMap<>();
resMap.put("数据总量" , staticData.get(0).getAllCount());
resMap.put("指标总量" , staticData.get(0).getAllIndex());
resMap.put("总体缺失率", staticData.get(0).getAllMissRate());
resMap.put("总体有效率", staticData.get(0).getAllValidRate());
return resMap;
}
// 查询到数据库的所有的表名
List<String> tableNames = statisticaldDataMapper.getAllTableNameOfDataBase();
Map<String ,Object> resMap = new HashMap<>();
// 总的行数
Long rowCount = 0L;
// 总的列数
Long columnCount = 0L;
// 总体缺失总数
int missCount = 0;
for (String tableName : tableNames) {
Long row = statisticaldDataMapper.getCount(tableName); // 表有多少行
Long column = statisticaldDataMapper.getColumn(tableName); // 表有多少列
// 计算每个表的缺失总数
int missNum = calculatorMissRate4Table(tableName); // 表的缺失数
missCount += missNum;
rowCount += row;
columnCount += column;
}
// 总体缺失 / 总体数据
double missRateTotal = (double) missCount/(rowCount*columnCount)*100;
// 格式化两位小数
DecimalFormat decimalFormat = new DecimalFormat("0.00");
System.out.println(decimalFormat.format(missRateTotal));
resMap.put("数据总量" , rowCount);
resMap.put("指标总量" , columnCount);
resMap.put("总体缺失率", decimalFormat.format(missRateTotal));
resMap.put("总体有效率", decimalFormat.format(1 - missRateTotal));
// 保存到缓存
StaticData cacheData = new StaticData(rowCount,columnCount,Float.parseFloat(decimalFormat.format(missRateTotal)),Float.parseFloat(decimalFormat.format(1 - missRateTotal)));
// 将数据保存到缓存中
statisticaldDataMapper.saveCache(cacheData);
return resMap;
}
@Override
public int showTableTrend(LocalDate minusDays) {
// 根据当前日期查询在今天和以前的所有表数量
int num = statisticaldDataMapper.countTableBeforeDate(minusDays.toString());
return num;
}
/**
*
* 根据表名计算每个表的 缺失总数
* @param tableName
* @return
*/
private int calculatorMissRate4Table(String tableName) {
// 1. 获取表的总记录数
Long row = statisticaldDataMapper.getCount(tableName);
// 2. 根据表名获取所有的字段名字
List<String> filedNames = statisticaldDataMapper.getColumnsByTableName(tableName);
// 3. 遍历所有的字段,统计为null 的缺失总数
int missCount = 0;
for (String filedName : filedNames) {
Long missNum = statisticaldDataMapper.getColumnMissCount(tableName, filedName);
missCount += missNum;
}
return missCount;
}
}
TableDataServiceImpl
这段代码是一个Java类,实现了一个服务接口`TableDataService`,包含了一些数据表操作的方法。让我逐个解释:
1. **TableDataServiceImpl类声明**:声明了一个类`TableDataServiceImpl`,实现了`TableDataService`接口。
2. **私有变量**:
- `private volatile boolean hasError = false;`:一个私有的`boolean`类型变量,用于标记是否有错误。
3. **依赖注入**:
- `@Autowired IndicatorManagementMapper indicatorManagementMapper;`:指标管理的Mapper对象。
- `@Autowired ThreadPoolTaskExecutor taskExecutor;`:线程池的TaskExecutor对象。
- `@Autowired DataSourceTransactionManager transactionManager;`:数据源事务管理器对象。
- `@Autowired TableDataMapper tableDataMapper;`:表数据的Mapper对象。
- `@Autowired TableDescribeMapper tableDescribeMapper;`:表描述的Mapper对象。
- `@Autowired CategoryMapper categoryMapper;`:分类的Mapper对象。
- `@Autowired UserLogService userLogService;`:用户日志的服务对象。
- `@Autowired TaskService taskService;`:任务的服务对象。
- `@Autowired FieldManagementService fieldManagementService;`:字段管理的服务对象。
- `@Autowired StatisticalDataMapper statisticalDataMapper;`:统计数据的Mapper对象。
- `@Autowired IndicatorManagementService indicatorManagementService;`:指标管理的服务对象。
- `@Autowired FilterDataColMapper filterDataColMapper;`:过滤数据列的Mapper对象。
- `@Autowired FilterDataInfoMapper filterDataInfoMapper;`:过滤数据信息的Mapper对象。
4. **getTableData方法**:获取表数据的方法。
- 参数:`TableId`表ID,`tableName`表名称。
- 返回值:`List<LinkedHashMap<String, Object>>`,包含表中数据的列表。
5. **uploadFile方法**:上传文件的方法。
- 参数:`file`上传的文件,`tableName`表名称,`type`类型,`user`用户,`userId`用户ID,`parentId`父ID,`parentType`父类型,`status`状态。
- 返回值:`List<String>`,包含特征列表。
在`uploadFile`方法中,代码执行了以下操作:
- 创建`TableDescribeEntity`对象,设置相关属性。
- 创建`CategoryEntity`对象,设置相关属性。
- 插入`CategoryEntity`到数据库。
- 设置`TableDescribeEntity`的表ID并插入到数据库。
- 调用`storeTableData`方法,存储表数据。
- 保存用户日志。
- 删除统计数据的缓存。
这段代码是一个Java方法,名为`createTable`,它是一个数据库事务,用于创建表格并插入数据。让我们逐步分析它:
1. **`createTable`方法**:这是主要的方法,用于创建表和插入数据。它接受表名(`tableName`),字段列表(`characterList`),创建用户(`createUser`)和目录实体(`nodeData`)作为参数。
2. **`@Transactional(propagation = Propagation.REQUIRED)`**:这是一个注解,表明这个方法应该在一个事务中执行。如果没有现有的事务,它会创建一个新的事务。`Propagation.REQUIRED`意味着如果当前没有活动的事务,则新的事务将被开启。
3. **`getFilterDataByConditions`方法**:这个方法根据条件过滤数据,并返回一个包含筛选后数据的列表。
4. **`getBelongType`方法**:这个方法根据目录实体(`nodeData`)找到它所属的类型。
5. **`tableDataMapper.getAllTableData`方法**:这个方法根据给定的表名获取所有表数据。
6. **创建表头信息**:根据字段管理表创建新表,存储筛选后的数据。字段管理表是一个存储字段信息的表。
7. **`tableDataMapper.createTableByField`方法**:根据字段信息创建新表。
8. **数据保存**:批量将数据插入新表中。如果数据量过大,则进行分批插入以防止SQL参数溢出。
9. **保存目录信息**:创建新的目录节点信息,并将其保存到数据库中。
10. **保存表描述信息**:创建新表的描述信息,并将其保存到数据库中。
11. **保存筛选数据信息**:保存筛选数据的相关信息,包括用户ID、用户名、筛选时间等。
12. **`statisticalDataMapper.deleteCache`方法**:清除数据统计的缓存,可能是为了确保最新的数据统计信息。
这段代码的主要功能是在数据库中创建新表,并将筛选后的数据插入其中,同时记录相关的元数据和操作日志。
这段代码是一个Java类,可能是一个服务类或控制器类。让我来解释每个函数和接口的作用:
1. `getFilterDataByConditions`: 这是一个方法,根据给定的条件筛选数据。它首先从数据库中获取所有目录信息,然后找到所有符合条件的宽表节点,接着根据传入的条件列表筛选数据,并最终返回筛选结果。该方法使用了事务管理。
2. `storeTableData`: 这是另一个方法,用于将CSV文件数据存储到数据库表中。它首先解析CSV文件,获取表头信息和数据行,然后根据数据行解析字段类型,并创建表信息。最后,将数据批量插入到数据库表中。
3. `getFeatureDataType`: 这是一个私有方法,用于根据CSV文件数据获取字段类型。它遍历CSV数据的每一行和每一列,尝试将数据转换成数字类型,如果转换成功,则将字段类型设置为float8,否则设置为VARCHAR(255)。
4. `@Transactional`: 这是一个注解,用于指示该方法应该在事务中运行。
5. `@Override`: 这也是一个注解,表明该方法是对父类或接口的方法进行重写。
6. `MultipartFile`: 这是Spring框架中的一个接口,用于处理上传的文件数据。
7. `CategoryEntity`: 这可能是一个实体类,用于表示某个类别或节点的信息。
8. `UserLog`: 这可能是另一个实体类,用于记录用户操作日志。
总体而言,这段代码涉及到数据筛选、CSV文件处理和数据库操作,主要用于处理数据并记录用户操作。
这段代码是一个Java方法,其主要功能是从数据库中导出数据并填充到CSV格式的列表中。整个过程涉及获取数据、填充缺失值、生成CSV格式的数据列表,并记录用户操作日志。下面是对每个步骤和接口的详细介绍:
1. **方法定义和参数解释**:
- `exportFile` 是方法的名称,属于某个类的重写方法(由 `@Override` 标注)。
- 接受一个 `ExportFilledDataTableVo` 类型的参数 `dataFillMethodVo`,这个参数封装了导出数据时需要的各种设置和方法。
2. **获取填充数据**:
- `List<Map<String, IsFillVo>> fillData`:这行代码调用 `indicatorManagementService.fillData` 方法,传入 `dataFillMethodVo.getDataFillMethodVo()`。此方法从指标管理服务获取填充数据,每个Map代表一行数据,只包含已填充的列。
3. **获取表的所有数据**:
- `List<LinkedHashMap<String, Object>> tableData`:通过 `tableDataMapper.getAllTableData` 方法获取特定表的所有数据,传入表名 `dataFillMethodVo.getDataFillMethodVo().getTableName()`。使用 `LinkedHashMap` 保证数据的插入顺序与字段的定义顺序一致。
4. **获取表头信息**:
- `List<FieldManagementEntity> fields`:通过 `fieldManagementService.list()` 获取当前数据库表的字段管理信息,这通常包括字段名等元数据。
5. **数据整合**:
- 使用两层循环对表数据进行遍历和填充。外层循环遍历每行数据,内层循环遍历每个需要填充的字段。
- 检查每行数据中是否存在需要填充的字段,如果不存在,则从填充数据 `fillData` 中获取相应的填充值。
6. **补全每行数据**:
- 对每行数据的 `LinkedHashMap` 进行遍历,确保所有字段都存在。如果某个字段在行数据中不存在,则将其值设为空字符串。
7. **生成CSV格式的数据列表**:
- 首先构建表头,将所有字段名称用逗号分隔。
- 接着,遍历每行数据,将数据按字段顺序转换为CSV格式的字符串。
8. **记录用户操作日志**:
- 创建 `UserLog` 对象并通过 `userLogService.save(userLog)` 方法保存。这里记录了操作用户的UID、用户名、操作时间和描述。
9. **返回数据**:
- 将包含表头和所有行数据的CSV格式列表 `fileData` 返回。
此方法的设计考虑到了数据的完整性和用户操作的可追踪性,同时通过适当的数据结构保证了数据的有序性和完整性。整个过程中涉及了多个服务和组件的交互,反映了典型的企业级应用架构。
这段代码是一个Java方法,名为`featureDescAnalyze`,用于执行对特征进行描述性分析的操作。首先,它接受三个参数:`featureName`表示特征名称,`tableName`表示表名,`taskInfo`表示任务信息。
1. 首先判断特征是否在字段管理表中,如果不在,则从数据库中查询特征的数据分布情况。
2. 如果特征是离散的,它会获取该特征的不同取值,并计算每个取值的频率和占比。
3. 如果特征是非离散的,它会获取总条数、中位数、众数、均值、最小值、最大值等统计信息,并根据最大最小值划分数据段,计算每个数据段的数据量。
4. 无论特征是离散还是非离散,最后都会记录用户的操作日志。
这段代码中的函数和接口包括:
- `featureDescAnalyze(String featureName, String tableName, CreateTaskEntity taskInfo)`:主函数,接收特征名称、表名和任务信息,执行描述性分析操作。
- `getOne(QueryWrapper<FieldManagementEntity> queryWrapper)`:从字段管理表中获取特征信息。
- `indicatorManagementMapper.getFiledCount(featureName, tableName)`:从数据库中获取特征的统计信息。
- `tableDataMapper.getAllCount(tableName)`:从数据库中获取表的总记录数。
- `tableDataMapper.getDistinctValue(tableName, featureName)`:从数据库中获取特征的不同取值。
- `tableDataMapper.getCount(featureValue, tableName, featureName)`:从数据库中获取特定取值的记录数。
- `userLogService.save(userLog)`:保存用户操作日志。
这段代码是一个任务管理系统中的创建任务的功能实现代码。首先,通过调用`taskService.list(null)`获取任务列表,然后通过流式处理筛选出是否存在相同的任务。如果不存在相同的任务,则创建新任务。
在创建任务之前,设置了任务的各种属性,比如创建时间、数据集名称、特征名称等。其中,如果任务负责人为空,则从`UserThreadLocal`中获取当前用户的用户名作为任务负责人。如果任务名称为空,则将其设置为当前用户的用户名加上当前日期。
接下来,根据表名获取关联疾病的父节点名称,并将其设置为任务的疾病属性。然后将任务的结果、备注等信息设置好,最后调用`taskService.save(task)`保存任务信息。
整体而言,该代码段通过查询数据库和执行统计计算来对特征进行描述性分析,并记录用户操作日志。
整体来说,这段代码实现了根据一定条件判断任务是否存在,如果不存在则创建新任务,并设置任务的各种属性信息。
这段代码是一个Java方法,名为`featureDescAnalyze`,用于执行对某个特征进行描述性分析的操作。首先,根据输入的特征名称和表名,以及任务信息,进行一系列判断和处理。
1. `FeatureDescAnaVo featureDescAnalyze(String featureName, String tableName, CreateTaskEntity taskInfo)`方法是一个重写的方法,它接受特征名称、表名和任务信息作为参数,并返回一个特征描述分析的结果对象`FeatureDescAnaVo`。
2. 在方法内部,首先判断特征是否被字段管理表所管理,若不被管理,则通过数据库查询判断特征是离散还是非离散。
3. 如果特征是非离散的,就获取总条数、中位数、众数、均值、最小值和最大值等描述性统计信息,并调用远程方法进行处理。处理结果包括数据分段柱状图数据。
4. 如果特征是离散的,就获取不同取值的频率,并计算每个取值的数据总条数以及占比等信息。
5. 最后,记录用户操作日志,并返回特征描述分析的结果对象。
整个方法逻辑比较清晰,通过一系列判断和处理,分别处理离散和非离散的特征,并最终返回相应的描述性分析结果。
这段代码是一个Java类中的两个方法:`singleFactorAnalyze` 和 `consistencyAnalyze`。这些方法似乎是用于处理数据分析任务的。
`singleFactorAnalyze` 方法接收三个参数:tableName 表示数据表的名称,colNames 是一个包含列名的列表,taskInfo 则是一个包含任务相关信息的实体对象。该方法的主要功能是执行单因素分析任务,并返回结果。
首先,它创建一个 `RunPyEntity` 对象,并使用 `HTTPUtils.postRequest` 方法发送 POST 请求执行单因素分析任务。然后,它从返回的 JSON 结果中提取数据并将其转换为 `SingleAnalyzeVo` 对象。
接着,它检查是否存在重复的任务。如果不存在重复任务,则创建一个新的任务对象,并将相关信息设置到任务对象中,包括数据表名称、特征列名、任务负责人、备注等。最后,它将任务对象保存到数据库中,并返回单因素分析结果。
`consistencyAnalyze` 方法与 `singleFactorAnalyze` 类似,也接收三个参数,执行一致性验证任务,并返回结果。
首先,它创建一个 `RunPyEntity` 对象,并使用 `HTTPUtils.postRequest` 方法发送 POST 请求执行一致性验证任务。然后,它从返回的 JSON 结果中提取数据并将其转换为 `ConsistencyAnalyzeVo` 对象。
接着,它检查是否存在重复的任务。如果不存在重复任务,则创建一个新的任务对象,并将相关信息设置到任务对象中,包括数据表名称、特征列名、任务负责人、备注等。最后,它将任务对象保存到数据库中,并返回一致性验证结果。
这两个方法都包含了一些重复的代码,例如任务创建和重复性检查。可能考虑将这些共用的部分提取出来,以提高代码的可维护性和可读性。
这段代码是一个Java方法,名为`getTableDataByFields`,它接收两个参数:`tableName`和`featureList`。`tableName`是一个字符串,代表要查询的数据表的名称,`featureList`是一个字符串列表,包含要查询的字段名。
在方法内部,它调用了`tableDataMapper`对象的`getTableDataByFields`方法,传入表名和字段列表作为参数。这个`tableDataMapper`对象可能是一个数据访问对象(Data Access Object),用来执行数据库操作。
最后,方法返回一个`List<Map<String, Object>>`类型的对象,其中每个元素是一个Map,代表查询结果的一行数据,Map的键是字段名,值是对应字段的值。
这段代码包含了几个方法,它们用于处理数据和生成分析结果。下面是每个方法的详细介绍:
1. `getDataCount` 方法:
- 这个方法接收一个`CategoryEntity`列表作为参数。
- 它使用`tableDataMapper`对象的`getCountByName`方法来获取每个`CategoryEntity`中的标签对应的记录数。
- 然后,它将这些记录数累加起来,并返回总记录数。
2. `getConsistencyAnalyzeFromJsonNode` 方法:
- 这个方法接收一个`JsonNode`对象作为参数,该对象包含了ICC分析的结果。
- 它从`JsonNode`中提取`ICC1`和`ICC2`部分,并创建相应的`ICCVo`对象来存储这些数据。
- 最后,它将两个`ICCVo`对象添加到一个`ArrayList`中,并打印出来。
3. `getSingleAnalyzeDataFromJsonNode` 方法:
- 这个方法同样接收一个`JsonNode`对象作为参数,该对象包含了单样本分析的结果。
- 它创建一个`SingleAnalyzeVo`对象,并从`JsonNode`中提取各种统计数据,如Wilcoxon W统计量、t统计量等,并将它们设置为`SingleAnalyzeVo`对象的属性。
- 它还从`JsonNode`中提取类别的统计信息,并创建`DiscreteVo`对象来存储这些信息。
- 最后,它创建两个`ArrayList`来存储两组数据,并使用`getBinData`方法来生成非离散数据分布的区间。
4. `getBinData` 方法:
- 这个方法接收一个`List<Double>`和一个`int`作为参数,用于指定数据和分箱的数量。
- 它首先对数据进行排序,然后找到最大值和最小值,并计算分箱的间隔。
- 然后,它遍历每个分箱,计算每个分箱中的数据点数量,并将结果存储在一个`LinkedHashMap<String, Integer>`中,其中键是分箱的描述,值是数据点数量。
1. `private boolean writeDataToCSV(List<String> data, String filePath)`: 这个方法用于将数据写入 CSV 文件。它接收一个包含字符串数据的列表和一个文件路径作为参数。在方法中,它首先创建一个 CSVWriter 对象来写入数据到文件。然后,它遍历传入的数据列表,将每行数据按逗号分割并写入文件。如果写入成功,则返回 true;如果发生 IOException,则输出错误消息并返回 false。
2. `private NotDiscrete getDataFromPy(JsonNode jsonNode)`: 这个方法从给定的 JsonNode 中获取数据并返回一个 NotDiscrete 对象。它首先从 JSON 中提取平均值、最大值、最小值、众数和中位数等数据,并将它们转换为浮点数并保留两位小数。然后,将这些数据设置到 NotDiscrete 对象中并返回。
3. `private LinkedHashMap<String,Integer> getBinData(Float max, Float min, String tableName, String featureName)`: 这个方法用于计算给定最大值和最小值之间的数据的分布情况。它将数据按照一定的区间划分,并计算每个区间内的数据量。具体地,它将数据分成六个区间,计算每个区间的起始值和结束值,并获取每个区间的数据量。最后,将起始值和结束值作为键,数据量作为值,存储在一个 LinkedHashMap 中,并返回该映射。
4. `private void getLeafNode(CategoryEntity nodeData,List<CategoryEntity> leafNodes)`: 这个方法用于获取给定节点的所有叶子节点。如果给定节点有子节点,它将递归地遍历所有子节点,直到找到叶子节点为止,并将这些叶子节点添加到传入的列表中。
5. `private CategoryEntity getBelongType(CategoryEntity nodeData, ArrayList<CategoryEntity> leafNodes)`: 这个方法用于确定给定节点所属的类型。它首先调用 `getLeafNode` 方法获取给定节点的所有叶子节点。然后,它遍历这些叶子节点,找到包含属性 `isWideTable` 值为 1 的节点,表示该节点属于宽表类型,然后返回该节点。
这些方法共同构成了一个处理和分析数据的工具集,它们可能用于生成统计报告或进行数据分析。
这段代码是一个 Java 类的部分实现,包含了一些关于表格数据管理的功能。让我来逐一解释每个函数和接口的作用:
1. `getCountByTableName(String tableName)`:这个方法用于获取指定表名的数据行数。
2. `getTableFields(String tableName)`:该方法用于获取指定表名的字段列表。
3. `getDataLikeMatch(String tableName, List<String> tableFields, String value)`:这个方法用于根据指定的表名、字段列表和值来获取类似匹配的数据。
4. `createFilterBtnTable(String tableName, List<CreateTableFeatureVo> characterList, String createUser, String status, String uid, String username, String IsFilter, String IsUpload, String uid_list,String nodeid)`:这个方法用于创建筛选按钮表格。它接收表名、特征列表、创建用户、状态、用户ID、用户名、是否筛选、是否上传、用户ID列表和节点ID作为参数。在函数内部,根据传入的参数,执行了以下步骤:
- 查询节点数据。
- 根据疾病特征列表、用户ID和节点ID获取筛选后的数据。
- 获取字段管理信息。
- 根据字段管理信息创建表头。
- 将筛选后的数据插入到新创建的表中。
- 保存目录信息。
- 保存表描述信息。
在这个函数中,注释提供了更详细的步骤说明,包括筛选数据、创建表头信息、保存创建表的数据信息、保存目录信息等。整体来说,这个函数实现了根据特定条件创建筛选后的数据表,并将相关信息保存到数据库中。
这段代码是一个 Java 类中的两个方法的实现。第一个方法是 `getFilterDataByConditionsByDieaseId`,第二个方法是 `getInfoByTableName`。我来逐一介绍它们:
### `getFilterDataByConditionsByDieaseId` 方法:
这个方法是一个公共方法,返回一个 `List`,其中包含了满足条件的数据。它接受四个参数:一个 `List<CreateTableFeatureVo>` 类型的对象列表、一个 `String` 类型的用户 ID (`uid`)、一个 `String` 类型的用户名 (`username`)、一个 `String` 类型的节点 ID (`nodeid`)。
在方法的开始处,会输出一些调试信息到控制台,然后通过调用 `categoryMapper.selectList(null)` 查询数据库中所有的目录信息,并通过 `categoryMapper.selectById(nodeid)` 查询指定节点的信息。接着,它会找到所有的宽表节点并保存在 `allWideTableNodes` 列表中。
然后,通过遍历给定的 `characterList`,将其中的数字形式的逻辑操作符(0 表示 AND,1 表示 OR,2 表示 AND NOT)转换为字符串形式。接着,处理 `characterList` 中的 `varchar` 类型的数据,给值添加单引号。
然后,创建一个 `otherWideTableData` 的列表,保存调用 `tableDataMapper.getFilterData("merge",characterList)` 方法的结果。然后,将其中的数据合并到 `res` 列表中。
接下来,会创建一个 `FilterDataInfo` 对象,并将其插入数据库中。然后,遍历 `characterList`,为每个特征创建一个 `FilterDataCol` 对象,并将其插入数据库中。
最后,返回 `res` 列表,其中包含了满足条件的数据。
### `getInfoByTableName` 方法:
这个方法是另一个公共方法,返回一个 `List`,其中包含了指定表的信息。它接受一个 `String` 类型的表名参数。
该方法调用了 `tableDataMapper.getInfoByTableName(tableName)` 方法,并返回其结果,该方法用于从数据库中获取指定表的信息。
这两个方法都涉及到数据库操作,主要是查询和插入操作,并且涉及到对传入参数的处理和转换。
package com.cqupt.software_1.service.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cqupt.software_1.common.RunPyEntity;
import com.cqupt.software_1.common.UserThreadLocal;
import com.cqupt.software_1.entity.*;
import com.cqupt.software_1.mapper.*;
import com.cqupt.software_1.service.*;
import com.cqupt.software_1.utils.HTTPUtils;
import com.cqupt.software_1.vo.*;
import com.fasterxml.jackson.databind.JsonNode;
import com.opencsv.CSVReader;
import com.opencsv.CSVWriter;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.net.URISyntaxException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;
// TODO 公共模块
@Service
public class TableDataServiceImpl implements TableDataService {
private volatile boolean hasError = false;
@Autowired
IndicatorManagementMapper indicatorManagementMapper;
@Autowired
ThreadPoolTaskExecutor taskExecutor;
@Autowired
DataSourceTransactionManager transactionManager;
@Autowired
TableDataMapper tableDataMapper;
@Autowired
TableDescribeMapper tableDescribeMapper;
@Autowired
CategoryMapper categoryMapper;
@Autowired
UserLogService userLogService;
@Autowired
TaskService taskService;
@Autowired
FieldManagementService fieldManagementService;
@Autowired
StatisticalDataMapper statisticalDataMapper;
@Autowired
IndicatorManagementService indicatorManagementService;
@Autowired
FilterDataColMapper filterDataColMapper;
@Autowired
FilterDataInfoMapper filterDataInfoMapper;
@Override
public List<LinkedHashMap<String, Object>> getTableData(String TableId, String tableName) {
List<LinkedHashMap<String, Object>> tableData = tableDataMapper.getTableData(tableName);
return tableData;
}
@Transactional(propagation = Propagation.REQUIRED) // 事务控制
@Override
public List<String> uploadFile(MultipartFile file, String tableName, String type, String user, int userId, String parentId, String parentType, String status) throws IOException, ParseException {
// 封住表描述信息
TableDescribeEntity tableDescribeEntity = new TableDescribeEntity();
tableDescribeEntity.setClassPath(parentType+"/"+type);
// 解析系统当前时间
tableDescribeEntity.setCreateTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
tableDescribeEntity.setCreateUser(user);
tableDescribeEntity.setTableName(tableName);
// 封装目录信息
CategoryEntity categoryEntity = new CategoryEntity();
categoryEntity.setLabel(tableName);
CategoryEntity parentCate = categoryMapper.selectById(parentId);
categoryEntity.setStatus(status);
categoryEntity.setCatLevel(parentCate.getCatLevel()+1);
categoryEntity.setIsCommon(parentCate.getIsCommon());
categoryEntity.setIsLeafs(1);
categoryEntity.setUid(UserThreadLocal.get().getUid().toString());
categoryEntity.setPath(parentCate.getPath()+"/"+tableName);
categoryEntity.setParentId(parentId);
categoryEntity.setIsDelete(0);
// 保存数据库
categoryMapper.insert(categoryEntity);
tableDescribeEntity.setTableId(categoryEntity.getId());
tableDescribeMapper.insert(tableDescribeEntity);
List<String> featureList = storeTableData(file, tableName);
UserLog userLog = new UserLog(null, UserThreadLocal.get().getUid(),UserThreadLocal.get().getUsername(),new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()),"数据文件上传");
userLogService.save(userLog);
statisticalDataMapper.deleteCache(); // 清除缓存
return featureList;
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void createTable(String tableName, List<CreateTableFeatureVo> characterList, String createUser, CategoryEntity nodeData) {
/**
* 筛选数据
* 查询当前目录下的宽表所有数据
* 1、查询nodeData的所有子节点,找到是宽表的节点信息(表名)
* 筛选 其他病种符合条件的所有数据
* 2、遍历所有目录信息 找到所有的宽表节点,排除上一步找到的宽表节点,使用剩下的宽表节点筛选数据
* 合并所有数据
* 创建表头信息
* 3、根据宽表的字段管理表创建一个新表,存储筛选后的数据
* 保存创建表的数据信息信息
* 4、将1、2步骤的数据插入到3创建的表中
* 保存目录信息
* 5、创建目录节点信息,并保存数据库
*
*/
List<LinkedHashMap<String, Object>> res = getFilterDataByConditions(characterList, nodeData);
CategoryEntity mustContainNode = getBelongType(nodeData, new ArrayList<CategoryEntity>());
// 查询考虑疾病的宽表数据
List<LinkedHashMap<String,Object>> diseaseData;
if(mustContainNode!=null) {
diseaseData = tableDataMapper.getAllTableData(mustContainNode.getLabel()); // 传递表名参数
}else{
diseaseData = new ArrayList<>();
}
// 合并考虑疾病和非考虑疾病的所有数据
for (LinkedHashMap<String, Object> re : res) {
diseaseData.add(re);
}
// 创建表头信息 获取宽表字段管理信息
List<FieldManagementEntity> fields = fieldManagementService.list(null);
HashMap<String, String> fieldMap = new HashMap<>();
for (FieldManagementEntity field : fields) {
fieldMap.put(field.getFeatureName(),field.getType());
}
// TODO 创建表头信息
tableDataMapper.createTableByField(tableName,fieldMap);
// TODO 数据保存 批量插入
// TODO 保证value值数量与字段个数一致
for (Map<String, Object> diseaseDatum : diseaseData) {
for (FieldManagementEntity field : fields) {
if(diseaseDatum.get(field.getFeatureName())==null)
{
diseaseDatum.put(field.getFeatureName(),null);
}
}
}
// TODO 分批插入 防止sql参数传入过多导致溢出
if(diseaseData.size()>200){
int batch = diseaseData.size()/200;
for(int i=0; i<batch; i++){
int start = i*200, end = (i+1)*200;
tableDataMapper.bachInsertData(diseaseData.subList(start,end),tableName); // diseaseData.subList(start,end) 前闭后开
}
tableDataMapper.bachInsertData(diseaseData.subList(batch*200,diseaseData.size()),tableName);
}else{
tableDataMapper.bachInsertData(diseaseData,tableName);
}
// 目录信息
// System.out.println("节点参数信息:"+JSON.toJSONString(nodeData));
CategoryEntity cat = categoryMapper.selectById(nodeData.getId());
CategoryEntity node = new CategoryEntity();
node.setIsDelete(0);
node.setParentId(nodeData.getId());
node.setPath(cat.getPath()+"/"+tableName);
node.setIsLeafs(1);
node.setIsCommon(nodeData.getIsCommon());
node.setCatLevel(nodeData.getCatLevel()+1);
node.setIsWideTable(0);
node.setLabel(tableName);
node.setStatus(nodeData.getStatus());
node.setUid(UserThreadLocal.get().getUid().toString());
node.setUsername(UserThreadLocal.get().getUsername());
node.setStatus("0");
node.setIsCommon(0);
node.setIs_filter("1");
categoryMapper.insert(node); // 保存目录信息
// 表描述信息
TableDescribeEntity tableDescribeEntity = new TableDescribeEntity();
tableDescribeEntity.setTableName(tableName);
tableDescribeEntity.setCreateUser(createUser);
tableDescribeEntity.setCreateTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
tableDescribeEntity.setClassPath(cat.getPath()+"/"+tableName);
tableDescribeEntity.setTableId(node.getId());
tableDescribeEntity.setUid(UserThreadLocal.get().getUid());
tableDescribeEntity.setTableStatus("0"); // 筛选后默认私有
// 保存表描述信息
tableDescribeMapper.insert(tableDescribeEntity);
UserLog userLog = new UserLog(null, UserThreadLocal.get().getUid(),UserThreadLocal.get().getUsername(),new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()),"筛选数据建表");
userLogService.save(userLog);
// 插入 filter_data_info 表信息
FilterDataInfo filterDataInfo = new FilterDataInfo();
filterDataInfo.setUid(UserThreadLocal.get().getUid());
filterDataInfo.setCreateUser(UserThreadLocal.get().getUsername());
filterDataInfo.setUsername(UserThreadLocal.get().getUsername());
filterDataInfo.setCateId(nodeData.getId());
filterDataInfo.setParentId(nodeData.getParentId());
filterDataInfo.setFilterTime(new Timestamp(System.currentTimeMillis())); // 时间
filterDataInfoMapper.insert(filterDataInfo);
for (CreateTableFeatureVo createTableFeatureVo : characterList) {
FilterDataCol filterDataCol = new FilterDataCol();
BeanUtils.copyProperties(createTableFeatureVo,filterDataCol);
filterDataCol.setFilterDataInfoId(filterDataInfo.getId());
FieldManagementEntity fieldManagementEntity = fieldManagementService.getOne(new QueryWrapper<FieldManagementEntity>().eq("feature_name", createTableFeatureVo.getFeatureName()));
filterDataCol.setRange(fieldManagementEntity.getRange());
filterDataColMapper.insert(filterDataCol);
}
statisticalDataMapper.deleteCache(); // 清除数据统计的缓存
}
// 根据条件筛选数据
@Transactional
@Override
public List<LinkedHashMap<String, Object>> getFilterDataByConditions(List<CreateTableFeatureVo> characterList,CategoryEntity nodeData) {
List<CategoryEntity> categoryEntities = categoryMapper.selectList(null); // 查询所有的目录信息
// 找到所有的宽表节点
List<CategoryEntity> allWideTableNodes = categoryEntities.stream().filter(categoryEntity -> {
return categoryEntity.getIsDelete()==0 && categoryEntity.getIsLeafs()==1 && categoryEntity.getIsWideTable()!=null && categoryEntity.getIsWideTable() == 1;
}).collect(Collectors.toList());
// 遍历当前节点的所有叶子节点,找到这个宽表节点
ArrayList<CategoryEntity> leafNodes = new ArrayList<>();
getLeafNode(nodeData, leafNodes);
/** 找到所有的非考虑疾病的宽表节点 **/
List<CategoryEntity> otherWideTable = null;
if(leafNodes!=null && leafNodes.size()>0){
for (CategoryEntity leafNode : leafNodes) {
if(leafNode.getIsWideTable()!=null && leafNode.getIsWideTable()==1) {
otherWideTable = allWideTableNodes.stream().filter(categoryEntity -> { // 所有的非考虑疾病的宽表节点
return !categoryEntity.getLabel().equals(leafNode.getLabel());
}).collect(Collectors.toList());
}
}
}else{
otherWideTable = allWideTableNodes;
}
if(otherWideTable==null) otherWideTable = allWideTableNodes;
// 筛选所有非考虑疾病的宽表数据
/** select * from ${tableName} where ${feature} ${computeOpt} ${value} ${connector} ... **/
// 前端传过来的 AND OR NOT 是数字形式0,1,2,需要变成字符串拼接sql
for (CreateTableFeatureVo createTableFeatureVo : characterList) {
if(createTableFeatureVo.getOpt()==null) createTableFeatureVo.setOptString("");
else if(createTableFeatureVo.getOpt()==0) createTableFeatureVo.setOptString("AND");
else if(createTableFeatureVo.getOpt()==1) createTableFeatureVo.setOptString("OR");
else createTableFeatureVo.setOptString("AND NOT");
}
// 处理varchar类型的数据
for (CreateTableFeatureVo createTableFeatureVo : characterList) {
if(createTableFeatureVo.getType()==null || createTableFeatureVo.getType().equals("character varying")){
createTableFeatureVo.setValue("'"+createTableFeatureVo.getValue()+"'");
}
}
// 依次查询每一个表中符合条件的数据
List<List<LinkedHashMap<String, Object>>> otherWideTableData = new ArrayList<>();
for (CategoryEntity wideTable : otherWideTable) {
otherWideTableData.add(tableDataMapper.getFilterData(wideTable.getLabel(),characterList)); // TODO 筛选SQl xml
}
/** 数据合并List<List<Map<String, Object>>> otherWideTableData(多张表) 合并到 List<Map<String,Object>> diseaseData(一张表) **/
ArrayList<LinkedHashMap<String, Object>> res = new ArrayList<>();
for (List<LinkedHashMap<String, Object>> otherWideTableDatum : otherWideTableData) {
for (LinkedHashMap<String, Object> rowData : otherWideTableDatum) {
res.add(rowData);
}
}
// // 插入 filter_data_info 表信息
// FilterDataInfo filterDataInfo = new FilterDataInfo();
// filterDataInfo.setUid(UserThreadLocal.get().getUid());
// filterDataInfo.setCreateUser(UserThreadLocal.get().getUsername());
// filterDataInfo.setUsername(UserThreadLocal.get().getUsername());
// filterDataInfo.setCateId(nodeData.getId());
// filterDataInfo.setParentId(nodeData.getParentId());
// filterDataInfo.setFilterTime(new Timestamp(System.currentTimeMillis())); // 时间
// filterDataInfoMapper.insert(filterDataInfo);
//
//
// ArrayList<FilterDataCol> filterDataCols = new ArrayList<>();
// for (CreateTableFeatureVo createTableFeatureVo : characterList) {
// FilterDataCol filterDataCol = new FilterDataCol();
// BeanUtils.copyProperties(createTableFeatureVo,filterDataCol);
// filterDataCol.setFilterDataInfoId(filterDataInfo.getId());
// FieldManagementEntity fieldManagementEntity = fieldManagementService.getOne(new QueryWrapper<FieldManagementEntity>().eq("feature_name", createTableFeatureVo.getFeatureName()));
// filterDataCol.setRange(fieldManagementEntity.getRange());
// filterDataColMapper.insert(filterDataCol);
// }
UserLog userLog = new UserLog(null, UserThreadLocal.get().getUid(),UserThreadLocal.get().getUsername(),new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()),"筛选数据");
userLogService.save(userLog);
return res;
}
@Transactional(propagation = Propagation.REQUIRED)
public List<String> storeTableData(MultipartFile file, String tableName) throws IOException {
ArrayList<String> featureList = null;
if (!file.isEmpty()) {
// 使用 OpenCSV 解析 CSV 文件
Reader reader = new BufferedReader(new InputStreamReader(file.getInputStream(),"UTF-8"));
CSVReader csvReader = new CSVReader(reader);
List<String[]> csvData = csvReader.readAll();
csvReader.close();
// 获取表头信息
String[] headers = csvData.get(0);
featureList = new ArrayList<String>(Arrays.asList(headers));
// 删除表头行,剩余的即为数据行
csvData.remove(0);
// 解析字段类型
String[] featureDataType = getFeatureDataType(csvData);
// 创建表信息
tableDataMapper.createTable2(headers,featureDataType, tableName);
// // 批量
// TODO 分批插入 防止sql参数传入过多导致溢出
if(csvData.size()>10000){
int batch = csvData.size()/10000;
for(int i=0; i<batch; i++){
int start = i*10000, end = (i+1)*10000;
tableDataMapper.batchInsertCsv(csvData.subList(start,end),tableName); // diseaseData.subList(start,end) 前闭后开
}
tableDataMapper.batchInsertCsv(csvData.subList(batch*10000,csvData.size()),tableName);
}else{
tableDataMapper.batchInsertCsv(csvData,tableName);
}
// TODO 改进
// int count = csvData.size();
// int pageSize = 5000;
// int threadNum = count % pageSize == 0 ? count / pageSize: count / pageSize + 1;
// CountDownLatch downLatch = new CountDownLatch(threadNum);
// long start = System.currentTimeMillis();
//
// for (int i = 0; i < threadNum; i++) {
// //开始序号
// int startIndex = i * pageSize;
// //结束序号
// int endIndex = Math.min(count, (i+1)*pageSize);
// //分割list
// List<String[]> epochData = csvData.subList(startIndex, endIndex);
//
// taskExecutor.execute(() -> {
// try {
// tableDataMapper.batchInsertCsv(epochData,tableName);
//
// }catch (Exception e){
// e.printStackTrace();
// }finally {
// //执行完后 计数
// downLatch.countDown(); // 计数器减1
// }
// });
// }
// try {
// //等待
// downLatch.await(); //等待所有的线程执行结束 当里面的数值变为0的时候主线程就不在等待
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
// long end = System.currentTimeMillis();
// System.out.println("插入数据耗费时间:"+(end-start));
}
return featureList;
}
private String[] getFeatureDataType(List<String[]> csvData) {
String[] dataType = new String[csvData.get(0).length];
for (String[] csvDatum : csvData) { //遍历每一行
for (int i=0; i<csvDatum.length; i++) { // 遍历每一列
try {
Float.parseFloat(csvDatum[i]); // 可以转成数字
}catch (Exception e){ // 不可以转成数字
dataType[i] = "VARCHAR(255)";
}
}
}
for(int i=0; i<csvData.get(0).length; i++){
if(dataType[i]==null) dataType[i]="float8";
}
return dataType;
}
// 数据填充后将数据导出csv 文件 List<String> 每一个string都是一行数据,以逗号分开
@Override
public List<String> exportFile(ExportFilledDataTableVo dataFillMethodVo){
// 获取填充的数据信息
List<Map<String, IsFillVo>> fillData = indicatorManagementService.fillData(dataFillMethodVo.getDataFillMethodVo()); // 每一个map是一行数据(只有填充的列)
// 获取这个表的所有数据
List<LinkedHashMap<String, Object>> tableData = tableDataMapper.getAllTableData(dataFillMethodVo.getDataFillMethodVo().getTableName());
// 获取表头信息
List<FieldManagementEntity> fields = fieldManagementService.list();
// 数据整合 表的所有数据有空值,使用填充后的数据替换
for(int i=0; i<tableData.size(); i++){
for (IndicatorsMissDataVo colNameVos : dataFillMethodVo.getDataFillMethodVo().getMissCompleteMethod()) {
if(!tableData.get(i).containsKey(colNameVos.getIndex())){ // 不包含这个列就说明这个是空
tableData.get(i).put(colNameVos.getIndex(),fillData.get(i).get(colNameVos.getIndex()).getValue());
}
}
}
// 每行map长度补齐
for (LinkedHashMap<String, Object> row : tableData) {
for (FieldManagementEntity field : fields) {
if(!row.containsKey(field.getFeatureName())){
row.put(field.getFeatureName(),"");
}
}
}
List<String> fileData = new ArrayList<>();
StringBuffer tableHead = new StringBuffer();
for(int i=0; i<fields.size(); i++){
if(i!=fields.size()-1){
tableHead.append(fields.get(i).getFeatureName()+",");
}else{
tableHead.append(fields.get(i).getFeatureName());
}
}
fileData.add(tableHead.toString());
for (LinkedHashMap<String, Object> rowData: tableData) {
StringBuffer temp = new StringBuffer();
for(int i=0; i<fields.size(); i++){
if(i!=fields.size()-1) {
temp.append(rowData.get(fields.get(i).getFeatureName())+",");
}else{
temp.append(rowData.get(fields.get(i).getFeatureName()));
}
}
fileData.add(temp.toString());
}
UserLog userLog = new UserLog(null, UserThreadLocal.get().getUid(),UserThreadLocal.get().getUsername(),new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()),"疾病数据文件导出");
userLogService.save(userLog);
return fileData;
}
// 对某个特征进行描述性分析
@Override
public FeatureDescAnaVo featureDescAnalyze(String featureName, String tableName,CreateTaskEntity taskInfo) throws IOException, URISyntaxException {
// 判断这个特征属于离散还是非离散
FeatureDescAnaVo featureDescAnaVo = new FeatureDescAnaVo();
FieldManagementEntity featureEntity = fieldManagementService.getOne(new QueryWrapper<FieldManagementEntity>().eq("feature_name", featureName));
if(featureEntity==null){ // 不被字段管理表管理
featureEntity = new FieldManagementEntity();
// 查询数据库判断是否离散
Map<String, Long> map= indicatorManagementMapper.getFiledCount(featureName, tableName);
if(map.get("num1")<=10 && map.get("num1")>=1 && 1.0*map.get("num1")/map.get("num2")<0.05) {
System.out.println("判断为离散");
featureEntity.setDiscrete(true);
}
else featureEntity.setDiscrete(false);
}
if(featureEntity.getDiscrete()==null || !featureEntity.getDiscrete()){ // 非离散
// 获取 总条数 中位数 众数 均值 中位数 最小值 最大值 众数
// 调用远程方法
Integer totalCount = tableDataMapper.getAllCount(tableName);
ArrayList<String> cols = new ArrayList<>();
cols.add(featureName);
RunPyEntity param = new RunPyEntity(tableName,null,cols);
JsonNode jsonNode = HTTPUtils.postRequest(param, "/notDiscreteFeatureDesc");
// 解析返回值
NotDiscrete notDiscrete = getDataFromPy(jsonNode);
/** 数据分段 柱状图数据 6个柱子 一个柱子表示一个数据范围取值的数据量 跟据最大最小值划分区间 判断类型 如果是整数就转换成整数就不保留小数, 浮点数就保留小数 **/
LinkedHashMap<String, Integer> binData = getBinData(notDiscrete.getMax(), notDiscrete.getMin(), tableName, featureName);
notDiscrete.setBinData(binData);
notDiscrete.setTotal(totalCount);
featureDescAnaVo.setNotDiscrete(notDiscrete);
featureDescAnaVo.setDiscrete(false);
}else{ // 离散
List<String> values = new ArrayList<>();
if(featureEntity.getRange() == null) { // 不被字段管理表管理
// 获取表中这个字段有哪些不同的取值
System.out.println("表名:"+tableName +" 列名:"+featureName+ " mapper:"+tableDataMapper);
Object[] res = tableDataMapper.getDistinctValue(tableName, featureName);
System.out.println("返回结果"+JSON.toJSONString(res));
for (Object re : res) values.add(re.toString());
}else{
String s = featureEntity.getRange().replace("{", "").replace("}", "");
String[] featureValues = s.split(",");
for (String featureValue : featureValues) values.add(featureValue);
}
ArrayList<DiscreteVo> discreteVos = new ArrayList<>();
// 获取数据总条数
Integer totalCount = tableDataMapper.getAllCount(tableName);
Integer validCount = 0;
for (String featureValue : values) {
DiscreteVo discreteVo = new DiscreteVo();
// 计算每个取值的数据总条数
featureValue = featureValue.trim().replace("\"", "");
System.out.println("featureValue = "+featureValue);
Integer count = tableDataMapper.getCount(featureValue,tableName,featureName);
validCount+=count;
discreteVo.setFrequent(count);
discreteVo.setTotalAmount(Float.parseFloat(String.format("%.2f",(float)count/totalCount*100))); // 累计占比
discreteVo.setVariable(featureValue);
discreteVos.add(discreteVo);
System.err.println("当前离散vo:"+discreteVo);
}
for (DiscreteVo discreteVo : discreteVos) {
discreteVo.setAmount(Float.parseFloat(String.format("%.2f",(float)discreteVo.getFrequent()/validCount*100))); // 有效值占比
}
featureDescAnaVo.setDiscrete(true);
featureDescAnaVo.setDiscreteVos(discreteVos);
}
UserLog userLog = new UserLog(null, UserThreadLocal.get().getUid(),UserThreadLocal.get().getUsername(),new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()),"疾病数据描述性分析");
userLogService.save(userLog);
//判断任务管理中是否有该任务,如果有就不在继续创建 没有就创建任务
List<Task> list = taskService.list(null);
List<Task> isRepeat = list.stream().filter(task -> {
return "描述性分析".equals(task.getTasktype()) && task.getFeature().equals(featureName) && task.getDataset().equals(tableName) && task.getTaskname().equals(taskInfo.getTaskName());
}).collect(Collectors.toList());
if(isRepeat == null || isRepeat.size() == 0){
Task task = new Task();
task.setCreatetime(new Timestamp(System.currentTimeMillis()));
task.setDataset(tableName);
task.setFeature(featureName);
String leader = taskInfo.getPrincipal();
if(leader == null || leader=="") {
System.out.println("操作人为空");
leader = UserThreadLocal.get().getUsername();
}
task.setLeader(leader);
String taskName = taskInfo.getTaskName();
if(taskName == null || taskName=="") {
System.out.println("任务名称为空");
taskName = UserThreadLocal.get().getUsername()+"_"+"描述性分析_"+ LocalDate.now().toString();
}
task.setTaskname(taskName);
task.setParticipant(taskInfo.getParticipants());
task.setTasktype(taskInfo.getTasktype()==null?"描述性分析":taskInfo.getTasktype());
// 获取关联疾病 TODO
// 跟据表名获取父节点的名称 select label from category where "id"=(select parent_id from category where label='copd')
String label = categoryMapper.getParentLabelByLabel(tableName);
task.setDisease(label);
task.setRemark(taskInfo.getTips());
task.setResult(JSON.toJSONString(featureDescAnaVo));
task.setUserid(UserThreadLocal.get().getUid());
task.setTargetcolumn(featureName);
System.out.println("插入:"+task);
taskService.save(task);
}
return featureDescAnaVo;
}
@Override
public SingleAnalyzeVo singleFactorAnalyze(String tableName, List<String> colNames,CreateTaskEntity taskInfo) throws IOException, URISyntaxException {
RunPyEntity param = new RunPyEntity(tableName,null,colNames);
JsonNode jsonNode = HTTPUtils.postRequest(param, "/singleFactorAnalyze");
SingleAnalyzeVo singleAnalyzeDataFromJsonNode = getSingleAnalyzeDataFromJsonNode(jsonNode);
List<Task> list = taskService.list(null);
List<Task> isRepeat = list.stream().filter(task -> {
return task.getTasktype().equals("单因素分析") && task.getFeature().equals(colNames.stream().collect(Collectors.joining(","))) && task.getDataset().equals(tableName) && task.getTaskname().equals(taskInfo.getTaskName());
}).collect(Collectors.toList());
if(isRepeat == null || isRepeat.size() == 0){
// 创建任务
System.err.println("开始创建任务");
Task task = new Task();
task.setCreatetime(new Timestamp(System.currentTimeMillis()));
task.setDataset(tableName);
String featureNames = colNames.stream().collect(Collectors.joining(","));
task.setFeature(featureNames);
String leader = taskInfo.getPrincipal();
if(leader == null || leader=="") {
leader = UserThreadLocal.get().getUsername();
}
task.setLeader(leader);
task.setRemark(taskInfo.getTips());
String taskName = taskInfo.getTaskName();
if(taskName == null || taskName=="") taskName = UserThreadLocal.get().getUsername()+"_"+"单因素分析_"+ LocalDate.now().toString();
task.setTaskname(taskName);
task.setParticipant(taskInfo.getParticipants());
task.setTasktype(taskInfo.getTasktype()==null?"单因素分析":taskInfo.getTasktype());
// 获取关联疾病 TODO
// 跟据表名获取父节点的名称 select label from category where "id"=(select parent_id from category where label='copd')
String label = categoryMapper.getParentLabelByLabel(tableName);
task.setDisease(label);
task.setResult(JSON.toJSONString(singleAnalyzeDataFromJsonNode));
task.setUserid(UserThreadLocal.get().getUid());
task.setTargetcolumn(colNames.get(1));
taskService.save(task);
}
return singleAnalyzeDataFromJsonNode;
}
// TODO 一致性验证
@Override
public ConsistencyAnalyzeVo consistencyAnalyze(String tableName, String featureName,CreateTaskEntity taskInfo) throws IOException, URISyntaxException {
ArrayList<String> featureNames = new ArrayList<>();
featureNames.add(featureName);
RunPyEntity param = new RunPyEntity(tableName,null,featureNames);
JsonNode jsonNode = HTTPUtils.postRequest(param, "/consistencyAnalyze");
System.out.println("返回状态码:"+jsonNode.get("code").asInt());
if(jsonNode.get("code").asInt()==500) return null;
List<ICCVo> consistencyAnalyzeFromJsonNode = getConsistencyAnalyzeFromJsonNode(jsonNode);
ConsistencyAnalyzeVo consistencyAnalyzeVo = new ConsistencyAnalyzeVo();
consistencyAnalyzeVo.setICCAnalyzeResult(consistencyAnalyzeFromJsonNode);
List<Task> list = taskService.list(null);
List<Task> isRepeat = list.stream().filter(task -> {
return task.getTasktype().equals("一致性验证") && task.getFeature().equals(featureName) && task.getDataset().equals(tableName)&&task.getTaskname().equals(taskInfo.getTaskName());
}).collect(Collectors.toList());
if(isRepeat == null || isRepeat.size() == 0) {
// 创建任务
Task task = new Task();
task.setCreatetime(new Timestamp(System.currentTimeMillis()));
task.setDataset(tableName);
task.setFeature(featureName);
String leader = taskInfo.getPrincipal();
if(leader == null || leader=="") {
leader = UserThreadLocal.get().getUsername();
}
task.setLeader(leader);
task.setRemark(taskInfo.getTips());
String taskName = taskInfo.getTaskName();
if(taskName == null || taskName=="") taskName = UserThreadLocal.get().getUsername()+"_"+"一致性验证_"+ LocalDate.now().toString();
task.setTaskname(taskName);
task.setParticipant(taskInfo.getParticipants());
task.setTasktype(taskInfo.getTasktype()==null?"一致性验证":taskInfo.getTasktype());
// 获取关联疾病 TODO
// 跟据表名获取父节点的名称 select label from category where "id"=(select parent_id from category where label='copd')
String label = categoryMapper.getParentLabelByLabel(tableName);
task.setDisease(label);
task.setModel("ICC");
task.setResult(JSON.toJSONString(consistencyAnalyzeVo));
task.setUserid(UserThreadLocal.get().getUid());
task.setTargetcolumn(featureName);
System.err.println("保存任务信息:"+task);
taskService.save(task);
}
return consistencyAnalyzeVo;
}
@Override
public List<Map<String, Object>> getTableDataByFields(String tableName, List<String> featureList) {
List<Map<String, Object>> tableData = tableDataMapper.getTableDataByFields(tableName,featureList);
return tableData;
}
@Override
public Integer getDataCount(List<CategoryEntity> categoryEntities) {
int count = 0;
for (CategoryEntity categoryEntity : categoryEntities) {
count+=tableDataMapper.getCountByName(categoryEntity.getLabel());
}
return count;
}
private List<ICCVo> getConsistencyAnalyzeFromJsonNode(JsonNode jsonNode){
JsonNode icc1 = jsonNode.get("ICC1");
JsonNode icc2 = jsonNode.get("ICC2");
ICCVo iccVo1 = new ICCVo();
ICCVo iccVo2 = new ICCVo();
iccVo1.setMethod(icc1.get("method").asText());
iccVo1.setType(icc1.get("type").asText());
iccVo1.setICC(icc1.get("ICC").asDouble());
iccVo1.setDf1(icc1.get("df1").asInt());
iccVo1.setDf2(icc1.get("df2").asInt());
iccVo1.setF(icc1.get("F").asDouble());
iccVo1.setP(icc1.get("p").asDouble());
iccVo2.setMethod(icc2.get("method").asText());
iccVo2.setType(icc2.get("type").asText());
iccVo2.setICC(icc2.get("ICC").asDouble());
iccVo2.setDf1(icc2.get("df1").asInt());
iccVo2.setDf2(icc2.get("df2").asInt());
iccVo2.setF(icc2.get("F").asDouble());
iccVo2.setP(icc2.get("p").asDouble());
ArrayList<ICCVo> iccVos = new ArrayList<>();
iccVos.add(iccVo1);
iccVos.add(iccVo2);
System.out.println("ICC:"+JSON.toJSONString(iccVos));
return iccVos;
}
private SingleAnalyzeVo getSingleAnalyzeDataFromJsonNode(JsonNode jsonNode){
SingleAnalyzeVo singleAnalyzeVo = new SingleAnalyzeVo();
singleAnalyzeVo.setWilcoxonW(jsonNode.get("w_stat").asDouble());
singleAnalyzeVo.setWilcoxonP(jsonNode.get("p_value_w").asDouble());
singleAnalyzeVo.setTT(jsonNode.get("t_stat").asDouble());
singleAnalyzeVo.setTP(jsonNode.get("p_value_t").asDouble());
singleAnalyzeVo.setCorrectTT(jsonNode.get("correct_t_stat").asDouble());
singleAnalyzeVo.setCorrectTP(jsonNode.get("correct_p_value_t").asDouble());
JsonNode classInfo = jsonNode.get("classInfo"); // 字典对象list。包含了每个类别的统计信息类别名称(className)类别总数 有效个数 缺失值个数
System.out.println("classInfo:"+JSON.toJSONString(classInfo));
ArrayList<DiscreteVo> discreteVos = new ArrayList<>();
for (JsonNode node : classInfo) {
DiscreteVo discreteVo = new DiscreteVo();
discreteVo.setVariable(node.get("className").asText());
discreteVo.setFrequent(node.get("frequent").asInt());
discreteVo.setValidFrequent(node.get("validFrequent").asInt());
discreteVo.setMissFrequent(node.get("missFrequent").asInt());
discreteVos.add(discreteVo);
}
singleAnalyzeVo.setDiscreteVos(discreteVos);
// 分类获取两组数据
ArrayList<Double> group1 = new ArrayList<>();
JsonNode group1Node = jsonNode.get("group1");
for (JsonNode node : group1Node) {
group1.add(node.asDouble());
}
ArrayList<Double> group2 = new ArrayList<>();
JsonNode group2Node = jsonNode.get("group2");
for (JsonNode node : group2Node) {
group2.add(node.asDouble());
}
// 分成六个柱状图的柱子描述数据分布区间
NotDiscrete notDiscrete1 = new NotDiscrete();
NotDiscrete notDiscrete2 = new NotDiscrete();
if(group1.size()>0) notDiscrete1.setBinData(getBinData(group1,7));
singleAnalyzeVo.setNotDiscrete(notDiscrete1);
if(group2.size()>0) notDiscrete2.setBinData(getBinData(group2,7));
singleAnalyzeVo.setNotDiscrete2(notDiscrete2);
return singleAnalyzeVo;
}
private LinkedHashMap<String,Integer> getBinData(List<Double> data,int binCount){
LinkedHashMap<String, Integer> res = new LinkedHashMap<>();
data.sort(new Comparator<Double>() {
@Override
public int compare(Double o1, Double o2) {
if(o1>o2) return 1;
else if(o1<o2) return -1;
else return 0;
}
});
// 找到最大值 最小值 分区间划分
double max = data.get(data.size()-1);
double min = data.get(0);
double gap = (max-min)/binCount;
for(int i=0; i<binCount; i++){
int count = 0;
Double end,start;
start = min + gap * i;
if(i==binCount-1) end = max;
else end = min + gap * (i+1);
for (Double datum : data) {
if(i==binCount-1){
if (datum < end && datum >= start) count++;
}else{
if (datum <= end && datum >= start) count++;
}
}
start = Double.parseDouble(String.format("%.2f", start));
end = Double.parseDouble(String.format("%.2f", end));
res.put(start+"~"+end,count);
}
return res;
}
private boolean writeDataToCSV(List<String> data, String filePath) {
try (CSVWriter writer = new CSVWriter(new FileWriter(filePath))) {
// 写入数据
for (String line : data) {
String[] parts = line.split(","); // 分割每行的数据
writer.writeNext(parts); // 写入CSV文件
}
return true;
} catch (IOException e) {
System.err.println("写入CSV文件时出现错误: " + e.getMessage());
return false;
}
}
private NotDiscrete getDataFromPy(JsonNode jsonNode){
NotDiscrete notDiscrete = new NotDiscrete();
String averageAsString = jsonNode.get("average").asText();
float average = Float.parseFloat(averageAsString);
notDiscrete.setAverage(Float.parseFloat(String.format("%.2f", average)));
notDiscrete.setMax(Float.parseFloat(jsonNode.get("max").asText()));
notDiscrete.setMin(Float.parseFloat(jsonNode.get("min").asText()));
notDiscrete.setMode(Float.parseFloat(jsonNode.get("mode").asText()));
notDiscrete.setMiddle(Float.parseFloat(jsonNode.get("middle").asText()));
notDiscrete.setTotal(jsonNode.get("middle").asInt());
return notDiscrete;
}
private LinkedHashMap<String,Integer> getBinData(Float max, Float min, String tableName, String featureName){
// 分成6个区间
float gap = (max-min)/6;
gap = Float.parseFloat(String.format("%.2f", gap));
LinkedHashMap<String, Integer> binData = new LinkedHashMap<>();
float start = min;
float end = min;
for(int i=0; i<6; i++){
start = Float.parseFloat(String.format("%.2f",min+gap*i));
if(i==5) end = max;
else {
end = Float.parseFloat(String.format("%.2f",min+gap*(i+1)));
}
// 获取每个区间的数据量
String type = null;
FieldManagementEntity fieldManagementEntity = fieldManagementService.getOne(new QueryWrapper<FieldManagementEntity>().eq("feature_name", featureName));
if(fieldManagementEntity==null) type = indicatorManagementMapper.getColType(tableName,featureName);
else type = fieldManagementEntity.getType();
if ("integer".equals(type)){
int s = (int)start;
int e = (int)end;
Integer count = tableDataMapper.getCountByCondition(String.valueOf(s),String.valueOf(e), tableName,featureName);
binData.put(start+"~"+end,count);
}else{
Integer count = tableDataMapper.getCountByCondition(String.valueOf(start),String.valueOf(end), tableName,featureName);
binData.put(start+"~"+end,count);
}
}
return binData;
}
private void getLeafNode(CategoryEntity nodeData,List<CategoryEntity> leafNodes){
if(nodeData.getChildren()!=null && nodeData.getChildren().size()>0){
for (CategoryEntity child : nodeData.getChildren()) {
if(child.getIsLeafs()!=null && child.getIsLeafs()==1) leafNodes.add(child);
else getLeafNode(child,leafNodes);
}
}
}
private CategoryEntity getBelongType(CategoryEntity nodeData, ArrayList<CategoryEntity> leafNodes){
getLeafNode(nodeData, leafNodes);
if(leafNodes!=null && leafNodes.size()>0){
for (CategoryEntity leafNode : leafNodes) {
if(leafNode.getIsWideTable()!=null && leafNode.getIsWideTable()==1) {
return leafNode;
}
}
}
return null;
}
@Override
public Integer getCountByTableName(String tableName) {
return tableDataMapper.getCountByTableName(tableName);
}
@Override
public List<String> getTableFields(String tableName) {
return tableDataMapper.getTableFields(tableName);
}
@Override
public List<LinkedHashMap<String, Object>> getDataLikeMatch(String tableName, List<String> tableFields, String value) {
return tableDataMapper.getDataByLikeMatch(tableName, tableFields, value);
}
// @Override
// public void createFilterBtnTable(String dataName, List<CreateTableFeatureVo> characterList, String createUser, String status, String uid, String username, String isFilter, String isUpload, String uidList, String nodeid) {
//
// }
@Override
public void createFilterBtnTable(String tableName, List<CreateTableFeatureVo> characterList, String createUser, String status, String uid, String username, String IsFilter, String IsUpload, String uid_list,String nodeid) {
/**
* 筛选数据
* 查询当前目录下的宽表所有数据
* 1、查询nodeData的所有子节点,找到是宽表的节点信息(表名)
* 筛选 其他病种符合条件的所有数据
* 2、遍历所有目录信息 找到所有的宽表节点,排除上一步找到的宽表节点,使用剩下的宽表节点筛选数据
* 合并所有数据
* 创建表头信息
* 3、根据宽表的字段管理表创建一个新表,存储筛选后的数据
* 保存创建表的数据信息信息
* 4、将1、2步骤的数据插入到3创建的表中
* 保存目录信息
* 5、创建目录节点信息,并保存数据库
*
*/
System.out.println("前端传递的值:"+"表名"+tableName+" userName"+username+" userId"+uid+" IsFilter"+IsFilter+" IsUpload"+" uid_list"+uid_list+" nodeID"+nodeid);
CategoryEntity nodeData = categoryMapper.selectById(nodeid);
List<LinkedHashMap<String, Object>> res = getFilterDataByConditionsByDieaseId(characterList,uid,username,nodeid);
// CategoryEntity mustContainNode = getBelongType(nodeData, new ArrayList<CategoryEntity>());
// // 查询考虑疾病的宽表数据
//List<LinkedHashMap<String,Object>> diseaseData = tableDataMapper.getAllTableData("merge"); // 传递表名参数
List<LinkedHashMap<String,Object>> diseaseData = res;
// System.out.println("考虑疾病所有数据");
// // 合并考虑疾病和非考虑疾病的所有数据
// for (LinkedHashMap<String, Object> re : res) {
// diseaseData.add(re);
// }
// 创建表头信息 获取宽表字段管理信息
List<FieldManagementEntity> fields = fieldManagementService.list(null);
// System.out.println("字段长度为:"+fields.size());
HashMap<String, String> fieldMap = new HashMap<>();
for (FieldManagementEntity field : fields) {
fieldMap.put(field.getFeatureName(),field.getUnit());
}
// TODO 创建表头信息
tableDataMapper.createTableByField(tableName,fieldMap);
// TODO 数据保存 批量插入
// TODO 保证value值数量与字段个数一致
for (Map<String, Object> diseaseDatum : diseaseData) {
for (FieldManagementEntity field : fields) {
if(diseaseDatum.get(field.getFeatureName())==null)
{
diseaseDatum.put(field.getFeatureName(),"");
}
}
// System.out.println("数据长度为:"+diseaseDatum.size());
}
System.out.println("========================================");
System.out.println("数据长度:"+diseaseData.size());
// TODO 分批插入 防止sql参数传入过多导致溢出
if(diseaseData.size()>200){
int batch = diseaseData.size()/200;
for(int i=0; i<batch; i++){
int start = i*200, end = (i+1)*200;
System.out.println("插入第"+i+"轮数据");
tableDataMapper.bachInsertData(diseaseData.subList(start,end),tableName); // diseaseData.subList(start,end) 前闭后开
}
tableDataMapper.bachInsertData(diseaseData.subList(batch*200,diseaseData.size()),tableName);
}else{
tableDataMapper.bachInsertData(diseaseData,tableName);
}
// 目录信息
CategoryEntity node = new CategoryEntity();
node.setIsDelete(0);
node.setParentId(nodeData.getId());
node.setIsLeafs(1);
node.setStatus(status);
node.setUid(uid);
node.setUsername(username);
node.setCatLevel(nodeData.getCatLevel()+1);
node.setLabel(tableName);
node.setIs_filter(IsFilter);
System.out.println(uid_list);
node.setIs_upload(IsUpload);
node.setUidList(uid_list);
System.out.println(node);
categoryMapper.insert(node); // 保存目录信息
// 表描述信息
TableDescribeEntity tableDescribeEntity = new TableDescribeEntity();
tableDescribeEntity.setTableName(tableName);
tableDescribeEntity.setCreateUser(node.getUsername());
// tableDescribeEntity.setUid(Integer.parseInt(uid));
tableDescribeEntity.setUid(UserThreadLocal.get().getUid());
tableDescribeEntity.setTableStatus(node.getStatus());
tableDescribeEntity.setCreateUser(username);
tableDescribeEntity.setCreateTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
tableDescribeEntity.setClassPath(nodeData.getLabel()+"/"+tableName);
tableDescribeEntity.setTableId(node.getId());
tableDescribeEntity.setTableSize(0.0f);
// 保存表描述信息
tableDescribeMapper.insert(tableDescribeEntity);
}
@Override
public List<LinkedHashMap<String, Object>> getFilterDataByConditionsByDieaseId(List<CreateTableFeatureVo> characterList, String uid, String username, String nodeid) {
System.out.println("历史数据筛选参数:nodeId "+nodeid +" uid "+uid+" username "+username);
List<CategoryEntity> categoryEntities = categoryMapper.selectList(null); // 查询所有的目录信息
CategoryEntity nodeData = categoryMapper.selectById(nodeid);
// 找到所有的宽表节点
List<CategoryEntity> allWideTableNodes = categoryEntities.stream().collect(Collectors.toList());
// 遍历当前节点的所有叶子节点,找到这个宽表节点
ArrayList<CategoryEntity> leafNodes = new ArrayList<>();
// getLeafNode(nodeData, leafNodes);
/** 找到所有的非考虑疾病的宽表节点 **/
List<CategoryEntity> otherWideTable = null;
if(leafNodes!=null && leafNodes.size()>0){
}else{
otherWideTable = allWideTableNodes;
}
if(otherWideTable==null) otherWideTable = allWideTableNodes;
// 筛选所有非考虑疾病的宽表数据
/** select * from ${tableName} where ${feature} ${computeOpt} ${value} ${connector} ... **/
// 前端传过来的 AND OR NOT 是数字形式0,1,2,需要变成字符串拼接sql
for (CreateTableFeatureVo createTableFeatureVo : characterList) {
if(createTableFeatureVo.getOpt()==null) createTableFeatureVo.setOptString("");
else if(createTableFeatureVo.getOpt()==0) createTableFeatureVo.setOptString("AND");
else if(createTableFeatureVo.getOpt()==1) createTableFeatureVo.setOptString("OR");
else createTableFeatureVo.setOptString("AND NOT");
}
// 处理varchar类型的数据
for (CreateTableFeatureVo createTableFeatureVo : characterList) {
if(createTableFeatureVo.getType()==null || createTableFeatureVo.getType().equals("character varying")){
createTableFeatureVo.setValue("'"+createTableFeatureVo.getValue()+"'");
}
}
List<List<LinkedHashMap<String, Object>>> otherWideTableData = new ArrayList<>();
ArrayList<LinkedHashMap<String, Object>> res = new ArrayList<>();
otherWideTableData.add(tableDataMapper.getFilterData("merge",characterList));
ArrayList<LinkedHashMap<String, Object>> res2 = new ArrayList<>();
for (List<LinkedHashMap<String, Object>> otherWideTableDatum : otherWideTableData) {
for (LinkedHashMap<String, Object> rowData : otherWideTableDatum) {
res.add(rowData);
}
}
// 插入 filter_data_info 表信息
FilterDataInfo filterDataInfo = new FilterDataInfo();
// filterDataInfo.setUid(Integer.parseInt(uid));
filterDataInfo.setUid(UserThreadLocal.get().getUid());
filterDataInfo.setCreateUser(username);
filterDataInfo.setUsername(username);
filterDataInfo.setCateId(nodeData.getId());
filterDataInfo.setParentId(nodeData.getParentId());
filterDataInfo.setFilterTime(new Timestamp(System.currentTimeMillis())); // 时间
filterDataInfoMapper.insert(filterDataInfo);
ArrayList<FilterDataCol> filterDataCols = new ArrayList<>();
for (CreateTableFeatureVo createTableFeatureVo : characterList) {
FilterDataCol filterDataCol = new FilterDataCol();
BeanUtils.copyProperties(createTableFeatureVo,filterDataCol);
filterDataCol.setFilterDataInfoId(filterDataInfo.getId());
FieldManagementEntity fieldManagementEntity = fieldManagementService.getOne(new QueryWrapper<FieldManagementEntity>().eq("feature_name", createTableFeatureVo.getFeatureName()));
filterDataCol.setRange(fieldManagementEntity.getRange());
filterDataColMapper.insert(filterDataCol);
}
return res;
}
@Override
public List<Map<String, Object>> getInfoByTableName(String tableName) {
return tableDataMapper.getInfoByTableName(tableName);
}
}
TableDescribeServiceImpl
这段代码是一个服务实现类,用于操作数据库中表的描述信息。让我逐步解释:
1. `TableDescribeServiceImpl` 类实现了 `TableDescribeService` 接口,并继承了 `ServiceImpl<TableDescribeMapper, TableDescribeEntity>`。这意味着它是一个基于 MyBatis-Plus 的服务实现类,用于处理 `TableDescribeEntity` 实体类的数据库操作。
2. 在类上标注了 `@Service` 注解,表示它是一个 Spring 的服务类。
3. `tableDescribeMapper` 属性通过 `@Autowired` 注解注入了 `TableDescribeMapper` 类型的 Bean。
4. `getColCount(String tableName)` 方法用于获取指定表名的列数,它调用了 `tableDescribeMapper` 的 `getColCount` 方法,并将表名作为参数传入。
5. `getRowCount(String tableName)` 方法用于获取指定表名的行数,类似地,它调用了 `tableDescribeMapper` 的 `getRowCount` 方法,并将表名作为参数传入。
这些方法的目的是为了提供对数据库表结构的基本信息查询功能。
package com.cqupt.software_1.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.software_1.entity.TableDescribeEntity;
import com.cqupt.software_1.mapper.TableDescribeMapper;
import com.cqupt.software_1.service.TableDescribeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
// TODO 公共模块新增类
@Service
public class TableDescribeServiceImpl extends ServiceImpl<TableDescribeMapper, TableDescribeEntity> implements TableDescribeService {
@Autowired
TableDescribeMapper tableDescribeMapper;
@Override
public Integer getColCount(String tableName) {
return tableDescribeMapper.getColCount(tableName);
}
@Override
public Integer getRowCount(String tableName) {
return tableDescribeMapper.getRowCount(tableName);
}
}
TableManagerServiceImpl
这段代码是针对数据库中表 `t_table_manager` 的操作服务实现类,让我逐步解释:
1. `TableManagerServiceImpl` 类实现了 `TableManagerService` 接口,并继承了 `ServiceImpl<TableManagerMapper, TableManager>`。这意味着它是一个基于 MyBatis-Plus 的服务实现类,用于处理 `TableManager` 实体类的数据库操作。
2. 在类上标注了 `@Service` 注解,表示它是一个 Spring 的服务类。
3. `tableManagerMapper` 属性通过 `@Autowired` 注解注入了 `TableManagerMapper` 类型的 Bean。
4. `getAllData()` 方法用于获取表 `t_table_manager` 中的所有数据,它调用了 `tableManagerMapper` 的 `selectList(null)` 方法。
5. `insertTableManager(TableManagerDTO tableManagerDTO)` 方法用于插入表管理信息,它调用了 `tableManagerMapper` 的 `insertTableManager` 方法。
6. `getFiledByTableName(String tableName)` 方法用于根据表名获取字段名列表,它调用了 `tableManagerMapper` 的 `getFiledByTableName` 方法。
7. `getCommentsByTableName(String tableName)` 方法用于根据表名获取字段注释列表,类似地,它调用了 `tableManagerMapper` 的 `getCommentsByTableName` 方法。
8. `getInfoByTableName(String tableName)` 方法用于根据表名获取表信息,它调用了 `tableManagerMapper` 的 `getInfoByTableName` 方法。
9. `getInfoByFiled(String param)` 方法根据字段信息获取表信息,它调用了 `tableManagerMapper` 的 `getInfoByFiled` 方法。
10. `getAllTableManagersByFiledName(List<String> tableNames)` 方法根据
package com.cqupt.software_1.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.software_1.common.TableManagerDTO;
import com.cqupt.software_1.entity.TableManager;
import com.cqupt.software_1.service.TableManagerService;
import com.cqupt.software_1.mapper.TableManagerMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* @author hp
* @description 针对表【t_table_manager】的数据库操作Service实现
* @createDate 2023-05-23 15:10:20
*/
@Service
public class TableManagerServiceImpl extends ServiceImpl<TableManagerMapper, TableManager>
implements TableManagerService {
@Autowired
private TableManagerMapper tableManagerMapper;
@Override
public List<TableManager> getAllData() {
List<TableManager> tableManager = tableManagerMapper.selectList(null);
return tableManager;
}
@Override
public void insertTableManager(TableManagerDTO tableManagerDTO) {
tableManagerMapper.insertTableManager(tableManagerDTO);
}
@Override
public List<String> getFiledByTableName(String tableName) {
List<String> tableNames = tableManagerMapper.getFiledByTableName(tableName);
return tableNames;
}
@Override
public List<String> getCommentsByTableName(String tableName) {
List<String> comments = tableManagerMapper.getCommentsByTableName(tableName);
return comments;
}
@Override
public List<Object> getInfoByTableName(String tableName) {
List<Object> res = tableManagerMapper.getInfoByTableName(tableName);
return res;
}
@Override
public boolean[] getInfoByFiled(String param) {
boolean r1 = false,r2 = false, r3 = false;
TableManager tableManager = tableManagerMapper.getInfoByFiled(param);
if (tableManager != null){
r1 = Objects.equals(tableManager.getIsDemography(), "1");
r2 = Objects.equals(tableManager.getIsPhysiological(), "1");
r3 = Objects.equals(tableManager.getIsSociology(), "1");
}
return new boolean[]{r1,r2,r3};
}
@Override
public List<TableManager> getAllTableManagersByFiledName(List<String> tableNames) {
List<TableManager> res= new ArrayList<>();
for (int i = 0; i< tableNames.size() ; i++) {
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("field_name", tableNames.get(i));
queryWrapper.eq("table_name","Diabetes");
TableManager tableManager = tableManagerMapper.selectOne(queryWrapper);
res.add(tableManager);
}
return res;
}
@Override
public List<TableManager> getAllDataByUserId(Integer userId) {
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("user_id",userId);
List<TableManager> tableManager = tableManagerMapper.selectList(queryWrapper);
return tableManager;
}
}
TableServiceImpl
这段代码是一个基于Spring框架的Java服务实现类。让我逐步解释每个部分的功能:
1. **包声明和导入**:
```java
package com.cqupt.software_1.service.impl;
import com.cqupt.software_1.entity.TableManager;
import com.cqupt.software_1.mapper.TableMapper;
import com.cqupt.software_1.service.TableService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
com.cqupt.software_1.service.impl是该类所在的包。TableManager和TableMapper是引入的实体类和数据访问对象(DAO),用于操作数据库表。TableService是服务接口,定义了该类需要实现的服务方法。@Autowired和@Service是Spring框架的注解,用于依赖注入和声明该类为服务类。
-
类声明:
@Service public class TableServiceImpl implements TableService {@Service注解表明这是一个Spring的服务类,负责业务逻辑的实现。TableServiceImpl类实现了TableService接口,意味着需要实现接口中定义的方法。
-
依赖注入:
@Autowired private TableMapper tableMapper;- 使用
@Autowired注解将TableMapper注入到TableServiceImpl类中,使得可以在类中直接使用tableMapper访问数据库。
- 使用
-
方法实现:
-
createTable 方法:
@Override public void createTable(String tableName, Map<String, String> fieldMap) { tableMapper.createTable(tableName, fieldMap); }createTable方法用于创建数据库表。- 参数
tableName是表名,fieldMap是字段名和字段类型的映射。 - 调用
tableMapper的createTable方法来执行具体的数据库表创建操作。
-
saveCSV2MySQL 方法:
@Override public void saveCSV2MySQL(String remotePath, String originalFilename) { tableMapper.saveCSV2MySQL(remotePath, originalFilename); }saveCSV2MySQL方法用于将CSV文件保存到MySQL数据库中。- 参数
remotePath是远程文件路径,originalFilename是原始文件名。 - 调用
tableMapper的saveCSV2MySQL方法来实现具体的文件导入操作。
-
insertTableInfo 方法:
@Override public void insertTableInfo(String tableName) { tableMapper.insertTableInfo(tableName); }insertTableInfo方法用于向数据库中插入表信息。- 参数
tableName是表名。 - 调用
tableMapper的insertTableInfo方法来执行具体的数据库插入操作。
-
这些方法实现了 TableService 接口中定义的服务功能,通过 TableMapper 实现了与数据库的交互,具体功能包括表创建、CSV文件导入和表信息插入。
```javascript
package com.cqupt.software_1.service.impl;
import com.cqupt.software_1.entity.TableManager;
import com.cqupt.software_1.mapper.TableMapper;
import com.cqupt.software_1.service.TableService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class TableServiceImpl implements TableService {
@Autowired
private TableMapper tableMapper;
@Override
public void createTable(String tableName, Map<String, String> fieldMap) {
tableMapper.createTable(tableName, fieldMap);
}
@Override
public void saveCSV2MySQL(String remotePath, String originalFilename) {
tableMapper.saveCSV2MySQL(remotePath,originalFilename);
}
@Override
public void insertTableInfo(String tableName) {
tableMapper.insertTableInfo(tableName);
}
}
TaskServiceImpl
这段代码是一个Java类,实现了`TaskService`接口,并提供了对任务(Task)的各种操作。
1. `getAlgorithmUsageDailyStatsLast7Days()`:获取过去7天内算法的每日使用统计数据。
2. `getAlgorithmName()`:获取所有算法的名称。
3. `getTaskList()`:获取所有任务列表。
4. `getlistbyId(Integer id)`:通过任务ID获取任务信息。
5. `deleteTask(int id)`:根据任务ID删除任务。
6. `getLeaderList()`:获取所有负责人(领导)的列表。
7. `createVisualizationTask(String tableName, Map<String, Object> selectDiseaseMap, CreateTaskEntity taskInfo)`:创建可视化任务,将选定的疾病数据和任务信息存储到数据库中。
8. `getTaskCountByTime(String timeStr)`:根据时间字符串获取任务数量。
9. `addRepresentTask(String tableName, List<String> colNames, String model, CreateTaskEntity taskInfo)`:添加代表性任务,将表名、列名、模型信息以及任务信息存储到数据库中。
这些方法通过调用`TaskMapper`和`CategoryMapper`中的对应方法实现数据库操作。其中,`TaskMapper`用于对任务表进行操作,而`CategoryMapper`用于获取疾病标签信息。
package com.cqupt.software_1.service.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.software_1.common.UserThreadLocal;
import com.cqupt.software_1.entity.AlgorithmUsageDailyStats;
import com.cqupt.software_1.entity.CreateTaskEntity;
import com.cqupt.software_1.entity.Task;
import com.cqupt.software_1.mapper.CategoryMapper;
import com.cqupt.software_1.mapper.TaskMapper;
import com.cqupt.software_1.service.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Service
public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task>
implements TaskService {
@Resource
TaskMapper taskMapper;
@Autowired
CategoryMapper categoryMapper;
@Override
public List<AlgorithmUsageDailyStats> getAlgorithmUsageDailyStatsLast7Days() {
return taskMapper.getAlgorithmUsageDailyStatsLast7Days();
}
@Override
public List<String> getAlgorithmName() {
return taskMapper.getAlgorithmName();
}
@Override
public List<Task> getTaskList() {
return taskMapper.getTaskList();
}
@Override
public Task getlistbyId(Integer id) {
return taskMapper.getlistbyId(id);
}
@Override
public void deleteTask(int id) {
taskMapper.deleteTask(id);
}
@Override
public List<String> getLeaderList() {
return taskMapper.getLeaderList();
}
@Override
public void createVisualizationTask(String tableName, Map<String, Object> selectDiseaseMap, CreateTaskEntity taskInfo) {
Task task = new Task();
String features = selectDiseaseMap.keySet().stream().collect(Collectors.joining(","));
task.setFeature(features);
task.setTargetcolumn(features);
task.setCreatetime(new Timestamp(System.currentTimeMillis()));
task.setDataset(tableName);
task.setLeader(taskInfo.getPrincipal()==null?UserThreadLocal.get().getUsername():taskInfo.getPrincipal());
task.setParticipant(taskInfo.getParticipants());
task.setTasktype(taskInfo.getTasktype()==null?"病人画像":taskInfo.getTasktype());
task.setTaskname(taskInfo.getTaskName()==null?UserThreadLocal.get().getUsername()+"_病人画像_"+ LocalDate.now().toString():taskInfo.getTaskName());
String label = categoryMapper.getParentLabelByLabel(tableName);
task.setDisease(label);
task.setRemark(taskInfo.getTips());
task.setModel("无");
task.setResult(JSON.toJSONString(selectDiseaseMap));
task.setUserid(UserThreadLocal.get().getUid());
taskMapper.insert(task);
}
@Override
public Integer getTaskCountByTime(String timeStr) {
return taskMapper.getTaskCountByTime(timeStr);
}
@Override
public void addRepresentTask(String tableName, List<String> colNames,String model, CreateTaskEntity taskInfo) {
Task task = new Task();
String features = colNames.stream().collect(Collectors.joining(","));
task.setFeature(features);
task.setTargetcolumn(features);
task.setCreatetime(new Timestamp(System.currentTimeMillis()));
task.setDataset(tableName);
task.setLeader(taskInfo.getPrincipal()==null?UserThreadLocal.get().getUsername():taskInfo.getPrincipal());
task.setParticipant(taskInfo.getParticipants());
task.setTasktype(taskInfo.getTasktype()==null?"疾病特征表征":taskInfo.getTasktype());
task.setTaskname(taskInfo.getTaskName()==null?UserThreadLocal.get().getUsername()+"_疾病特征表征_"+ LocalDate.now().toString():taskInfo.getTaskName());
task.setModel(model);
String label = categoryMapper.getParentLabelByLabel(tableName);
task.setDisease(label);
task.setRemark(taskInfo.getTips());
task.setModel("无");
task.setUserid(UserThreadLocal.get().getUid());
taskMapper.insert(task);
}
}
UserLogServiceImpl
这段代码是一个基于Spring框架的Java服务实现类。它位于`com.cqupt.software_1.service.impl`包中。首先,它导入了一些必要的类和接口,包括`ServiceImpl`类、`UserLog`实体类、`UserLogMapper`接口以及`UserLogService`接口。
在类声明上方有一段注释,指出了该类的作者、描述以及创建日期。
接着,类名为`UserLogServiceImpl`,它继承了`ServiceImpl<UserLogMapper, UserLog>`类,并实现了`UserLogService`接口。这意味着它提供了对数据库表`user_log`的操作。
在类中,通过`@Autowired`注解将`UserLogMapper`接口的实例注入到了`userLogMapper`变量中。
`insertUserLog`方法是该类的一个重要方法,它接受一个`UserLog`对象作为参数,并将其插入到数据库中。在方法内部,通过`userLogMapper`调用`insert`方法实现插入操作,然后将插入结果返回。
总体来说,这个类是用来处理`user_log`表的数据库操作的实现类,其中最重要的方法是`insertUserLog`,用于插入用户日志信息。
package com.cqupt.software_1.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.software_1.entity.UserLog;
import com.cqupt.software_1.mapper.UserLogMapper;
import com.cqupt.software_1.service.UserLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author hp
* @description 针对表【user_log】的数据库操作Service实现
* @createDate 2023-09-07 14:34:13
*/
@Service
public class UserLogServiceImpl extends ServiceImpl<UserLogMapper, UserLog>
implements UserLogService {
@Autowired
private UserLogMapper userLogMapper;
@Override
public int insertUserLog(UserLog userLog) {
int insert = userLogMapper.insert(userLog);
return insert;
}
}
UserServiceImpl
这段代码是另一个基于Spring框架的Java服务实现类,位于`com.cqupt.software_1.service.impl`包中。它也导入了一些必要的类和接口,包括`ServiceImpl`类、`User`实体类、`UserMapper`接口、`UserService`接口以及一些自定义的数据传输对象。
在类声明上方有一段注释,指出了该类的作者、描述以及创建日期。
类名为`UserServiceImpl`,它同样继承了`ServiceImpl<UserMapper, User>`类,并实现了`UserService`接口,用于对数据库表`user`进行操作。
在类中,通过`@Autowired`注解将`UserMapper`接口的实例注入到了`userMapper`变量中。
接下来是一系列方法的实现:
- `getAll`方法返回了所有用户的列表。
- `getUserByName`方法根据用户名获取用户信息。
- `getUserById`方法根据用户ID获取用户信息。
- `saveUser`方法用于保存用户信息。
- `getAllUserInfo`方法用于分页获取所有用户的信息。
- `updateStatusById`方法用于更新用户状态。
- `removeUserById`方法用于删除用户。
- `insertUser`方法用于插入用户信息。
- `getUserPage`方法用于分页获取用户信息,返回包含总数和数据列表的Map。
- `updatePwd`方法用于更新用户密码。
- `querUser`方法用于查询所有用户信息。
- 还有一些管理员端数据管理相关的方法,如`addTableSize`用于增加用户表格大小,`minusTableSize`用于减少用户表格大小,以及`selectByUid`用于根据用户ID查询用户信息。
总体来说,这个类是用于处理用户表`user`的数据库操作的实现类,包含了各种用户信息管理和数据管理的方法。
package com.cqupt.software_1.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.software_1.entity.User;
import com.cqupt.software_1.service.UserService;
import com.cqupt.software_1.mapper.UserMapper;
import com.cqupt.software_1.vo.InsertUserVo;
import com.cqupt.software_1.vo.UserPwd;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author hp
* @description 针对表【user】的数据库操作Service实现
* @createDate 2023-05-16 16:44:39
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
implements UserService{
@Autowired
private UserMapper userMapper;
@Override
public List<User> getAll() {
List<User> users = userMapper.selectList(null);
return users;
}
@Override
public User getUserByName(String userName) {
User user = userMapper.getUerByUserName(userName);
return user;
}
@Override
public User getUserById(Integer id) {
return userMapper.getUserById(id);
}
@Override
public void saveUser(User user) {
userMapper.saveUser(user);
}
@Override
public Page<User> getAllUserInfo(int pageNum , int pageSize) {
Page<User> page = new Page<>(pageNum, pageSize);
return userMapper.selectPage(page,null);
}
@Override
public boolean updateStatusById(Integer uid, Integer role ,double uploadSize , String status) {
boolean b = userMapper.updateStatusById(uid, role ,uploadSize, status);
if ( b ) return true;
return false;
}
@Override
public boolean removeUserById(Integer uid) {
userMapper.removeUserById(uid);
return true;
}
@Override
public boolean insertUser(InsertUserVo user) {
userMapper.insertUser(user);
return false;
}
public Map<String, Object> getUserPage(int pageNum, int pageSize) {
int offset = (pageNum - 1) * pageSize;
List<User> userList = userMapper.selectUserPage(offset, pageSize);
int total = userMapper.countUsers();
Map<String, Object> result = new HashMap<>();
result.put("total", total);
result.put("data", userList);
return result;
}
@Override
public boolean updatePwd(UserPwd user) {
userMapper.updatePwd(user);
return false;
}
@Override
public List<User> querUser() {
List<User> users = userMapper.selectList(null);
return users;
}
// 下面方法是管理员端-数据管理新增
@Override
public void addTableSize(String uid,float tableSize) {
userMapper.addTableSize(Integer.parseInt(uid), tableSize);
}
@Override
public void minusTableSize(String uid, float tableSize) {
userMapper.minusTableSize(Integer.parseInt(uid), tableSize);
}
@Override
public User selectByUid(String uid) {
return userMapper.selectByUid(Integer.parseInt(uid));
}
}










