spring Exploration Business Development

Pending:

nexus local repository, upload and download jar package

 

jwt resolve

Design Spring Security and permissions system based JWT

https://www.codesheep.cn/2019/03/14/security-jwt-hibernate/

 

Table definitions, database tables migration, update


https://flywaydb.org/getstarted/firststeps/maven#creating-the-first-migration

The only field, unique_together 

unique_together = (('type_name', 'capability_name'))

 

Inquire:

精确(UserCopy1Example.andDescriptionEqualTo) done

模糊(UserCopy1Example.andDescriptionLike) done

Conditions sorting (UserCopy1Example.orderByClause) done

 

 

Enumeration: done

Java enumeration (enum) Detailed seven common usage

https://blog.csdn.net/qq_27093465/article/details/52180865

MyBaits enumeration types - the type using a database field in the string of numbers or the like where a non-enumerated type

https://blog.csdn.net/houyefeng/article/details/45886613

MyBatis database field mapping Java enum

https://blog.csdn.net/chidi5109/article/details/100599083

Mybatis enumeration mapping database stored int conversion

https://blog.csdn.net/zangdaiyang1991/article/details/86518088

SpringBoot integration Mybatis automatically converted enumeration type

https://blog.csdn.net/qq_26440803/article/details/83451221

General enumeration SpringBoot and MybatisPlus3.X integration of (XII)

https://www.cnblogs.com/dalianpai/p/11771269.html

 

Route management, the request processing

https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#webmvc-fn-router-functions

 

@Temporal(TemporalType.TIMESTAMP)
@Column
@JsonProperty("create_time")
@JsonDeserialize(using = EventCreateTimeDeserializer.class)
@JsonSerialize(using = EventCreateTimeSerializer.class)
@TableField(typeHandler = EventCreateTimeHandler.class)
@Future(message = "时间在当前时间之后才可以通过")
private java.util.Date createTime;

post http://localhost:9000/log/

EventCreateTimeDeserializer.deserialize
Entity:
 setCreateTime
 setLevel
@Future(message = "时间在当前时间之后才可以通过")
private java.util.Date createTime;
 getEffectiveTemporalValidationTolerance
 FutureValidatorForDate.getInstant
 AbstractFutureInstantBasedValidator.is_valid
EventLevelValidator
long id = this.getBaseMapper().insert(event);
getCreateTime

[2020-02-13 14:57:42.646]  [DEBUG] <http-nio-9000-exec-1> org.apache.ibatis.logging.jdbc.BaseJdbcLogger:143   ==>  Preparing: INSERT INTO tianshu_log_event ( create_time, content, level, owner, description ) VALUES ( ?, ?, ?, ?, ? )  
 

EventCreateTimeHandler.setParameter
EventLevelHandler.setParameter


return this.getById(event.getId());
setCreateTime、setLevel
EventCreateTimeSerializer.serialize

controller(RestController),model(Entity、Domain),view

Ma Ying-jeou: Chapter 6 Web MVC REST application

https://coding.imooc.com/class/chapter/252.html#Anchor

 

Data validation:

Quick start Spring Boot parameters check

https://mp.weixin.qq.com/s?__biz=MzUxOTc4NjEyMw==&mid=2247484258&idx=1&sn=a88dd960fd183f2f834a96489d643583&chksm=f9f51886ce829190645896f86083183d69066698a1264bcdd8784dabf03f5c0b7d2c50408701&mpshare=1&scene=24&srcid=0517wvmU7j3SiGApLmBIq44I#rd

Spring Boot parameter check (the difference @Validated and @Valid, custom check, check how nested)

https://blog.csdn.net/Howinfun/article/details/90287047

packet checksum validation-api nested property (a collection of objects) wording

https://blog.csdn.net/huangdi1309/article/details/89673875

 

Brother Mark: Section XII verification  ( courseware[Q ]

 

Serialization and de-serialization


 

Ma Ying-jeou: Chapter 6 Web MVC REST application

https://coding.imooc.com/class/chapter/252.html#Anchor/

accessing-data-mysql

https://spring.io/guides/gs/accessing-data-mysql/

CRUD

 

Associated foreign key (one to one, many-to-many foreign key delete behavior: CASCADE, PROTECT, SET_NULL, SET_DEFAULT, SET):

 

分页(userCopy1Repository.getPageList(page, pageSize),

PagingAndSortingRepository)

https://github.com/pagehelper/Mybatis-PageHelper

Bulk operations, delete (SimpleJpaRepository)

Persistence API section VIII of the Java  ( courseware ) (Note: only functions to achieve here, since jpa do a lot of packaging, then consider the performance or use mybatis)

Atomic operation?
.setCommit (false)

.setCommit(true)

https://segmentfault.com/n/1330000009887617

Custom response

https://blog.csdn.net/shenszy/article/details/85676415

httpClient

rest Template

 

createTime--> create_time

asynchronous

http://www.spring4all.com/article/540

Not implemented, the problems encountered:

spring boot2 EnableAysnc If the controller requires proxying (e.g. due to @Transactional), please us

Bale

1 jar command line to run

java -jar target\msgcenter-0.0.1-SNAPSHOT.jar

2 war tmocat running in the container, is provided as follows:

Deployment
docker

http://www.spring4all.com/article/557

application.yml

# Logger Config
logging:
  level:
    root: info # 全局
    ik.starriver.msgcenter: debug # 包级别
  pattern:
    console: '%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){magenta}  %clr([%5p])  %highlight(%C:%L)   %m %n'
    file: '%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){magenta}  %clr([%5p])  %highlight(%C:%L)   %m %n'
    # 默认日志文件名
  file: test.log
  # 默认日志路径
  path: ./log
  # logback.xml路径,默认为classpath:logback.xml
  # config: ./logback.xml
#app
server:
  port: 9000

#spring
spring:
  output:
    ansi:
      enabled: ALWAYS
  devtools:
    restart:
      enabled: false

  # mysql DATABASE CONFIG
  datasource:
    # 使用druid数据源
    #    type: com.alibaba.druid.pool.DruidDataSource
    type: org.apache.commons.dbcp2.BasicDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://10.1.252.23:3306/springtest?serverTimezone=UTC
    username: root
    password: 123456
    filters: stat
    maxActive: 20
    initialSize: 1
    maxWait: 60000
    minIdle: 1
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: select 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    maxOpenPreparedStatements: 20
    # dbcp2
    dbcp2:
      url: jdbc:mysql://10.1.252.23:3306/springtest?serverTimezone=UTC
      username: root
      password: '%tBqnWF1y3ku'
      maxTotal: 20
      maxIdle: 5
      driverClassName: com.mysql.cj.jdbc.Driver

  jpa:
    open-in-view: false
    database: MYSQL
    databasePlatform: org.hibernate.dialect.MySQL5InnoDBDialect
    generateDdl: true
    hibernate:
      ddlAuto: update

#mybatis
mybatis-plus:
  mapper-locations: classpath:/mapper*/*Mapper.xml
  #实体扫描,多个package用逗号或者分号分隔
  typeAliasesPackage: ik.starriver.msgcenter.entity
  #  typeEnumsPackage: com.baomidou.springboot.entity.enums
  global-config:
    # 数据库相关配置
    db-config:
      #      table-prefix: tianshu_log_
      #主键类型  AUTO:"数据库ID自增", INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
      #      id-type: ASSIGN_ID
      #字段策略 IGNORED:"忽略判断",NOT_NULL:"非 NULL 判断"),NOT_EMPTY:"非空判断"
      field-strategy: not_empty
      #驼峰下划线转换
      column-underline: true
      #数据库大写下划线转换
      #capital-mode: true
      #逻辑删除配置
      logic-delete-value: 0
      logic-not-delete-value: 1
      db-type: mysql
    #刷新mapper 调试神器
    refresh: true
  # 原生配置
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: false

pom.xml

<?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.3.0.M1</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>ik.starriver</groupId>
	<artifactId>msgcenter</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>msgcenter</name>
	<description>msgcenter project for starriver</description>

	<properties>
		<java.version>1.8</java.version>
		<mybatis-plus-boot-starter.version>3.3.1</mybatis-plus-boot-starter.version>
		<docker.image.prefix>starriver</docker.image.prefix>
<!--		<dockerfile.maven.version>1.3.4</dockerfile.maven.version>-->
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-dbcp2</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-validation</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.dataformat</groupId>
			<artifactId>jackson-dataformat-xml</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<!--	mybatis-plus start	-->
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>${mybatis-plus-boot-starter.version}</version>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<!--	mybatis-plus end	-->
	</dependencies>

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

	<repositories>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
		</repository>
	</repositories>
	<pluginRepositories>
		<pluginRepository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
		</pluginRepository>
	</pluginRepositories>

</project>

Bale:

D:\shen\java\webdevelop\spring\msgcenter>java -jar target\msgcenter-0.0.1-SNAPSHOT.jar

Upload jar package to the deployment environment:

 Dockerfile

Command line: docker run -e "JAVA_OPTS = -Xmx52m" app-image

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD msgcenter-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 9000
ENV JAVA_OPTS="-Xmx52m"
ENV DATABASE_URL="--spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springtest"
ENV DATABASE_USERNAME="--spring.datasource.username=root"
ENV DATABASE_PASSWORD="--spring.datasource.password=123456"
ENTRYPOINT exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar $DATABASE_URL $DATABASE_USERNAME $DATABASE_PASSWORD
# 启动命令模式为:exec java $JAVA_OPTS(jvm的参数) xxx-app.jar $SPRING_OPTIONS(spring的参数)

Docker-compose.yml

[root@shen msgcenter]# cat docker-compose.yml 
version: "3"
services:
  web:
    build: .
    image: msgcenter
    ports: ['9000:9000']
    #command: ["/bin/bash", "start.sh"]
    # command: ["uwsgi", "--ini", "uwsgi.ini"]
    #environment:
     # - ALLOW_HOST=*
      #- DB_HOST=10.1.252.23
      #- DB_PORT=3306
      #- DB_USER=root
      #- DB_PASSWORD=%tBqnWF1y3ku
      #- DB_NAME=tianshu_data_dict
    # volumes: ['.:/code']

docker-deploy.py  

[root@shen msgcenter]# cat docker-deploy.py 
import re
import os

DOCKER_COMPOSE_IMAGE_NAME = "msgcenter"


def stop_container():
    p = os.popen('docker ps')
    output = p.read()
    # print(output)
    pattern = re.compile(".*{}".format(DOCKER_COMPOSE_IMAGE_NAME))
    try:
        container_id = re.search(pattern, output).group().split()[0]
        if not container_id:
            return
        p = os.popen('docker stop {}'.format(container_id))
        output = p.read()
        print("docker stop {}".format(output))
    except (AttributeError, ) as e:
        print("stop_container: {}".format(str(e)))


def docker_compose():
    p = os.popen('docker-compose up -d --build')
    output = p.read()
    print(output)


def docker_ps():
    print("------------------")
    docker_ps_cmd = 'docker ps|grep {}'.format(DOCKER_COMPOSE_IMAGE_NAME)
    print(docker_ps_cmd)
    p = os.popen(docker_ps_cmd)
    output = p.read()
    print(output)


if __name__ == "__main__":
    stop_container()
    docker_compose()
    docker_ps()

Generated image, and start docker

[root@shen msgcenter]# python3 docker-deploy.py 
 

PS:

cli dynamic way incoming global variables:

D:\shen\java\webdevelop\spring\log>java -jar target\log-0.0.1-SNAPSHOT.jar

--spring.datasource.url=

jdbc:mysql://10.1.252.23:3306/springisp?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf8

--spring.profiles.active=pro

--spring.datasource.username=root

--spring.datasource.password=123456
 

Official website deployment documentation

https://docs.spring.io/spring-boot/docs/current/reference/html/deployment.html#containers-deployment

FROM openjdk:8-jdk-alpine AS builder
WORKDIR target/dependency
ARG APPJAR=target/*.jar
COPY ${APPJAR} app.jar
RUN jar -xf ./app.jar

FROM openjdk:8-jre-alpine
VOLUME /tmp
ARG DEPENDENCY=target/dependency
COPY --from=builder ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=builder ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=builder ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.example.MyApplication"]

 

Database time zone issue

Such misunderstandings and JDBC MySQL, resulting in a time stamp is actually stored in the database, and the service system to take the difference between the value of the 13 or 14 hours, this time with the United States is (= 13) No (= 14) daylight saving when closely related.

solve:

mysql> set global time_zone = '+08:00';
Query OK, 0 rows affected (0.00 sec)
 
mysql> set time_zone = '+08:00';
Query OK, 0 rows affected (0.00 sec)

https://blog.csdn.net/qq_30553235/article/details/79612824 

 

restdocs

https://www.cnblogs.com/qq350760546/p/8397557.html

https://docs.spring.io/spring-restdocs/docs/2.0.4.RELEASE/reference/html5/#introduction

http://www.spring4all.com/article/3333

 

http request class structure:

RestTemplate
@Test
    public void test() {
        final String url = "http://localhost:9000/log/?page=2&pageSize=2&orderBy=level&direction=desc&searchName=content&searchValue=con&nameLike=true";
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
        requestHeaders.add("Authorization", "Bearer test");
        RestTemplate template = new RestTemplate();
        HttpEntity<String> requestEntity = new HttpEntity<String>(null, requestHeaders);
        ResponseEntity<String> response = template.exchange(url, HttpMethod.GET, requestEntity, String.class);
        String result = response.getBody();
        System.err.println(result);
    }

 

MockMvc

 

@SpringBootTest
@AutoConfigureMockMvc
@AutoConfigureRestDocs(uriPort = 9000)
public class RestControllerTest {

    @Autowired
    private MockMvc mockMvc;

@Test
    void testGetEventPage() throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.put("Content-Type", Arrays.asList(MediaType.APPLICATION_JSON_VALUE));
        headers.put("Authorization", Arrays.asList("Bearer dXNlcjpzZWNyZXQ="));

        this.mockMvc.perform(get("/log/?page=2&pageSize=2&orderBy=level&direction=desc&searchName=content&searchValue=con&nameLike=true").headers(headers))
                .andExpect(status().isOk())
                .andDo(document("eventPage",
                        requestHeaders(
                                headerWithName("Content-Type").description(
                                        "desc Content-Type"),
                                headerWithName("Authorization").description(
                                        "JWT token: Bearer dXNlcjpzZWNyZXQ=")),
                        requestParameters(
                            parameterWithName("page").description("The page to retrieve"),
                            parameterWithName("pageSize").description("Entries per page"),
                            parameterWithName("orderBy").description("Entries orderBy"),
                            parameterWithName("direction").description("Entries orderBy direction"),
                            parameterWithName("searchName").description("filter by column name"),
                            parameterWithName("searchValue").description("filter by column name's value"),
                            parameterWithName("nameLike").description("use name like or not")
                        )
//                        responseHeaders(
//                                headerWithName("X-RateLimit-Reset").description(
//                                        "Time at which the rate limit period will reset"))
                ));
    }


 

Published 105 original articles · won praise 33 · views 30000 +

Guess you like

Origin blog.csdn.net/github_38596081/article/details/104076322