SpringBoot

一、导读

1、开发工具及技术栈

  • JDK:jdk1.8.0_191
  • 开发工具:IntelliJIDEA 2020.3.2
  • SpringBoot:
    • 简化Spring的开发
    • 需要一定的java基础
    • 有Spring、SpringMVC、Mybatis框架知识
  • Maven
  • Magic-Api
  • JWT

二、SpringBoot

1、概述

SpringBoot 提供了一种快速使用Spring的方式,基于约定优于配置的思想,可以让开发人员不必在配置和逻辑业务之间进行思维的切换,全身心投入到逻辑业务的代码编写中,从而大打提高开发的效率。一定程度上缩短了开发周期。

2、功能

  1. 自动配置

    SpringBoot是一个运行时的过程,就是程序启动的时候,考虑众多因素,才会决定Spring配置应该用哪个,不该用哪个,该过程时自动的。

  2. 起步依赖

    是一个Maven模型,根据POM定义了其他库的依赖传递,简单说就是把具备某些功能的坐标打包到一起,并提供一些默认的功能。

  3. 辅助功能

    比如嵌入式服务器、安全、指标、健康监测、外部配置等。

  • SpringBoot提供了一种快速开发Spring项目的方式,而不是Spring功能上的增强。

3、快速入门

3.1、pom

<?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.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.tjhis</groupId>
<artifactId>hisApi</artifactId>
<version>1.0.2</version>
<name>hisApi</name>
<description>hisApi</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<!-- 引入magic-api-spring-boot-starter依赖。-->
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-spring-boot-starter</artifactId>
<version>2.0.2</version>
</dependency>
<!-- 定时任务 -->
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-plugin-task</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Oracle驱动 -->
<!-- <dependency>-->
<!-- <groupId>com.oracle.database.jdbc</groupId>-->
<!-- <artifactId>ojdbc8</artifactId>-->
<!-- <scope>runtime</scope>-->
<!-- </dependency>-->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.4</version>
</dependency> <dependency>
<groupId>com.oracle.database.nls</groupId>
<artifactId>orai18n</artifactId>
<version>19.7.0.0</version>
</dependency>
<!-- 日志监控,Druid 用 -->
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- Druid https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- properti.yml的配置文件处理器,写yml文件时会有提示 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- Lombok项目是一个java库,它可以自动插入到编辑器和构建工具中,增强java的性能。
不需要再写getter、setter或equals方法,只要有一个注解,你的类就有一个功能齐全的构建器、自动记录变量等等。 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- JWT -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
<!-- hutool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.10</version>
</dependency>
<!-- bouncycastle SM2 加密 -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15to18</artifactId>
<version>1.69</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>
  • 增加启动引导类

    package cn.tjhis.api;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
    public class ApiApplication {
    public static void main(String[] args) {
    SpringApplication.run(ApiApplication.class, args);
    }
    }

3.2、配置文件

## 生产环境
server:
port: 9908
# 配置静态资源启用 gzip 压缩
compression:
enabled: true
min-response-size: 128
# 配置主数据源
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
datasource:
driver-class-name: oracle.jdbc.OracleDriver #oracle.jdbc.driver.OracleDriver
username: system
password: manager
#url: jdbc:oracle:thin:@192.168.11.10:1521/orcl
url: jdbc:wrap-jdbc:filters=encoding:jdbc:oracle:thin:@//localhost:1521/orcl
type: com.alibaba.druid.pool.DruidDataSource
#Spring Boot 默认是不注入这些属性值的,需要自己绑定
#druid 数据源专有配置 ,必须导入 druid-spring : 1.1.10 才能配置以下参数
druid:
# 处理Oracle的英文字符集乱码的问题,中文字符集屏蔽该行
#connection-properties: serverEncoding=ISO-8859-1;clientEncoding=GBK
initialSize: 5
minIdle: 5
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,log4j2
# StatViewServlet配置 sql监控
stat-view-servlet:
enabled: true
url-pattern: "/druid/*"
reset-enable: false
login-username: admin
login-password: Admin@123
#允许那些ip
allow: 127.0.0.1,192.168.120.93
#禁止那些ip
deny: 192.168.120.93
# WebStatFilter配置 web-jdbc关联监控
web-stat-filter:
enabled: true
url-pattern: "/*"
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
filter:
stat:
enabled: true
merge-sql: true
# data:
# 配置mongo数据源
# mongodb:
# host: localhost
# port: 27017
# database: magicapi
# username: magicapi
# password: 123456
# 配置redis数据源
# redis:
# host: localhost
# port: 6379
# database: 4
# timeout: 5000
magic-api:
web: /magic/web
security:
username: admin # 登录用户名
password: Admin@123 # 登录密码
resource:
# type: database # 配置接口存储方式,这里选择存在数据库中
# table-name: magic_api_file # 数据库表名
prefix: /api # key前缀
location: d:/magic-api
# 配置打印SQL
show-sql: true
date-pattern: yyyy-MM-dd HH:mm:ss
page:
size: size # 页大小的参数名称
page: page # 页码的参数名称
default-page: 1 # 未传页码时的默认首页
default-size: 10 # 未传页大小时的默认页大小
prefix: api # 接口前缀,可以不配置
sql-column-case: camel # 启用驼峰命名转换
backup: #备份相关配置
enable: false #是否启用
max-history: -1 #备份保留天数,-1为永久保留
datasource: magic #指定数据源(单数据源时无需配置,多数据源时默认使用主数据源,如果存在其他数据源中需要指定。)
table-name: magic_api_backup #使用数据库存储备份时的表名
response-code:
success: 200 #执行成功的code值
invalid: 400 #参数验证未通过的code值
exception: 500 #执行出现异常的code值
response: |- # 配置JSON格式,格式为magic-script中的表达式
{
code: code,
message: message,
data,
timestamp,
requestTime,
executeTime,
}
throw-exception: true
task:
thread-name-prefix: magic-task- #线程池名字前缀
pool:
size: 8 #线程池大小,默认值为CPU核心数
shutdown:
awaitTermination: false #关闭时是否等待任务执行完毕,默认为false
awaitTerminationPeriod: 10s # 关闭时最多等待任务执行完毕的时间
# 更多配置 https://ssssssss.org/magic-api/config/
person:
name: 张三
address:
- 北京
- 丰台
- 富丰桥
age: 16
  • 创建Controller

  • 小结

    • 在创建项目时,默认使用jar打包方式,因为用main函数启动的。
    • 启动引导类是项目的入口。

4、Magic-api

4.1、简介

  • magic-api 是一个基于Java的接口快速开发框架,编写接口将通过magic-api提供的UI界面完成,自动映射为HTTP接口,无需定义Controller、Service、Dao、Mapper、XML、VO等Java对象即可完成常见的HTTP API接口开发。

  • 之前我们开发一个接口,至少需要Controller,Service,Dao,Mapper文件,还需要各种配置,搭建启动springboot项目,发布完成,接口才能访问,接口才算完成。

    而magic要做的就是通过UI界面动态的配置一下接口路径,出入参,点击保存,接口发布完成,即可访问,不需要编写代码,只需要简单配置,还支持事物,分页,http请求等数据库操作,有点类似于现在的低代码平台

  • 特性

    支持MySQL、MariaDB、Oracle、DB2、PostgreSQL、SQLServer 等支持jdbc规范的数据库

    支持非关系型数据库Redis、Mongodb

    支持集群部署、接口自动同步。

    支持分页查询以及自定义分页查询

    支持多数据源配置,支持在线配置数据源

    支持SQL缓存,以及自定义SQL缓存

    支持自定义JSON结果、自定义分页结果

    支持对接口权限配置、拦截器等功能

    支持运行时动态修改数据源

    支持Swagger接口文档生成

    基于magic-script脚本引擎,动态编译,无需重启,实时发布

    支持Linq式查询,关联、转换更简单

    支持数据库事务、SQL支持拼接,占位符,判断等语法

    支持文件上传、下载、输出图片

    支持脚本历史版本对比与恢复

    支持脚本代码自动提示、参数提示、悬浮提示、错误提示

    支持导入Spring中的Bean、Java中的类

    支持在线调试

    支持自定义工具类、自定义模块包、自定义类型扩展、自定义方言、自定义列名转换等自定义操作

4.2、Magic-api 增删改查

  • Oracle的表名必须用双引号,才能好使
// 新增
return db.table('test_data').insert({ id : 4, name : 'admin'})
return db.table('test_data').primary('id').save({ id : 4, name : 'admin'})
return db.table(\'user\').insert(body);
// oracle只有这种方法好使,成功之后返回rowid
var sql = """ insert into SCOTT.DEPT (DEPTNO,DNAME,LOC) values (#{DEPTNO},#{DNAME},#{LOC})"""
return db.insert(sql,body)
// 表名必须用双引号,才能好使,实际上不是,在这种状态不能开启驼峰sql-column-case ,如果需要驼峰,可以用db.camel()
return db.table("SCOTT.DEPT").insert(body) // 更新
return db.table('test_data').primary('id').update({ id: 4, name : '张三峰'})
return db.update(\'update user set userName=\‘李四\’ where id=#{id}\') // 删除
return db.table('test_data').primary('id').where().eq('id',4).delete()
return db.update(\'delete from user where id=#{id}\') // 查询单条:路径变量从path对象中获取
return db.table(\'user\')
.where()
.eq(\'id\',path.id)
.selectOne();
return db.selectValue('select username from user where id = #{id}') return db.camel().selectOne('select * from user where id = #{id} ')
return db.selectInt('select count(*) from user') // 查询所有
var sql = """
select dept_code,dept_name from dept_dict
"""
return db.camel().select(sql)
return db.camel().select('select * from user')
return db.camel().table("dept_dict").select() // 分页 ,由于已经在application.yml中配置好了分页参数,可直接使用,下面第7项中有更详细的分页
return db.camel().table(\'user\').page();
return db.camel().page(sql);
// 从第11行开始取10行
return db.camel().table("dept_dict").page(10,11) // 动态拼接
return db.camel().select("select * from sys_user ?{id,where id = #{id}}"); // 当id有值时,生成SQL:select * from sys_user where id = ?`,
// 当id无值时,生成SQL:select * from sys_user
return db.select("select * from sys_user ?{id!=null&&id.length() > 3,where id = #{id}}");
// 当id!=null&&id.length() > 3判断为true时,生成SQL:`select * from sys_user where id = ?
// 当判断为false时,生成SQL:select * from sys_user // 模糊查询
return db
.camel()
.table("dept_dict")
.columns('dept_code','dept_name')
.where()
.like('dept_code','01%')
.like('dept_name','%疗区')
.page()

4.3、参数获取

  • ### 这样的`URL`参数`magic-api` 会自动将`name`和`age`映射为同名变量。
    GET http://localhost:9999/xxx/xxx?name=abc&age=49
  • Post也会映射为同名参数

  • POST请求:使用body对象可以直接获取请求body中的参数,例如

    {
    "name": "magic-api",
    "version": "9.9.9"
    }
    ## 如要获取name属性 则可通过 body.name 来获取
  • Path参数获取:路径变量从path对象中获取,GET请求,请求路径为/detail/

  • 如要获取heade中的 token 可以通过header.token 来获取

4.4、校验

  • assert在 2.0 已经被弃用
//import assert;  //导入断言模块
// 验证不通过时,会终止运行
//assert.notEmpty(body.name,400,'名称不能为空!');
//assert.notEmpty(body.firstLetter,400,'首字母不能为空!');
//return db.table('pms_brand').insert(body); if (pageSize==null || pageSize==0){
pageSize=10
}
if (pageIndex==null || pageIndex==0){
exit 400, '页码不能为空!';
}
// 类型转换
pageSize= pageSize::int
pageIndex= pageIndex::int
var sql = """
select dept_code,dept_name from dept_dict
"""
return db.page(sql,pageSize,pageSize * (pageIndex - 1))

4.7、切换数据源

// 从数据源key定义为slave的库中查询
return db.slave.select("""
select * from sys_user
""")

4.8、事物

// 自动事务
var val = db.transaction(()=>{
var v1 = db.update('...');
var v2 = db.update('....');
return v2;
});
return val; // 手动事务
var tx = db.transaction(); //开启事务
try{
var value = db.update('...');
tx.commit(); // 提交事务
return value;
}catch(e){
tx.rollback(); // 回滚事务
}

4.9、结果转换

var list = db.table('comm.dept_dict').select();
return list.map((item)=>{
code : item.deptCode,
name : item.deptName,
showStatus : item.clinicAttr==0? '临床' : '其它'
});

4.10、java访问magic

  • 配置文件中的magic的配置不要加prefix,否则在java无总是报找不到路径

  • 建议方法用execute,不要用call

    • execute内部调用接口不包含code以及message信息,同时也不走拦截器。
    • call内部调用接口包含code以及message信息,同时也不走拦截器。
  • 代码

    @RestController
    public class LoginController {
    private final MagicAPIService service;
    private static final Logger logger = LoggerFactory.getLogger(CustomRequestInterceptor.class); public LoginController(MagicAPIService service) {
    this.service = service;
    } @GetMapping("/login")
    public Object login(String userName, String password) {
    Map<String, Object> params = new HashMap<>();
    // 注入变量信息
    params.put("userName", userName);
    // 内部调用接口不包含code以及message信息,同时也不走拦截器。
    Object value = service.call("GET", "/comm/getUserByUserName", params);
    logger.info(value.toString());
    return null;
    }
    }

4.11、magic访问java

import cn.tjhis.hisapi.config.JwtConfig;
var jwt = JwtConfig.parse(header.token)
return jwt.payloads.id;

5、properties.yml

  • 优先级:properties.properties > properties.yml > properties.yaml

  • 获取值

    • @Value

      @RestController
      public class TestController {
      @Value("${spring.jackson.date-format}")
      private String dataFormat;
      @GetMapping("/test")
      public String getTest(){
      return "Hello,王红晓," + dataFormat;
      }
      }
  • Environment

    @RestController
    public class TestController {
    // 不建议使用Autowired注解,而是用构造的方法注入
    private final Environment env; public TestController(Environment env) {
    this.env = env;
    } @GetMapping("/test")
    public String getTest() {
    return "Hello,王红晓," + env.getProperty("spring.jackson.date-format");
    }
    }
  • @ConfigurationProperties

    person:
    name: 张三
    age: 18
    address:
    - 北京
    - 丰台
    - 富丰桥

    // 定义映射的实体类

    package cn.tjhis.hisapi.entity;

    import lombok.Data;

    import org.springframework.boot.context.properties.ConfigurationProperties;

    import org.springframework.context.annotation.PropertySource;

    import org.springframework.stereotype.Component;

    @Component

    @ConfigurationProperties(prefix = "person")

    @Data

    public class Person {

    private String name;

    private int age;

    private String[] address;

    }

    // 使用

    import cn.tjhis.hisapi.entity.Person;

    import org.springframework.core.env.Environment;

    import org.springframework.web.bind.annotation.GetMapping;

    import org.springframework.web.bind.annotation.RestController;

    @RestController

    public class TestController {

    private final Environment env;

    private final Person person;

    public TestController(Environment env, Person person) {

    this.env = env;

    this.person = person;

    }

      @GetMapping("/test")
    public String getTest() {
    return "Hello,王红晓," + person;
    }

    }

6、profile

  • 激活

    spring:
    profiles:
    active: test
  • active对应的配置文件为:application-XXX.yml,其中XXX即可为active的值

  • 文件名

    • application-test.yml:测试环境
    • application-dev.yml:开发环境
    • application-pro.yml:生产环境
  • 虚拟机启动方式:

    • 启动配置里面VM加:-Dspring.profiles.active=pro
  • jar包启动方式

    • 在jar包的cmd命令行输入java -jar ./hisApi-1.0.1.jar --spring.profiles.active=test
    • 直接拷贝个文件和jar包平级application.yml,会优先启用该配置文件,其他配置也会被加载,但是会被当前的文件覆盖,如果放到config文件中,优先级会更高。运行命令:java -jar ./hisApi-1.0.1.jar

7、druid

8、idea快捷键

一、常用快捷键

Ctrl + F12 弹出当前文件结构层(类的方法属性等),可以在弹出的层上直接输入,进行筛选

Ctrl + 左键单击 在打开的文件标题上,弹出该文件路径

Ctrl + N 根据输入的 类名 查找类文件

Ctrl + D 复制光标所在行 或 复制选择内容,并把复制内容插入光标位置下面

Ctrl + P 方法参数提示显示

Ctrl + Alt + O 优化导入的类,可以对当前文件和整个包目录使用

Alt + Insert 代码自动生成,如生成对象的 set / get 方法,构造函数,toString() 等

Shift + F6 对文件 / 文件夹 重命名

Ctrl + Shift + Enter 自动结束代码,行末自动添加分号

Ctrl + B 找变量、方法、类等的来源或者使用过的地方

Ctrl + Alt + B 在某个调用的方法名上使用会跳到具体的实现处,可以跳过接口

Ctrl + Q 光标所在的变量 / 类名 / 方法名等上面(也可以在提示补充的时候按),显示文档内容

Ctrl + Alt + T 对选中的代码弹出环绕选项弹出层(try,if等语句包裹)

Ctrl + Alt + L 格式化代码,可以对当前文件和整个包目录使用

Ctrl + Alt + 左方向键 退回到上一个操作的地方

Ctrl + Alt + 右方向键 前进到上一个操作的地方

Ctrl + Shift + J 自动将下一行合并到当前行末尾

Alt + F8 在 Debug 的状态下,选中对象,弹出可输入计算表达式调试框,查看该输入内容的调试结果

连按两次Shift 弹出 Search Everywhere 弹出层

Alt + F7 查找光标所在的方法 / 变量 / 类被调用的地方

Ctrl + Alt + F7 显示使用的地方。寻找被该类或是变量被调用的地方,用弹出框的方式找出来

Ctrl + F 在当前文件进行文本查找

Ctrl + Shift + F 根据输入内容查找整个项目 或 指定目录内文件

Ctrl + R 在当前文件进行文本替换

Ctrl + Shift + R 根据输入内容替换对应内容,范围为整个项目 或 指定目录内文件

Ctrl + H 显示当前类的层次结构

Ctrl + Alt + H 调用层次

Ctrl + Shift + H 显示方法层次结构

Ctrl + W 递进式选择代码块。可选中光标所在的单词或段落,连续按会在原有选中的基础上再扩展选中范围

Ctrl + Shift + W 递进式取消选择代码块。可选中光标所在的单词或段落,连续按会在原有选中的基础上再扩展取消选中范围

Ctrl + [ 移动光标到当前所在代码的花括号开始位置

Ctrl + ] 移动光标到当前所在代码的花括号结束位置

Ctrl + Shift + [ 选中从光标所在位置到它的顶部中括号位置

Ctrl + Shift + ] 选中从光标所在位置到它的底部中括号位置

Ctrl + O 选择可重写的方法

Ctrl + I 选择可实现的方法

Ctrl + Y 删除光标所在行 或 删除选中的行

Ctrl + X 剪切光标所在行 或 剪切选择内容

Ctrl + G 在当前文件跳转到指定行处

Ctrl + Q 光标所在的变量 / 类名 / 方法名等上面(也可以在提示补充的时候按),显示文档内容

Ctrl + U 前往当前光标所在的方法的父类的方法 / 接口定义

Ctrl + End 跳到文件尾

Ctrl + Home 跳到文件头

Alt + ` 显示版本控制常用操作菜单弹出层

Alt + Enter 根据光标所在问题,提供快速修复选择,光标放在的位置不同提示的结果也不同

Shift + ESC 隐藏当前 或 最后一个激活的工具窗口

Shift + End 选中光标到当前行尾位置

Shift + Home 选中光标到当前行头位置

Shift + Enter 开始新一行。光标所在行下空出一行,光标定位到新行位置

Shift + 左键单击 在打开的文件名上按此快捷键,可以关闭当前打开文件

Ctrl + Alt + I 光标所在行 或 选中部分进行自动代码缩进,有点类似格式化

Ctrl + Alt + Space 类名自动完成

Ctrl + Shift + N 通过文件名定位 / 打开文件 / 目录,打开目录需要在输入的内容后面多加一个正斜杠

Ctrl + Shift + U 对选中的代码进行大 / 小写轮流转换

Ctrl + Shift + / 代码块注释

Ctrl + Shift + Backspace 退回到上次修改的地方

Ctrl + Shift + F12 编辑器最大化

Ctrl + Shift + 左键单击 把光标放在某个类变量上,按此快捷键可以直接定位到该类中

二、Ctrl相关

Ctrl + F 在当前文件进行文本查找 (必备)

Ctrl + R 在当前文件进行文本替换 (必备)

Ctrl + Z 撤销 (必备)

Ctrl + Y 删除光标所在行 或 删除选中的行 (必备)

Ctrl + X 剪切光标所在行 或 剪切选择内容

Ctrl + C 复制光标所在行 或 复制选择内容

Ctrl + D 复制光标所在行 或 复制选择内容,并把复制内容插入光标位置下面 (必备)

Ctrl + W 递进式选择代码块。可选中光标所在的单词或段落,连续按会在原有选中的基础上再扩展选中范围 (必备)

Ctrl + E 显示最近打开的文件记录列表

Ctrl + N 根据输入的 类名 查找类文件

Ctrl + G 在当前文件跳转到指定行处

Ctrl + J 插入自定义动态代码模板

Ctrl + P 方法参数提示显示

Ctrl + Q 光标所在的变量 / 类名 / 方法名等上面(也可以在提示补充的时候按),显示文档内容

Ctrl + U 前往当前光标所在的方法的父类的方法 / 接口定义

Ctrl + B 进入光标所在的方法/变量的接口或是定义处,等效于 Ctrl + 左键单击

Ctrl + K 版本控制提交项目,需要此项目有加入到版本控制才可用

Ctrl + T 版本控制更新项目,需要此项目有加入到版本控制才可用

Ctrl + H 显示当前类的层次结构

Ctrl + O 选择可重写的方法

Ctrl + I 选择可继承的方法

Ctrl + + 展开代码

Ctrl + - 折叠代码

Ctrl + / 注释光标所在行代码,会根据当前不同文件类型使用不同的注释符号 (必备)

Ctrl + [ 移动光标到当前所在代码的花括号开始位置

Ctrl + ] 移动光标到当前所在代码的花括号结束位置

Ctrl + F1 在光标所在的错误代码处显示错误信息

Ctrl + F3 调转到所选中的词的下一个引用位置

Ctrl + F4 关闭当前编辑文件

Ctrl + F8 在 Debug 模式下,设置光标当前行为断点,如果当前已经是断点则去掉断点

Ctrl + F9 执行 Make Project 操作

Ctrl + F11 选中文件 / 文件夹,使用助记符设定 / 取消书签

Ctrl + F12 弹出当前文件结构层,可以在弹出的层上直接输入,进行筛选

Ctrl + Tab 编辑窗口切换,如果在切换的过程又加按上delete,则是关闭对应选中的窗口

Ctrl + Enter 智能分隔行

Ctrl + End 跳到文件尾

Ctrl + Home 跳到文件头

Ctrl + Space 基础代码补全,默认在 Windows 系统上被输入法占用,需要进行修改,建议修改为 ALT+/(必备)

Ctrl + Delete 删除光标后面的单词或是中文句

Ctrl + BackSpace 删除光标前面的单词或是中文句

Ctrl + 1,2,3...9 定位到对应数值的书签位置

Ctrl + 左键单击 在打开的文件标题上,弹出该文件路径

Ctrl + 光标定位 按 Ctrl 不要松开,会显示光标所在的类信息摘要

Ctrl + 左方向键 光标跳转到当前单词 / 中文句的左侧开头位置

Ctrl + 右方向键 光标跳转到当前单词 / 中文句的右侧开头位置

Ctrl + 前方向键 等效于鼠标滚轮向前效果

Ctrl + 后方向键 等效于鼠标滚轮向后效果

三、Alt相关

Alt + ` 显示版本控制常用操作菜单弹出层

Alt + Q 弹出一个提示,显示当前类的声明 / 上下文信息

Alt + F1 显示当前文件选择目标弹出层,弹出层中有很多目标可以进行选择

Alt + F2 对于前面页面,显示各类浏览器打开目标选择弹出层

Alt + F3 选中文本,逐个往下查找相同文本,并高亮显示

Alt + F7 查找光标所在的方法 / 变量 / 类被调用的地方

Alt + F8 在 Debug 的状态下,选中对象,弹出可输入计算表达式调试框,查看该输入内容的调试结果

Alt + Home 定位 / 显示到当前文件的 Navigation Bar

Alt + Enter IntelliJ IDEA 根据光标所在问题,提供快速修复选择,光标放在的位置不同提示的结果也不同 (必备)

Alt + Insert 代码自动生成,如生成对象的 set / get 方法,构造函数,toString() 等(必备)

Alt + 左方向键 按左方向切换当前已打开的文件视图

Alt + 右方向键 按右方向切换当前已打开的文件视图

Alt + 前方向键 当前光标跳转到当前文件的前一个方法名位置

Alt + 后方向键 当前光标跳转到当前文件的后一个方法名位置

Alt + 1,2,3...9 显示对应数值的选项卡,其中 1 是 Project 用得最多

四、Shift相关

Shift + F1 如果有外部文档可以连接外部文档

Shift + F2 跳转到上一个高亮错误 或 警告位置

Shift + F3 在查找模式下,查找匹配上一个

Shift + F4 对当前打开的文件,使用新Windows窗口打开,旧窗口保留

Shift + F6 对文件 / 文件夹 重命名

Shift + F7 在 Debug 模式下,智能步入。断点所在行上有多个方法调用,会弹出进入哪个方法

Shift + F8 在 Debug 模式下,跳出,表现出来的效果跟 F9 一样

Shift + F9 等效于点击工具栏的 Debug 按钮

Shift + F10 等效于点击工具栏的 Run 按钮

Shift + F11 弹出书签显示层

Shift + Tab 取消缩进

Shift + ESC 隐藏当前 或 最后一个激活的工具窗口

Shift + End 选中光标到当前行尾位置

Shift + Home 选中光标到当前行头位置

Shift + Enter 开始新一行。光标所在行下空出一行,光标定位到新行位置

Shift + 左键单击 在打开的文件名上按此快捷键,可以关闭当前打开文件

Shift + 滚轮前后滚动 当前文件的横向滚动轴滚动

五、Ctrl + Alt相关

Ctrl + Alt + L 格式化代码,可以对当前文件和整个包目录使用 (必备)

Ctrl + Alt + M 提取方法:选中代码,快速抽取为方法 (必备)

Ctrl + Alt + O 优化导入的类,可以对当前文件和整个包目录使用 (必备)

Ctrl + Alt + I 光标所在行 或 选中部分进行自动代码缩进,有点类似格式化

Ctrl + Alt + T 对选中的代码弹出环绕选项弹出层

Ctrl + Alt + J 弹出模板选择窗口,将选定的代码加入动态模板中

Ctrl + Alt + H 调用层次

Ctrl + Alt + B 在某个调用的方法名上使用会跳到具体的实现处,可以跳过接口

Ctrl + Alt + V 快速引进变量

Ctrl + Alt + Y 同步、刷新

Ctrl + Alt + S 打开 IntelliJ IDEA 系统设置

Ctrl + Alt + F7 显示使用的地方。寻找被该类或是变量被调用的地方,用弹出框的方式找出来

Ctrl + Alt + F11 切换全屏模式

Ctrl + Alt + Enter 光标所在行上空出一行,光标定位到新行

Ctrl + Alt + Home 弹出跟当前文件有关联的文件弹出层

Ctrl + Alt + Space 类名自动完成

Ctrl + Alt + 左方向键 退回到上一个操作的地方 (必备)

Ctrl + Alt + 右方向键 前进到上一个操作的地方 (必备)

Ctrl + Alt + 前方向键 在查找模式下,跳到上个查找的文件

Ctrl + Alt + 后方向键 在查找模式下,跳到下个查找的文件

六、Ctrl + Shift相关

Ctrl + Shift + F 根据输入内容查找整个项目 或 指定目录内文件 (必备)

Ctrl + Shift + R 根据输入内容替换对应内容,范围为整个项目 或 指定目录内文件 (必备)

Ctrl + Shift + J 自动将下一行合并到当前行末尾 (必备)

Ctrl + Shift + Z 取消撤销 (必备)

Ctrl + Shift + W 递进式取消选择代码块。可选中光标所在的单词或段落,连续按会在原有选中的基础上再扩展取消选中范围 (必备)

Ctrl + Shift + N 通过文件名定位 / 打开文件 / 目录,打开目录需要在输入的内容后面多加一个正斜杠 (必备)

Ctrl + Shift + U 对选中的代码进行大 / 小写轮流转换 (必备)

Ctrl + Shift + T 对当前类生成单元测试类,如果已经存在的单元测试类则可以进行选择

Ctrl + Shift + C 复制当前文件磁盘路径到剪贴板

Ctrl + Shift + V 弹出缓存的最近拷贝的内容管理器弹出层

Ctrl + Shift + E 显示最近修改的文件列表的弹出层

Ctrl + Shift + H 显示方法层次结构

Ctrl + Shift + B 跳转到类型声明处

Ctrl + Shift + I 快速查看光标所在的方法 或 类的定义

Ctrl + Shift + A 查找动作 / 设置

Ctrl + Shift + / 代码块注释 (必备)

Ctrl + Shift + [ 选中从光标所在位置到它的顶部中括号位置

Ctrl + Shift + ] 选中从光标所在位置到它的底部中括号位置

Ctrl + Shift + + 展开所有代码

Ctrl + Shift + - 折叠所有代码

Ctrl + Shift + F7 高亮显示所有该选中文本,按Esc高亮消失

Ctrl + Shift + F8 在 Debug 模式下,指定断点进入条件

Ctrl + Shift + F9 编译选中的文件 / 包 / Module

Ctrl + Shift + F12 编辑器最大化

Ctrl + Shift + Space 智能代码提示

Ctrl + Shift + Enter 自动结束代码,行末自动添加分号 (必备)

Ctrl + Shift + Backspace 退回到上次修改的地方

Ctrl + Shift + 1,2,3...9 快速添加指定数值的书签

Ctrl + Shift + 左键单击 把光标放在某个类变量上,按此快捷键可以直接定位到该类中 (必备)

Ctrl + Shift + 左方向键 在代码文件上,光标跳转到当前单词 / 中文句的左侧开头位置,同时选中该单词 / 中文句

Ctrl + Shift + 右方向键 在代码文件上,光标跳转到当前单词 / 中文句的右侧开头位置,同时选中该单词 / 中文句

Ctrl + Shift + 左方向键 在光标焦点是在工具选项卡上,缩小选项卡区域

Ctrl + Shift + 右方向键 在光标焦点是在工具选项卡上,扩大选项卡区域

Ctrl + Shift + 前方向键 光标放在方法名上,将方法移动到上一个方法前面,调整方法排序

Ctrl + Shift + 后方向键 光标放在方法名上,将方法移动到下一个方法前面,调整方法排序

七、Alt + Shift相关

Alt + Shift + N 选择 / 添加 task

Alt + Shift + F 显示添加到收藏夹弹出层 / 添加到收藏夹

Alt + Shift + C 查看最近操作项目的变化情况列表

Alt + Shift + I 查看项目当前文件

Alt + Shift + F7 在 Debug 模式下,下一步,进入当前方法体内,如果方法体还有方法,则会进入该内嵌的方法中,依此循环进入

Alt + Shift + F9 弹出 Debug 的可选择菜单

Alt + Shift + F10 弹出 Run 的可选择菜单

Alt + Shift + 左键双击 选择被双击的单词 / 中文句,按住不放,可以同时选择其他单词 / 中文句

Alt + Shift + 前方向键 移动光标所在行向上移动

Alt + Shift + 后方向键 移动光标所在行向下移动

八、其他

F2 跳转到下一个高亮错误 或 警告位置 (必备)

F3 在查找模式下,定位到下一个匹配处

F4 编辑源

F7 在 Debug 模式下,进入下一步,如果当前行断点是一个方法,则进入当前方法体内,如果该方法体还有方法,则不会进入该内嵌的方法中

F8 在 Debug 模式下,进入下一步,如果当前行断点是一个方法,则不进入当前方法体内

F9 在 Debug 模式下,恢复程序运行,但是如果该断点下面代码还有断点则停在下一个断点上

F11 添加书签

F12 回到前一个工具窗口

Tab 缩进

ESC 从工具窗口进入代码文件窗口

Ctrl + Shift + Alt + V 无格式黏贴

Ctrl + Shift + Alt + N 前往指定的变量 / 方法

Ctrl + Shift + Alt + S 打开当前项目设置

Ctrl + Shift + Alt + C 复制参考信息

9、idea其他操作技巧

  • 输入sout:会输出System.out.prinln()
  • 输入main:会输出public static void main(String[] args) {}
  • 输入4.fori:会输出for (int i = 0; i < 4; i++) {}
  • 输入arr.length.fori:会输出for (int i = 0; i < arr.length; i++) {}

10、推荐插件

  • Chinese (Simplified) Language Pack
  • Alibaba Java Coding Guidelines阿里巴巴代码规范检查插件
  • Presentation Assistant 快捷键展示 Key Promoter X 快捷键提示插件 弃用,前一个好用
  • Gsonformat
  • Translation翻译插件
  • One Dark Theme
  • Rainbow Brackets彩虹括号插件
  • Codota
  • MybatisX 高效操作Mybatis plus插件
  • PTG 自动生成JavaBean
  • HighlightBracketPair —— 括号开始结尾 高亮显示。
  • Grep Console 控制台日志 高亮
  • google-java-format —— 代码自动格式化
  • Leetcode Editor 可以在IDEA中在线刷题。
  • Material Theme UI ——IDEA主题插件
  • RoboPOJOGenerator—JSON(根据json生成类)(GsonFormat也可以,但是好久没更新过了)
  • Atom Material File Icons

三、融合其他框架

1、jwt

1.1、加入依赖

<!-- JWT -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>

1.2、配置

config:
jwt:
# 是否校验 1 开 ; 0 关
isOpen: 1
# 加密密钥
secret: 92df4304-80c6-43b6-9bb2-beb6cf9b6845
# token有效时长
expire: 3600
# header 名称
header: token

1.3、配置类

package cn.tjhis.hisapi.config;

import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.signers.JWTSignerUtil;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import cn.hutool.jwt.JWTUtil; import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map; /**
* 描述:JWT的token,区分大小写
* 路径:cn.tjhis.hisapi.config
* 工程:hisApi
* 作者:wanghx
* 日期:2023-02-06 10:24
*/
@ConfigurationProperties(prefix = "config.jwt") // 用于绑定属性,其中prefix表示所绑定的属性的前缀。
@Component // 表示将该类标识为Bean
@Data
public class JwtConfig { private int isOpen;
private String secret;
private long expire;
private String header; /**
* 生成token
* @param payload
* @return
*/
public String createToken (Map<String,Object> payload){
Date nowDate = new Date();
Date expireDate = new Date(nowDate.getTime() + expire * 1000);//过期时间
//签发时间
payload.put(JWTPayload.ISSUED_AT, nowDate);
//生效时间
payload.put(JWTPayload.NOT_BEFORE, nowDate);
//过期时间 最大有效期1天强制过期
payload.put(JWTPayload.EXPIRES_AT, expireDate);
return JWTUtil.createToken(payload, JWTSignerUtil.hs256(secret.getBytes(StandardCharsets.UTF_8)));
}
/**
* 解析token
* @param token
* @return
*/
public JWT parse(String token){
return JWT.create().setSigner(JWTSignerUtil.hs256(secret.getBytes(StandardCharsets.UTF_8))).parse(token);
}
}

1.4、编写controller层下UserController

package cn.tjhis.hisapi.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import cn.tjhis.hisapi.config.JwtConfig;
import cn.tjhis.hisapi.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.ssssssss.magicapi.core.model.JsonBean;
import org.ssssssss.magicapi.core.service.MagicAPIService; import javax.annotation.Resource;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map; /**
* 描述:登录
* 路径:cn.tjhis.hisapi.controller
* 工程:hisApi
* 作者:wanghx
* 日期:2023-02-06 06:07
*/
@RestController
public class LoginController {
private final MagicAPIService service;
private static final Logger logger = LoggerFactory.getLogger(LoginController.class);
@Resource
private JwtConfig jwtConfig ;
public LoginController(MagicAPIService service) {
this.service = service;
} @GetMapping("/login")
public Object login(String userName, String password) {
if (StrUtil.isEmpty(userName)){
return new JsonBean<>(-1, "用户名不能为空!");
}
if (StrUtil.isEmpty(password)){
return new JsonBean<>(-1, "密码不能为空!");
}
// 根据用户名获取信息
Map<String, Object> params = new HashMap<>();
// 注入变量信息
params.put("userName", userName.toUpperCase());
// 内部调用接口不包含code以及message信息,同时也不走拦截器。
try {
LinkedHashMap linkedHashMap = service.execute("GET", "/comm/getUserByUserName", params);
if (linkedHashMap == null){
return new JsonBean<>(-1, "用户不存在!");
}
// 将obj转换成User对象
User user = JSONUtil.toBean(JSONUtil.parseObj(linkedHashMap),User.class);
//获取密文字节数组
String pwd = (user.getUserPwd() + "wanghx").toUpperCase();
// 字符串反转后md5加密
String pwdEnc = SecureUtil.md5(StrUtil.reverse(pwd));
if (password.equals(pwdEnc))
{
// token中不携带密码
linkedHashMap.remove("userPwd");
String token = jwtConfig.createToken(linkedHashMap);
return new JsonBean<>(200,"success",token);
}
else
{
return new JsonBean<>(-1, "密码不正确!");
}
}
catch (Exception e){
return new JsonBean<>(-1, e.getMessage());
} }
}

1.5、拦截器

package cn.tjhis.hisapi.interceptor;

import cn.hutool.jwt.JWT;
import cn.tjhis.hisapi.config.JwtConfig;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.ssssssss.magicapi.core.interceptor.RequestInterceptor;
import org.ssssssss.magicapi.core.model.ApiInfo;
import org.ssssssss.magicapi.core.model.JsonBean;
import org.ssssssss.magicapi.core.model.Options;
import org.ssssssss.script.MagicScriptContext; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* 自定义请求拦截器,可实现鉴权
* https://ssssssss.org/magic-api/pages/senior/interceptor/
*
* @see RequestInterceptor
*/
@Component
@Order(1) //拦截器顺序,可选
public class CustomRequestInterceptor implements RequestInterceptor {
@Resource
private JwtConfig jwtConfig;
private static final Logger logger = LoggerFactory.getLogger(CustomRequestInterceptor.class); /**
* 接口请求之前
*
* @param info 接口信息
* @param context 脚本变量信息
*/
@Override
public Object preHandle(ApiInfo info, MagicScriptContext context, HttpServletRequest request, HttpServletResponse response) throws Exception {
String path = request.getRequestURI();
logger.info("请求接口:{},{}", info.getName(), Options.REQUIRE_LOGIN);
// 是否开启
if (jwtConfig.getIsOpen()==1){
//获取请求头中的令牌
String token = request.getHeader(jwtConfig.getHeader()); try {
//验证令牌
JWT verify = jwtConfig.parse(token);
return null;
} catch (SignatureVerificationException e) {
return new JsonBean<>(-1,"无效签名");
} catch (TokenExpiredException e) {
return new JsonBean<>(-1,"token过期");
} catch (AlgorithmMismatchException e) {
return new JsonBean<>(-1,"token算法不一致");
} catch (Exception e) {
return new JsonBean<>(-1,"token无效");
}
}
return null;
} /**
* 接口执行之后
*
* @param info 接口信息
* @param context 变量信息
* @param value 即将要返回到页面的值
*/
@Override
public Object postHandle(ApiInfo info, MagicScriptContext context, Object value, HttpServletRequest request, HttpServletResponse response) throws Exception {
logger.info("{} 执行完毕,返回结果:{}", info.getName(), value);
return null;
}
}

1.6、magic-api中使用token

import cn.tjhis.hisapi.config.JwtConfig;
var jwt = JwtConfig.parse(header.token)
return jwt.payloads.id;

2、Redis

2.1、引入依赖

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

2.2、注入后编写代码

  • 注入的时候用Resource注解或者构造器,不推荐用 Autowired
  • redisTemplate 这个名字不能写错,否则报错:expected single matching bean but found 2: redisTemplate,stringRedisTemplate
  • @Resource注解是javax包中的注解,它是优先byName来装配的,如果byName无法装配,则会自动尝试byType装配,在byType装配时,要求匹配类型的对象必须有且仅有1个,如果无法装配,则会报告错误@Autowired注解是Spring框架中的注解,它是优先byType来装配的,
  • @Autowired为Spring提供的注解,需要导入包:org.springframework.beans.factory.annotation.Autowired
  • @Resource注解由J2EE提供,需要导入包:javax.annotation.Resource
package cn.tjhis.springredis.controller;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; /**
* 描述:
* 路径:cn.tjhis.springredis.controller
* 工程:spring-redis
* 作者:wanghx
* 日期:2023-02-07 06:15
*/
@RestController
public class TestController {
@Resource
private RedisTemplate redisTemplate;
@GetMapping("get")
public Object get(String key){
return redisTemplate.boundValueOps(key).get();
}
@GetMapping("set")
public void set(String key,String name){
redisTemplate.boundValueOps(key).set(name);
}
}

3、logback

  • 基本信息(不用添加任何pom引用)

    • SpringBoot版本2.4.5
    • 日志框架SLF4J
    • 日志框架的实现LockBack
  • 使用xml配置可以完成yml配置实现不了的功能,比如按天将日志归档。

  • xml有多种命名形式,但官方推荐的命名是logback-spring.xml

  • 日志文件输出在项目根目录下的logs文件夹下。

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration scan="true" scanPeriod="60 seconds" debug="false">
    <contextName>logback</contextName>
    <!--控制台输出内容的颜色转换以及格式-->
    <substitutionProperty name="logging.pattern.console"
    value="%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
    <!--日志文件输出内容的格式-->
    <substitutionProperty name="logging.pattern.file"
    value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
    <conversionRule conversionWord="wex"
    converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
    <conversionRule conversionWord="wEx"
    converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
    <!--输出到控制台-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    <!--控制台使用layout节点-->
    <layout class="ch.qos.logback.classic.PatternLayout">
    <pattern>
    ${logging.pattern.console}
    </pattern>
    </layout>
    </appender>
    <!--按天生成日志-->
    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <Prudent>true</Prudent>
    <!--滚动策略,我配置了按天生成日志文件-->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <!--相对路径,生成的文件就在项目根目录下-->
    <FileNamePattern>
    logs/%d{yyyy-MM-dd}.log
    </FileNamePattern>
    <!--注意超过365天的日志文件会被删除,即使已经按天分开也会删除-->
    <MaxHistory>365</MaxHistory>
    </rollingPolicy>
    <!--日志文件里只保存ERROR及以上级别的日志 INFO -->
    <!-- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">-->
    <!-- <level>INFO</level>-->
    <!-- </filter>-->
    <!--文件使用encoder节点-->
    <encoder>
    <Pattern>
    ${logging.pattern.file}
    </Pattern>
    </encoder>
    </appender>
    <!--这个logger里的配置相当于之前yml里的logging.level.com.lpc: trace-->
    <!--additivity的作用-->
    <!--true,则子Logger不止会在自己的appender里输出,还会在root的logger的appender里输出-->
    <!--而这个logger里没配置appender,所以得交给root打印-->
    <!--所以cn.tjhis.hisapi包里的日志从TRACE级别开始-->
    <!--其他包里的日志根据root的配置从INFO级别开始打印-->
    <logger name="cn.tjhis.hisapi" level="TRACE" additivity="true">
    </logger>
    <root level="INFO">
    <appender-ref ref="console"/>
    <appender-ref ref="file"/>
    </root>
    </configuration>

4、hutool

4.1、db

  • Maven项目中在src/main/resources目录下添加db.setting文件(非Maven项目添加到ClassPath中即可),[mysql]是分组,如果只连接一个数据库,可不写,如果写了,必须显式的指定,否则报错No config for group: []

    ## db.setting文件
    [mysql]
    url = jdbc:mysql://localhost:3306/net6Api
    user = admin
    pass = Admin@123 ## 可选配置
    # 是否在日志中显示执行的SQL
    showSql = true
    # 是否格式化显示的SQL
    formatSql = false
    # 是否显示SQL参数
    showParams = true
    # 打印SQL的日志等级,默认debug,可以是info、warn、error
    sqlLevel = debug
  • 添加依赖

    <properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <mysql.version>8.0.27</mysql.version>
    <hutool.version>5.8.12</hutool.version>
    </properties>
    <dependencies>
    <!--mysql数据库驱动 -->
    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>${mysql.version}</version>
    </dependency>
    <!-- 引入 hutool -->
    <dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>${hutool.version}</version>
    </dependency>
    </dependencies>
  • 测试

    import java.sql.SQLException;
    import java.util.List; /**
    * 描述:hutool的DB测试类
    * 路径:cn.tjhis.hutool
    * 工程:testHutool
    * 作者:wanghx
    * 日期:2023-02-11 07:50
    */
    public class DbTest {
    public static void main(String[] args) {
    // 只有一个数据库,可不写,[mysql]
    Db db = Db.use("mysql");
    try {
    // 查询全部
    List<Entity> payrollInfo = db.findAll("payroll_info");
    Console.log(payrollInfo.get(0).getStr("employee_name"));
    // 条件查询
    List<Entity> list = db.findAll(Entity.create("payroll_info").set("id", 5));
    JSON json = JSONUtil.parse(list);
    Console.error(json.getByPath("salary_month"));
    } catch (SQLException e) {
    throw new RuntimeException(e);
    }
    }
    }

5、mybatis

  • 搭建工程

  • 引入依赖

    • 注意spring-boot-starter版本2.4.5mybatis-spring-boot-starter的版本2.2.2
    • 也不需要加@Component或者@Repository或者@MapperScan等等
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.5</version>
    <relativePath/> <!-- lookup parent from repository -->
    </parent> <dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.2</version>
    </dependency>
    <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.8</version>
    </dependency>
    <dependency>
    <groupId>com.oracle.database.jdbc</groupId>
    <artifactId>ojdbc6</artifactId>
    <version>11.2.0.4</version>
    </dependency> <dependency>
    <groupId>com.oracle.database.nls</groupId>
    <artifactId>orai18n</artifactId>
    <version>19.7.0.0</version>
    </dependency>
  • 编写DataSource和mybatis相关配置proterties.yml

  • 定义表和实体类

    @Data
    public class Dept {
    private int deptNo;
    private String dName;
    private String loc;
    }
  • 编写dao和mapper

    @Mapper
    public interface DeptMapper {
    /**
    * 查询所有科室
    * @return 返回所有科室
    */
    @Select("select deptno, dname, loc from scott.dept")
    public List<Dept> findDeptList();
    }
  • 编写controller

    @RestController
    public class DeptController {
    @Resource
    private DeptMapper mapper;
    @GetMapping("getDeptAll")
    public String getDeptList(){
    JSON json = JSONUtil.parse(mapper.findDeptList());
    return json.toString();
    }
    }
  • 测试

    @SpringBootTest
    class SpringbootMybatisApplicationTests { @Resource
    private DeptMapper mapper;
    @Test
    void test() {
    List<Dept> deptList = mapper.findDeptList();
    String json = JSONUtil.parse(deptList).toString();
    System.out.println(json);
    } }

6、Mybatis Plus(简称 MP)

  • 优势:

    • 是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
    • 内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
    • 只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 依赖

    <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
    <dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.2</version>
    </dependency>
  • 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹:

    @SpringBootApplication
    @MapperScan("cn.tjhis.springboot.mybatis.plus.mapper")
    public class SpringbootMybatisPlusApplication { public static void main(String[] args) {
    SpringApplication.run(SpringbootMybatisPlusApplication.class, args);
    } }
  • 创建实体

    • 默认生成的语句是:SELECT dept_no,d_name,loc FROM scott.dept,所以需要指定表名和映射的字段名。
    • 需要指出表名:@TableName
    • 需要指定字段:@TableField
    @Data
    @TableName("scott.dept")
    public class Dept {
    @TableField("deptno")
    private int deptNo;
    @TableField("dname")
    private String dName;
    private String loc;
    }
  • 创建mapper

    • 不需要写@Mapper注解
    • DeptMapper中的 selectList() 方法的参数为 MP 内置的条件封装器 Wrapper,所以不填写就是无任何条件
    public interface DeptMapper extends BaseMapper<Dept> {
    }
  • 测试

    @SpringBootTest
    class SpringbootMybatisPlusApplicationTests {
    @Resource
    private DeptMapper deptMapper; @Test
    void test() {
    System.out.println(("----- selectAll method test ------"));
    List<Dept> userList = deptMapper.selectList(null);
    userList.forEach(System.out::println);
    }
    }

SpringBoot导读的更多相关文章

  1. 基于SpringBoot+Mybatis+AntDesign快速开发平台,Jeecg-Boot 1.1 版本发布

    Jeecg-Boot 1.1 版本发布,初成长稳定版本 导读     平台首页UI升级,精美的首页支持多模式 提供4套代码生成器模板(支持单表.一对多) 集成Excel简易工具类,支持单表.一对多导入 ...

  2. spring-boot 热加载实现替换Jrebel

    导读: 本文主要说说,在玩spring-boot时,我们经常要遇到重启服务这种浪费时间的事情,为了割掉这个痛点,我们一般有2中方式实现. 一个是springload , 另外一个是 spring-bo ...

  3. java+springBoot+Thymeleaf+vue分页组件的定义

    导读 本篇着重介绍java开发环境下,如何写一个vue分页组件,使用到的技术点有java.springBoot.Thymeleaf等: 分页效果图 名称为vuepagerbasic的分页组件,只包含上 ...

  4. 靓仔,整合SpringBoot还在百度搜配置吗?老司机教你一招!!!

    导读 最近陈某公司有些忙,为了保证文章的高质量可能要两天一更了,在这里陈某先说声不好意思了!!! 昨天有朋友问我SpringBoot如何整合Redis,他说百度谷歌搜索了一遍感觉不太靠谱.我顿时惊呆了 ...

  5. RocketMQ 4.7.1 环境搭建、集群、MQ整合SpringBoot

    导读 之前学过ActiveMQ但是并发量不是很大点我直达,所以又学阿里开源的RocketMQ,据说队列可以堆积亿级别.下面是网上找的消息队列对比图,仅供参考 部署 官网 点我直达 前置条件 推荐使用6 ...

  6. SpringBoot整合阿里短信服务

    导读 由于最近手头上需要做个Message Gateway,涉及到:邮件(点我直达).短信.公众号(点我直达)等推送功能,网上学习下,整理下来以备以后使用. 步骤 点我直达 登录短信服务控制台 点我直 ...

  7. SpringBoot 实现微信推送模板

    导读 由于最近手头上需要做个Message Gateway,涉及到:邮件(点我直达).短信.公众号等推送功能,网上学习下,整理下来以备以后使用. 添加依赖 在SpringBoot项目中添加依赖 < ...

  8. SpringBoot 开发提速神器 Lombok+MybatisPlus+SwaggerUI

    导读 Lombok:可以让你的POJO代码特别简洁,不止简单在BO/VO/DTO/DO等大量使用,还有设计模式,对象对比等 MybatisPlus:增加版Mybatis,基础的数据库CRUD.分页等可 ...

  9. 解决 Springboot Unable to build Hibernate SessionFactory @Column命名不起作用

    问题: Springboot启动报错: Caused by: org.springframework.beans.factory.BeanCreationException: Error creati ...

  10. 【微框架】Maven +SpringBoot 集成 阿里大鱼 短信接口详解与Demo

    Maven+springboot+阿里大于短信验证服务 纠结点:Maven库没有sdk,需要解决 Maven打包找不到相关类,需要解决 ps:最近好久没有写点东西了,项目太紧,今天来一篇 一.本文简介 ...

随机推荐

  1. 关于xtr的一些基础

    Q&A 如何找到QSEQ方式的xtt呢? 我们可以去版本的代码中寻找,具体位置在:(modem_proc/rf/rftarget_denali/mtp/xtt/etc/QSEQ/) 在QSEQ ...

  2. grafana嵌入iframe,去除菜单和上方工具条

    1.首先修改grafana的配置:etc/grafana/grafana.ini,修改下面这两个配置为true 2.由于项目使用了nginx,要启用https,需要修改下面这几个配置:(不需要启用ht ...

  3. k8s ingress 报错整理

    问题: Error from server (InternalError): error when creating "ingress-rules-demo1.yaml": Int ...

  4. Windows Service调试方法小结

    方法1:log记录 这是一个通用的调试方法,效率比较低,但比较实用,通过查看日志,总能达到调试的目的 方法2:附加到进程 这是Windows Service程序调试的常用方法,缺点是对Windows环 ...

  5. 了解ASP(二)

    变量 ASP中的变量有普通变量,Session变量,Application变量. 变量的生存期 在子程序外声明的变量可被 ASP 文件中的任何脚本访问和修改. 在子程序中声明的变量只有当子程序每次执行 ...

  6. ASP中把数据导出为Excel的三种方法

    方法一:用excel组件 这种方法利用Excel组件直接导出excel文件,要求服务器端安装有微软office(Excel)程序,否则无法运行. 完整示例如下: Set conn=server.Cre ...

  7. k8s 删除 node节点

    查看现有状态 [root@master ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION master NotReady control-plan ...

  8. Newtonsoft.Json高级用法--转载至 焰尾迭 随笔

    本人只做搬运工,以这方便自己学习的态度!以下内容均为拷贝! 如有不适请联系本人! 本文原作者:焰尾迭 本文地址:http://www.cnblogs.com/yanweidie/p/4605212.h ...

  9. debian 新安装备忘

    change resource https://www.cnblogs.com/devzyh/p/12670194.html 安装sougou输入法,并配置好.重启. https://www.cnbl ...

  10. 1.Python3.5+Pyqt5+PyCharm+Opencv3.3+Qtdesigner开发环境配置

    一:Python3.3和Pyqt5的安装 注意:两个的版本一定要对应,一定要对应,一定要对应,重要的事情说三遍. 因为我自己的电脑是64位的,所以我下载的都是64位版本的,且都是3.5版本的:这两个一 ...