目录标题
- 问题
- 后端
- 1.[mybatis报错Parameter 'start' not found. Available parameters are [1, 0, param1, param2]](https://www.cnblogs.com/josephcnblog/articles/7077244.html)
- 知识
- 后端
- 1. [@Select 数据表的字段与实体类的属性值](https://www.cnblogs.com/yanguobin/p/11919042.html)
- 2.[@Select标签内的大于小于判断符号](https://blog.csdn.net/qq_42811766/article/details/127283062)
- 3.[MetaObjectHandler](https://blog.csdn.net/weixin_72979483/article/details/130952080)
- 4. [MybatisPlus中@TableLogic逻辑删除](http://www.mobange.com/nav/java/90162.html)
- 5.[lombok里的Builder注解](http://fendou.net.cn/index.php/a/369)
- 6. [mybatis-plus IEnum转化](https://blog.csdn.net/cfv3246/article/details/115523168)
- 7.[曲线拟合](https://blog.csdn.net/wufeiwua/article/details/109004452)
- 8. 根据国家城市名称获取经纬度
- 9. 获取接口信息的接口
- 10.springboot引入Apache spark(达梦数据库)gradle
- 常用接口实例
问题
后端
1.mybatis报错Parameter ‘start’ not found. Available parameters are [1, 0, param1, param2]
知识
后端
1. @Select 数据表的字段与实体类的属性值
2.@Select标签内的大于小于判断符号
3.MetaObjectHandler
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
if (metaObject.hasGetter("createTime")) {
this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
}
if (metaObject.hasGetter("updateTime")) {
this.strictInsertFill(metaObject, "updateTime", Date.class, new Date());
}
if (metaObject.hasGetter("lastModifyTime")) {
this.strictInsertFill(metaObject, "lastModifyTime", Date.class, new Date());
}
}
@Override
public void updateFill(MetaObject metaObject) {
if (metaObject.hasGetter("updateTime")) {
this.strictInsertFill(metaObject, "updateTime", Date.class, new Date());
}
if (metaObject.hasGetter("lastModifyTime")) {
this.strictInsertFill(metaObject, "lastModifyTime", Date.class, new Date());
}
}
}
4. MybatisPlus中@TableLogic逻辑删除
参考
@TableLogic(value = "1", delval = "0")
5.lombok里的Builder注解
6. mybatis-plus IEnum转化
定义枚举时需要使用mybaties plus的枚举转换:
枚举类需要继承IEnum
application-dev.properties文件配置mybatis-plus.configuration.default-enum-type-handler=com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
7.曲线拟合
8. 根据国家城市名称获取经纬度
参考
在Java中使用离线API获取国家城市的经纬度,一个常用的选择是使用Geonames数据库。Geonames是一个开源的地理数据库,包含了世界范围内的地理位置信息,包括国家、城市、地点等。
以下是在Java中使用Geonames离线API获取国家城市的经纬度的简单示例:
1.下载数据库文件:访问Geonames的官方网站(https://www.geonames.org/export/)并下载适用于您的需求的数据库文件。您可以下载包含国家和城市信息的数据库文件,例如"cities15000.txt"。
2.导入依赖:将下载的数据库文件放在项目中,并导入相关的Java类库。
在代码中使用库:使用Java读取和查询Geonames数据库文件,根据国家或城市名称获取对应的经纬度信息。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class OfflineGeolocation {
public static void main(String[] args) {
try {
// 加载数据库文件
String databaseFile = "/path/to/cities15000.txt";
Map<String, String> geonamesData = loadGeonamesData(databaseFile);
// 查询国家或城市的经纬度
String country = "China";
String city = "Beijing";
double latitude = getLatitude(geonamesData, country, city);
double longitude = getLongitude(geonamesData, country, city);
System.out.println("经度: " + longitude);
System.out.println("纬度: " + latitude);
} catch (IOException e) {
e.printStackTrace();
}
}
private static Map<String, String> loadGeonamesData(String databaseFile) throws IOException {
Map<String, String> geonamesData = new HashMap<>();
BufferedReader reader = new BufferedReader(new FileReader(databaseFile));
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split("\t");
if (parts.length > 1) {
String geoname = parts[1];
double latitude = Double.parseDouble(parts[4]);
double longitude = Double.parseDouble(parts[5]);
geonamesData.put(geoname, latitude + "," + longitude);
}
}
reader.close();
return geonamesData;
}
private static double getLatitude(Map<String, String> geonamesData, String country, String city) {
String key = city + ", " + country;
String value = geonamesData.get(key);
if (value != null) {
String[] latLng = value.split(",");
return Double.parseDouble(latLng[0]);
}
return 0.0;
}
private static double getLongitude(Map<String, String> geonamesData, String country, String city) {
String key = city + ", " + country;
String value = geonamesData.get(key);
if (value != null) {
String[] latLng = value.split(",");
return Double.parseDouble(latLng[1]);
}
return 0.0;
}
}
9. 获取接口信息的接口
要实现一个可以获取所有接口信息的接口,你可以使用 Spring Boot 的 Actuator 模块和 Reflections 库来实现。
首先,确保已将 Spring Boot Actuator 添加到 Maven 或 Gradle 依赖中:
Maven 依赖配置:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Gradle 依赖配置:
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-actuator'
然后,在你的 Spring Boot 应用中创建一个新的 REST Controller 类,用于暴露获取接口信息的接口:
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.reflections.Reflections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint;
import org.springframework.core.env.Environment;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@RestController
@RequestMapping("/api-info")
public class ApiInfoController {
@Autowired
private Environment environment;
@GetMapping
@ApiOperation("获取所有接口信息")
public ResponseEntity<List<ApiInfo>> getAllApiInfo() {
String basePackage = environment.getProperty("spring.application.base-package");
List<ApiInfo> apiInfos = new ArrayList<>();
Reflections reflections = new Reflections(basePackage);
Set<Class<?>> classes = reflections.getTypesAnnotatedWith(Api.class);
for (Class<?> clazz : classes) {
Api apiAnnotation = clazz.getAnnotation(Api.class);
if (apiAnnotation != null) {
String apiName = apiAnnotation.value();
String apiDescription = apiAnnotation.description();
Method[] methods = clazz.getMethods();
for (Method method : methods) {
ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
if (apiOperation != null) {
String operationPath = getOperationPath(clazz, method);
String operationSummary = apiOperation.value();
apiInfos.add(new ApiInfo(apiName, apiDescription, operationPath, operationSummary));
}
}
}
}
return ResponseEntity.ok(apiInfos);
}
private String getOperationPath(Class<?> clazz, Method method) {
RequestMapping classRequestMapping = clazz.getAnnotation(RequestMapping.class);
RequestMapping methodRequestMapping = method.getAnnotation(RequestMapping.class);
StringBuilder pathBuilder = new StringBuilder();
if (classRequestMapping != null && classRequestMapping.value().length > 0) {
pathBuilder.append(classRequestMapping.value()[0]);
}
if (methodRequestMapping != null && methodRequestMapping.value().length > 0) {
pathBuilder.append(methodRequestMapping.value()[0]);
}
return pathBuilder.toString();
}
@Endpoint(id = "api-info")
public static class ApiInfoEndpoint {
private final ApiInfoController apiInfoController;
public ApiInfoEndpoint(ApiInfoController apiInfoController) {
this.apiInfoController = apiInfoController;
}
@ReadOperation
public List<ApiInfo> getAllApiInfo() {
return apiInfoController.getAllApiInfo().getBody();
}
}
@RestControllerEndpoint(id = "api-info")
public static class ApiInfoRestControllerEndpoint {
private final ApiInfoController apiInfoController;
public ApiInfoRestControllerEndpoint(ApiInfoController apiInfoController) {
this.apiInfoController = apiInfoController;
}
@GetMapping
public ResponseEntity<List<ApiInfo>> getAllApiInfo() {
return apiInfoController.getAllApiInfo();
}
}
public static class ApiInfo {
private String apiName;
private String apiDescription;
private String operationPath;
private String operationSummary;
public ApiInfo(String apiName, String apiDescription, String operationPath, String operationSummary) {
this.apiName = apiName;
this.apiDescription = apiDescription;
this.operationPath = operationPath;
this.operationSummary = operationSummary;
}
// Getters and setters
}
}
上述代码创建了一个获取所有接口信息的 REST Controller,通过扫描指定的基础包中带有 @Api 注解的类,获取其下带有 @ApiOperation 注解的方法信息,并返回给调用方。
在这个 Controller 中,我们还使用了 Actuator 的 @Endpoint 和 @RestControllerEndpoint 注解,分别创建了一个自定义的 Endpoint 和 RestControllerEndpoint,以便将接口信息暴露在 Actuator 端点中。这样,你可以通过访问 /actuator/api-info 或 /api-info 端点来获取所有接口信息列表。
确保在应用的配置文件(例如 application.properties)中设置了 spring.application.base-package 属性,该属性指定需要扫描的基础包路径。
运行应用后,你可以访问 http://localhost:8080/api-info 来获取所有接口信息的列表。
10.springboot引入Apache spark(达梦数据库)gradle
引入依赖
implementation 'org.apache.spark:spark-sql_2.12:3.1.2'
implementation ('org.apache.spark:spark-core_2.12:3.1.2')
{
exclude group: 'org.codehaus.janino', module: 'janino'
}
implementation ('org.codehaus.janino:janino:3.0.16')
//implementation 'org.apache.spark:spark-jdbc_2.12:3.1.2'
// implementation 'org.codehaus.janino:commons-compiler:3.1.6'
确保 Spark SQL 和 Janino 版本的兼容性
创建一个Spring Boot的配置类或启动类,用于创建SparkSession和连接到数据库:
package com.iscas.biz.config;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SparkSession;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
public class SparkConfig {
@Bean
public SparkSession sparkSession() {
return SparkSession.builder()
.appName("DataQualityAnalysis")
.master("local[*]") // 指定Spark的运行模式
.getOrCreate();
}
@Bean
public DataSource mysqlDataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("dm.jdbc.driver.DmDriver");
dataSource.setUrl("jdbc:dm://192.168.101.121:5236/POLITICS_WORK?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8");
dataSource.addConnectionProperty("user", "SYSDBA");
dataSource.addConnectionProperty("password", "SYSDBA001");
return dataSource;
}
@Bean
public Properties connectionProperties() {
Properties connectionProperties = new Properties();
connectionProperties.put("user", "SYSDBA");
connectionProperties.put("password", "SYSDBA");
connectionProperties.put( "driver","dm.jdbc.driver.DmDriver");
return connectionProperties;
}
@Bean
public Dataset<Row> loadDataFromMySQL(SparkSession sparkSession,Properties connectionProperties) {
/* return sparkSession.read().format("jdbc").option("driver","dm.jdbc.driver.DmDriver")
.option("url", "jdbc:dm://192.168.101.121:5236/POLITICS_WORK?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8")
.option("dbtable", "POLITICS_WORK.COGNIT_NEWS")
.option("user", "SYSDBA")
.option("password", "SYSDBA")
.load();*/
return sparkSession.read()
.jdbc("jdbc:dm://192.168.101.121:5236/POLITICS_WORK?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8", "POLITICS_WORK.COGNIT_NEWS",connectionProperties);//达梦数据库要指定模式名.表名 其他数据库有的只需指定表名
}
}
接下来,创建一个用于数据质量分析的服务类:
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DataQualityAnalysisService {
@Autowired
private Dataset<Row> data;
public void performDataQualityAnalysis() {
// 在这里进行数据质量分析的操作,可以使用Spark SQL或其他Spark API进行查询、聚合、过滤等操作
long totalRows = data.count();
long missingValues = data.filter("col1 IS NULL OR col2 IS NULL").count();
double missingPercentage = (missingValues * 100.0) / totalRows;
System.out.println("Total rows: " + totalRows);
System.out.println("Missing values: " + missingValues);
System.out.println("Missing percentage: " + missingPercentage);
}
}
常用接口实例
SparkSession类全部函数说明并代码举例
Dataset类全部函数说明并代码举例
apache spark RDD类的全部函数及代码举例
总结:
Apache Spark 在 Java 中的接口文档的基本结构:
SparkSession:SparkSession 是 Spark 2.0 引入的主要入口点,用于创建 Spark 应用程序。它可以通过 SparkSession.Builder 类来构建,提供了各种配置选项和方法用于创建 DataFrame、执行 SQL 查询等。
Dataset 和 DataFrame(已过期):Dataset 和 DataFrame 是 Spark 中用于处理结构化数据的核心 API。Dataset 是类型安全的分布式数据集合,DataFrame 是 Dataset 的一种特殊类型,可以看作是一张表格。你可以在 Dataset 和 DataFrame 上进行各种数据操作和转换,如过滤、映射、聚合等。
RDD(Resilient Distributed Datasets):RDD 是 Spark 中的一个基本抽象概念,代表一个可分区、可并行计算的数据集合。虽然 Spark 推荐使用 Dataset 和 DataFrame,但如果需要更底层的控制,仍然可以使用 RDD。
Transformations(转换操作):Spark 提供了许多用于对数据进行转换的操作,如 map、filter、join、groupBy 等。这些操作可以应用到 Dataset、DataFrame 或 RDD 上,通常会生成一个新的 Dataset、DataFrame 或 RDD。
Actions(动作操作):Actions 是触发实际计算并返回结果的操作。这些操作会将计算图转换为执行计划,并将最终结果返回给驱动程序或写入外部系统,如 collect、count、save 等。
容错性和数据分片:Spark 提供了容错性和数据分片机制,可以确保在节点故障时能够自动恢复和保证数据一致性。