packaging属性

pom.xml packaging属性指明了打包方式——jar/war/pom,pom说明是个父模块,具体打包要子模块。

<packaging>jar</packaging>

打包插件

spring-boot-maven-plugin插件,会根据packaging属性打包,并将所有依赖和sping组件打包成一个war/jar包。

 <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
 </plugin>

其它打包插件有:Maven - 打包可执行jar包

jar打包

所有依赖和Tomcat一起打包成jar,运行只要java -jar xxx.jar

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.greate</groupId>
    <artifactId>community</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>community</name>
    <description>great community — Echo</description>
    <!--jar打包-->
    <packaging>jar</packaging>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <!--spring内置一个Tomcat-->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <!--thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!--Devtools 热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>

        ...

    </dependencies>

    <build>
        <finalName>ROOT</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

war打包

除去Tomcat所有依赖打包成war,必须部署到Tomcat环境中运行

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.greate</groupId>
    <artifactId>community</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>community</name>
    <description>great community — Echo</description>
    <!--war打包-->
    <packaging>war</packaging>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <!--除去Tomcat依赖-->
                <exclusion>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                    <groupId>org.springframework.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <!--thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!--Devtools 热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>

        ...

    </dependencies>

    <build>
        <finalName>ROOT</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

做了啥?学到了啥?

C Sharp

承担了一些CRUD的开发;以CAP、Redis的操作封装更熟悉了

Java

接手项目用到了,主要是spring boot,一点点的spring cloud alibaba

QT

项目中用到,熟悉了基本用法,界面主要用的QWidget

open layer地图用法

学会了C++库的引用

Python

基本的语法上手,做了个打卡工具

Php

laravel Demo入门

Vue

把仿微博项目用Vue重做了

嵌入式

玩了几次stm32 hal库开发,了解了大概流程,上手简单很多

Android

年初学了点原生android,了解了个大概,有些东西——比如数据绑定、xml展示——和wpf思路差不多

什么还是没做?

leetcode 算法

linux 应用开发/驱动开发

玩硬件——一直想找个开源项目,从画板子开始学一遍

其它

胖了10几斤,达到了历史最高了。期间坚持一段时间跑步,右膝盖受不了。
拨了颗智齿,有点后悔,不是太歪留着也可以
每天久坐,腰开始疼了,痔疮加重了
计划去洗牙,一直没去

拿了优秀员工,工资涨了一千块

生活不易,猫猫叹气

我写完才发现自已过好差啊。变的更累了,进步不大,身体还变差了。生活无趣,印象中除了上班,周末只是干饭,惟一一次出去玩是老婆拉我去海边。写到这觉得有点对不起老婆了。

2024要干嘛

换个工作,目的是长技术涨工资
要不要转嵌入式?能不能转?不知道,可以先学

考个摩托车驾照
减个肥吧
出去走一次吧,去哪都行


瓦片地图显示

openlayers html

<!doctype html>
<html lang="en">

<head>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/ol.css">
  <style>
    .map {
      height: 400px;
      width: 100%;
    }
  </style>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/ol.js"></script>
  <script src="https://code.jquery.com/jquery-3.7.1.min.js"
    integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
  <title>OpenLayers</title>
</head>

<body>
  <h2>My Map</h2>
  <div id="map" class="map"></div>
  <script type="text/javascript">
    let server = "http://10.1.2.200:5500/"
    // let json = '{"originX":"-20037700","originY":"30241100","size":"512","resolution":["33.072982812632297","16.933367200067735","8.4666836000338677","4.2333418000169338","2.1166709000084669","1.0583354500042335","0.52916772500211673","0.26458386250105836"],"xMin":"2199.2910886158115","yMin":"3067.6768479598759","xMax":"11179.195134644895","yMax":"12292.290762729714"}'
    // var info = JSON.parse(json)
    let info
    $.ajax({
      async: false,
      url: "http://10.1.2.200:5500/map/GetTiledMapInfo",
      headers: { "MineId": "0" },
      success: function (result) {
        info = result.data;
      }
    })

    //要鉴权
    // $.ajax({url:"http://10.1.2.200:5500/map/GetTiledMap", headers:{"MineId": "0"},success:function(result){
    //     //console.log("infos",result)
    //     info.tiledUrl = result.data.tiledUrl;
    //     // console.log(info)
    // }});

    // console.log(info)
    function formatQuery(num, len, radix) {
      let str = num.toString(radix || 10)
      return str.padStart(len, '0')
    }
    let projection = new ol.proj.Projection({
      code: 'EPSG:4527',
      units: 'm',
      extent: [info.xMin, info.yMin, info.xMax, info.yMax]
    })
    //必须是number
    let originCenter =  [Number(info.xMin) + (Number(info.xMax) - Number(info.xMin)) / 2, Number(info.yMin)  + (Number(info.yMax) - Number(info.yMin)) / 2]
    var map = new ol.Map({
      target: 'map',
      layers: [
        new ol.layer.Tile({
          zIndex: 0,
          source: new ol.source.XYZ({
            tileUrlFunction: (coordinate) => {
              let x = 'C' + this.formatQuery(coordinate[1], 8, 16)
              let y = 'R' + this.formatQuery(coordinate[2], 8, 16)
              let z = 'L' + this.formatQuery(coordinate[0], 2, 10)
              return `${server}${info.tiledUrl ? info.tiledUrl : "TiledMap/2023070401/Layers/_alllayers"}/${z}/${y}/${x}.png`
            },
            tileGrid: new ol.tilegrid.TileGrid({
              tileSize: info.size,
              //必须是number
              origin: [Number(info.originX), Number(info.originY)],
              extent: [info.xMin, info.yMin, info.xMax, info.yMax],
              minZoom: 0,
              resolutions: info.resolution
            }),
            projection: projection
          })
        })
      ],
      view: new ol.View({
        projection: projection,
        center: originCenter,
        resolution: info.resolution[1],
        resolutions: info.resolution
      })
    });
  </script>
</body>

</html>

每层首片编号计算

//单张瓦片大小 米
double r = resolution[z] * size;
//originXY的加还是减,是xy是Min还是Max,可以试出来。具体和坐标正方向有关
x += (-originX + xMin) / r;
y += (originY - yMax) / r;

Qt上实现

  1. Qt自定义地图插件实现
  2. 利用QWebEnginaView加载openlayer的html,有错误没解决

2023/11/30更新:

  • QWebEnginaView报错是原因:ol的最新库在webengina上不兼容,换个旧版的库问题解决;
  • Qt的地图插件使用的是高德坐标系,项目使用的是百度坐标系,并且QT插件不能设置地图
    范围,默认是全球,使得插件在点定位出现偏差。

由SecureRandom随机生成key

KeyGenerator kgen = KeyGenerator.getInstance("AES");
// 防止linux下 随机生成key
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(password.getBytes());
kgen.init(128, secureRandom);
// kgen.init(128, new SecureRandom(password.getBytes()));
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(content);
return result; // 加密

指定key iv

Cipher cipher = Cipher.getInstance("AES/CBC/ISO10126Padding");
SecretKeySpec keySpec = new SecretKeySpec(Base64.getDecoder().decode(key), "AES");
// 设置偏移量参数
IvParameterSpec ivSpec = new IvParameterSpec(Base64.getDecoder().decode(iv));
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

byte[] encryped = cipher.doFinal(data);
byte[] decrypted=new byte[data.length];
System.arraycopy(encryped, 0, decrypted, 0, encryped.length);
return new String(decrypted, "utf-8").trim();

注意

  • 获取execute的结果保存到变量,使用into,execute ... into variable、select ... into variable
  • 拼接字符串,使用||,或者使用函数concat('A', 'B', ...)
  • PERFORM vs EXECUTE :

    • PERFORM 调用无返回值的函数
    • EXECUTE 执行动态生成的语名
  • pg_sleep(secends), PERFORM pg_sleep(0.1) 这样调用,或者嵌在select中
CREATE OR REPLACE FUNCTION gen_min_day(_day varchar) RETURNS void AS  
$BODY$
DECLARE 
i INTEGER;
num INTEGER;
T TIMESTAMP;
sqlstring VARCHAR;
t1 TIMESTAMP;
BEGIN
  RAISE NOTICE 'Value: %', _day;
  EXECUTE 'create TABLE IF not EXISTS ' || concat('transducerstatusminute', _day) || '(
  "number" int4 NOT NULL,
  "value" float8,
  "time" timestamp(6) NOT NULL
  ) ';
  num := 3218101;
  i := 1;
  T := cast (concat(_day ,' 0:0:0.000') as  timestamp without time zone);
  t1 := T;
  << goto_label >>
  WHILE
  num <= 3218201
  loop
  sqlstring :=  'INSERT INTO ' || concat('transducerstatusminute', _day) || ' ( "number", "value", "time" ) VALUES ( '|| num || E',1,\'' || T || E'\')';
  --RAISE NOTICE 'running: %', sqlstring;
  EXECUTE sqlstring;
  i := i + 1;
  T := T + '5min';
  IF i = 289 THEN
    num := num + 1;
    IF num <= 3218201 THEN
      i := 1;
      T := t1;
      --sleep
      PERFORM pg_sleep(0.1);
      CONTINUE goto_label;    
    END IF; 
  END IF;
  END loop;
END;
$BODY$ LANGUAGE plpgsql;

do $$
DECLARE
daystring VARCHAR;
sqlstring TIMESTAMP;
rel VARCHAR;
k INTEGER;
BEGIN
k := 1;
WHILE k<365 LOOP
  daystring := 'SELECT CURRENT_DATE-interval  '|| E'\'' || k  || E' day\'';
  --RAISE NOTICE 'running: %', daystring;
  --获取execute的结果保存到变量
  execute daystring into sqlstring;
  --RAISE NOTICE 'running: %', sqlstring;
  select to_char(sqlstring, 'YYYYMMDD') into rel;
  PERFORM gen_min_day(rel);
  k := k+1;
END LOOP;

END;
$$ LANGUAGE plpgsql;

Ref
How pg_sleep() Works in PostgreSQL
Execut vs PERFORM