shell脚本执行方式

shell脚本执行方式

一个规范的Shell脚本在第一行会指出由哪个程序(解释器)来执行脚本中的内容,这一行内容在Linux bash的编程一般为:

1
#!/bin/bash

1
#!/bin/sh

注意

  • 在Shell中如果一行的第一个字母是#,则是注释,但是上面两个是写在第一行,所以不是脚本注释行,如果写在某个命令之后,则变成注释行。
  • sh为bash的软链接,大多数情况下,脚本的开头使用“#!/bin/bash”和“#!/bin/sh”是没有区别的,但更规范的写法是在脚本的开头使用“#!/bin/bash”。

shell脚本执行方式

有3种方式:

bash script-name或是sh script-name

当脚本文件本身没有可执行权限时常使用的方法,或者脚本文件开头没有指定解释器时需要使用的方法。
注意:

尽量不要用sh script-name去执行脚本,理由如下:

  • 脚本已经是可执行模式的,在里面指定的是bash,操作更简单些。
    脚本中总是声明上确定的shell(如bash)是好的实践: #!/bin/bash。
  • 不同的shell(sh、bash、zsh、fish、csh、tcsh、ksh、ash、dash……)有各种差异,深坑勿入。
    目前主流的是bash/zsh。更多shell的信息 参见 https://en.wikipedia.org/wiki/Comparison_of_command_shells
  • sh可能是个符号链接,可能链接到不同的shell,如有的Ubuntu版本,sh是链接到dash的。

参见:DO NOT run script file by sh | 不要以sh foo-script的方式运行脚本 #85

path/script-name或者./script-name

在当前路径下执行脚本(脚本需要有执行权限).
体方法为:chmod a+x script-name。然后通过执行脚本绝对路径或者相对路径就可以执行脚本了。

source script-name或者. script-name

读入脚本并执行脚本,即在当前Shell中执行source或“.”加载并执行的相关脚本文件的命令及语句,而不是产生一个子Shell来执行文件中的命令。

3种shell执行方式具体区别、示例参见Linux 中执行Shell 脚本的方式(三种方法)

参考文档

mysql 常用函数整理

mysql 常用函数整理

mysql 常用函数整理

字符串操作

字符串拼接 concat

1
select id, name, concat('-', name, '-') from t_student;

去掉无用空格 trim

1
select id, name, trim(name) from t_student

截取字符串

获取前缀 left

获取后缀 right

截取字符串 substring_index

substring_index(str,delim,count)
参数依次是:要分隔截取的字符串(如:”aaa_bbb_ccc”)、分隔符(如:“_”)、位置(表示第几个分隔符处,如:“1”)。
count为正数,那么就是从左边开始数,函数返回第count个分隔符的左侧的字符串;
count为负数,那么就是从右边开始数,函数返回第count个分隔符右边的所有内容;
count可以为0,返回为空。

例子:

1
2
3
substring_index("aaa_bbb_ccc","_",1) #返回为 aaa;
substring_index("aaa_bbb_ccc","_",2) #返回为 aaa_bbb;
substring_index(substring_index("aaa_bbb_ccc","_",-2),"_",1) 返回为 bbb;

截取字符串 substring

substring(string,position);
substring(string FROM position);

参数依次是:

  • string参数是要提取子字符串的字符串。
  • position参数是一个整数,用于指定子串的起始字符,position可以是正或负整数。

注意,SQL中,字符串的起始序号从1开始。

参考资料

spring boot启动失败,JVM 报错:warning Insufficient space for shared memory file

spring boot启动失败,JVM 报错:warning Insufficient space for shared memory file

问题与原因

启动spring boot程序时,报异常,导致程序启动失败,遇到形如下面的错误:

1
2
3
4
5
6
7
8
A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].StandardContext[/Integration]]
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1123)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:800)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
……

然而,这个只是结果,实际上并不能定位问题,笔者继续找异常,看到类似下面的错误:

1
2
3
4
5
6
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:137) ~[spring-boot-1.5.13.RELEASE.jar:1.5.13.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.__refresh(AbstractApplicationContext.java:537) ~[spring-context-4.3.17.RELEASE.jar:4.3.17.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.jrLockAndRefresh(AbstractApplicationContext.java:40002) ~[spring-context-4.3.17.RELEASE.jar:4.3.17.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:41008) ~[spring-context-4.3.17.RELEASE.jar:4.3.17.RELEASE]
……

还是搜不出什么结果,实在崩溃之际,发现spring boot程序启动时,第一句log有这么一句:

1
2
warning Insufficient space for shared memory file
……

并且发现,使用jps等命令时,也会报这个警告,才发现原来是硬盘满了,可以使用

1
df -h

查看目前服务器硬盘情况。
其他命令:
查看一个文件夹中所有文件的大小(不含子目录中的文件):du -Sh或du -Ssh
查看一个文件夹中所有文件的大小(包含子目录中的文件):du -h或者du -sh

S:表示不统计子目录,s:表示不要显示其下子目录和文件占用的磁盘空间大小信息,只显示总的占用空间大小
查看文件夹中每一个文件的大小:du -ah 或者ls -lRh

解决

定位问题后,清理硬盘,即可避免异常、启动程序。

参考文档

Java中如何判断文件类型

Java中如何判断文件类型

目前看到的有两种方式:

  • 根据文件后缀
  • 根据文件魔数

根据文件后缀

满足一般需要,但如果文件后缀被手工修改,则可能判断错误。

JDK中已经提供了现成的接口用于根据文件名判断:

1
URLConnection.guessContentTypeFromName("xxx.com/api/yyy.jpg")

根据文件魔数

魔数概念就不在此赘述,此种方式会通过读取文件二进制字节流的方式,获取文件开头的几个字节,用于判断文件类型。

JDK中提供的接口:

1
URLConnection.guessContentTypeFromStream(inputStream)

该方法需要传入文件输入流。

当然,也有第三方工具库也可以做到这一点,比如Java如何获取Content-Type的文件类型Mime Type这篇文章中提到的jMimeMagic库,可以通过如下方式获取类型:

1
2
3
4
File file = new File("e:\\test\\123.gif")
MagicMatch match = Magic.getMagicMatch(file, false, true);
String contentType = match.getMimeType();
System.out.println(contentType);

参考资料

java根据URL获取输入流以及下载文件

java根据URL获取输入流以及下载文件

代码取自:JAVA根据URL网址获取输入流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
* 根据地址获得数据的输入流
* @param strUrl 网络连接地址
* @return url的输入流
*/
public static InputStream getInputStreamByUrl(String strUrl){
HttpURLConnection conn = null;
try {
URL url = new URL(strUrl);
conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(20 * 1000);
final ByteArrayOutputStream output = new ByteArrayOutputStream();
IOUtils.copy(conn.getInputStream(),output);
return new ByteArrayInputStream(output.toByteArray());
} catch (Exception e) {
logger.error(e+"");
}finally {
try{
if (conn != null) {
conn.disconnect();
}
}catch (Exception e){
logger.error(e+"");
}
}
return null;
}

如若想下载文件,则可以在上面方法基础上,进一步封装即可:\

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public ResponseEntity<byte[]> downloadFileByUrl(String downUrl, String fileName, String contentType, String contentDisposition) throws IOException {
InputStream inputStream = getInputStreamByUrl(downUrl);

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
IOUtils.copy(inputStream, byteArrayOutputStream);
inputStream.close();
HttpHeaders headers = new HttpHeaders();
//设置下载协议头。下面fileName的两次转换主要是为了保证中文文件名
fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
headers.set(HttpHeaders.CONTENT_DISPOSITION, contentDisposition + ";filename=" + new String(fileName.getBytes(), "utf-8"));
headers.set(HttpHeaders.CONTENT_TYPE, contentType);
ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(byteArrayOutputStream.toByteArray(), headers, HttpStatus.OK);
byteArrayOutputStream.close();
return responseEntity;
}

其中Content-Type可以用MediaType中的常量,自行控制;Content-Disposition则看需求,如果需要直接打开文件,则传”inline”,若是想下载则传”attachment”。

Spring Boot 上传文件报错 The temporary upload location [xxx] is not valid

Spring Boot 上传文件报错 The temporary upload location [xxx] is not valid

问题

导入excel文件时,偶发bug:

1
2
3
4
5
6
7
8
9
10
11
org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.io.IOException: The temporary upload location [C:\Users\AppData\Local\Temp\tomcat.4266029690466887869.8037\work\Tomcat\localhost\ROOT] is not valid
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:112)
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.<init>(StandardMultipartHttpServletRequest.java:86)
at org.springframework.web.multipart.support.StandardServletMultipartResolver.resolveMultipart(StandardServletMultipartResolver.java:79)
at org.springframework.web.servlet.DispatcherServlet.checkMultipart(DispatcherServlet.java:1104)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:936)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)

原因

Spring boot项目在导入文件时,没有找到指定文件夹。
子所以是偶发的问题,是因为spring boot项目本身在启动后会自动在Temp文件夹中创建若干临时文件夹,而操作系统可能会定期删除这些临时文件夹。linux也有类似操作系统自动清空临时文件夹的操作,参见这篇文章CentOS7的/tmp目录自动清理规则

\

源码层面的分析参见SpringBoot文件上传异常之提示The temporary upload location xxx is not valid

解决

手工改变临时文件的存储路径,并且如果该路径下的文件夹没有创建,则用程序来创建,保证路径有效。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Configuration
public class MultipartConfig {

/**
* 文件上传临时路径
*/
@Bean
MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
String location = System.getProperty("user.dir") + "/data/tmp";
File tmpFile = new File(location);
if (!tmpFile.exists()) {
tmpFile.mkdirs();
}
factory.setLocation(location);
return factory.createMultipartConfig();
}
}

参考资料

spring boot连接mysql 8时报errorCode 0, state 08001错误

spring boot连接mysql 8时报errorCode 0, state 08001错误

现象

spring boot 启动时,连接mysql 8数据库报错errorCode 0, state 08001

原因

1. spring boot项目中,pom文件中配置的mysql驱动版本与mysql数据库版本不一致

此时修改pom文件中的版本即可,可以使用下面的配置:

1
2
3
4
5
……
<groupId>mysql
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
……

同时,yml文件中的mysql驱动类文件最好修改成

1
2
3
……
driver-class-name: com.mysql.cj.jdbc.Driver
……

2. 连接配置参数需要修改

如果修改驱动文件后还是抛出异常,此时可以尝试修改连接参数,改成如下这种:

1
2
3
……
url: jdbc:mysql://ip地址:3306/数据库名称?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Hongkong
……

没细查,主要应该是由于加密方式、编码等原因导致的。

参考资料

git使用技巧- cherry-pick挑选某个commit应用到当前分支

git使用技巧- cherry-pick挑选某个commit应用到当前分支

git cherry-pick可以挑选某个分支的一个或多个commit,将其应用到当前分支上。

1
git cherry-pick <commit id>

查询commit id 的查询可以使用git log查询(查询版本的历史),最简单的语法如下:

1
git log

如果想查找已经被删除的某次commit,则可以用

1
git reflog

spring boot 多个包启动失败-添加注解扫描多个包

spring boot 多个包启动失败-添加注解扫描多个包

spring boot 多个包启动失败-解决:扫描多个包

表现:启动时提示如下信息:
因为项目需要,将代码结构调整为:


这种组织结构,注意,此处时同一个项目(没有拆分成多个maven模块),有多个包保存不同功能模块的代码。此时启动项目,报错如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2019-11-12 19:28:40.563 [recruit_system] [main] ERROR [org.springframework.boot.SpringApplication] -Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeForPcController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'enrollInfoServiceImpl': Unsatisfied dependency expressed through field 'baseMapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.xxx.yy.mapper.EnrollInfoMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:321)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107)
at com.xxx.RecruitApplication.main(RecruitApplication.java:27)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'enrollInfoServiceImpl': Unsatisfied dependency expressed through field 'baseMapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.xxx.yy.mapper.EnrollInfoMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:518)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:496)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:627)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:169)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:318)
... 17 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.xxx.yy.mapper.EnrollInfoMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 35 common frames omitted

可以看到,初始化各种bean失败(controller、service等)。

解决

推测是spring boot启动类扫描代码的目录错误。在启动类的@SpringBootApplication注解中指定:

1
@SpringBootApplication(scanBasePackages = {"com.xxx.xx", "com.xxx.yy"})

即可解决该问题。

但有引入新问题:

新增mapper后,mapper实例化失败

报出如下异常:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2019-11-12 19:33:32.772 [recruit_system] [main] ERROR [org.springframework.boot.SpringApplication] -Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeForPcController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'enrollInfoServiceImpl': Unsatisfied dependency expressed through field 'baseMapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.xxx.yy.mapper.EnrollInfoMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:321)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107)
at com.xxx.RecruitApplication.main(RecruitApplication.java:26)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'enrollInfoServiceImpl': Unsatisfied dependency expressed through field 'baseMapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.xxx.yy.mapper.EnrollInfoMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:518)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:496)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:627)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:169)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:318)
... 17 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.xxx.yy.mapper.EnrollInfoMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 35 common frames omitted

解决

添加扫描多个包注解:
在启动类中添加@MapperScan,并写上不同包的mapper:

1
2
3
4
5
6
7
@MapperScan({"com.xxx.yy.mapper", "com.xxx.xx.mapper"})
@SpringBootApplication(scanBasePackages = {"com.xxx.recruit", "com.xxx.employee"})
@ServletComponentScan
@EnableScheduling
@Slf4j
public class RecruitApplication ……
……

参考文章

git使用技巧-stash保存现场,恢复现场

git使用技巧-stash保存现场,恢复现场

git stash命令:保存现场、恢复现场

  • 功能:将git 工作区中的数据暂存起来,保存现场,以及后续的恢复现场,类似于函数调用的保存现场、恢复现场
  • 使用场景:正在开发一个代码,编写到一半,需要将代码恢复到某个版本修复某个bug上,但已经编写的工作又想保留

用法

1
2
3
4
git stash   # 保存当前现场。
git stash list # 查看当前stash缓存的内容
## 编辑其他内容,编辑完毕后,想回复现场:
git stash pop # 弹出stash缓存栈顶内容,即可恢复现场


注意stash保存数据时,实际是一个栈结构,基本每次最新stash进去的数据,都保存在栈顶,如果用git stash pop命令,弹出的都是最新压入的数据。

如果多次stash,想取出某一次压入的数据,可以先用查看stash的记录id:

1
git stash list

可以看到,git stash list的结果基本如下:

1
2
stash@{0}: WIP on dev: f52c633 add merge
stash@{1}: WIP on dev: d23b633 add feature

然后挑选哪次弹出即可:

1
git stash apply stash@{1}

注意git stash apply命令不会将数据弹出、数据仍保存在stash缓存中;git stash pop则会将数据彻底弹出。
如果运用git stash apply之后,想彻底删掉某条记录,可以用:

1
git stash drop stash@{1}

参考资料