springboot项目问题

目录标题

  • 问题
    • 后端
      • 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);
    }
}

你可能感兴趣的:(项目经验,spring,boot,后端,java)