赞
踩
maven官网 Maven – Download Apache Maven
(1)仓库:远程仓库、镜像仓库、本地仓库
(2)坐标:jia包下载的地址
(3)依赖:下载一个jar包,会下载和其相关的jar包
(4)命令 mvn cmd
①clean 对项目进行清理,清理的过程中会删除删除target目录下编译的内容。
②install 对本项目进行打包。三种打包方式,pom打包,jar包和war包。打包方式在pom.xml文件中进行指定。jar包就是普通的打包方式,可以是pom工程的子工程。war包的都是web工程,是可以直接放到tomcat下运行的工程。打成pom包和jar包的工程在新建的时候可以不需要制定maven项目的原型,达成war包的项目需要制定maven项目原型,指定的原型通常为maven-archetype-webapp,代表web项目。
③compiler 编译项目源代码。
maven依赖的传递性
说明: maven中的jar包是有依赖的传递性
例如: A项目依赖B.jar包, B.jar依赖C.jar. 在项目中,只需要添加B.jar.则B/C.jar都会自动添加.
maven依赖传递性实现原理
镜像仓库配置
- <mirrors>
- <!-- mirror
- | Specifies a repository mirror site to use instead of a given repository. The repository that
- | this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
- | for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
- |
- -->
- <!-- 阿里云首选镜像,有不能下的包会在别的镜像源下载 -->
- <mirror>
- <id>nexus-aliyun</id>
- <mirrorOf>central</mirrorOf>
- <name>Nexus aliyun</name>
- <url>https://maven.aliyun.com/nexus/content/groups/public</url>
- </mirror>
- <!-- 默认下载源 -->
- <mirror>
- <id>mirrorId</id>
- <mirrorOf>repositoryId</mirrorOf>
- <name>Human Readable Name for this Mirror.</name>
- <url>http://my.repository.com/repo/path</url>
- </mirror>
- </mirrors>
本地仓库地址
<localRepository>E:\apache-maven-3.6.3-bin\repository</localRepository>
Spring Boot 是所有基于 Spring 开发的项目的起点。Spring Boot 的设计是为了让开发者尽可能快的跑起来 Spring 应用程序并且尽可能减少开发者的配置文件。
特点:
(1) 嵌入的Tomcat(服务器默认端口号8080)
(2)简化Maven配置
(3)提供了大量的自动配置,比如需要持久层数据源连接数据库,只需要提供对应属性就可以。
默认地址: https://start.spring.io
阿里云地址: https://start.aliyun.com
在idea中已经集成,当创建springboot项目时可以看到
Springboot是一个微服务框架,简化了应用的开发和部署。
Spring其核心就是控制反转(IOC),和面向切面(AOP),整合三方框架
Spring MVC接收用户发来的请求,处理业务,并给出相应
Mybatis与数据库相对接
spring和springmvc注解:
Spring和MVC_mvc和spri_S Y H的博客-CSDN博客
mybatis和mp注解:
(8条消息) Mybatis和MP_mybatis 数组查询_S Y H的博客-CSDN博客
第一步:springboot项目中,resources/目录下创建名为banner.txt的文件
第二步:在网站生成图案 Text to ASCII Art Generator (TAAG) (patorjk.com)
第三步:将图案cv,启动springboot项目。新图案就出来了
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
lombok常用提供常用注解
- @Data //自动生成get/set方法
- @Accessors(chain = true) // //开启链式加 原理:重写set/get方法
- @NoArgsConstructor //无参构造
- @AllArgsConstructor //全参构造
- import lombok.extern.slf4j.Slf4j;
-
- @Slf4j
- public class LoginController {
- public String login(String username, String password) {
- log.trace("日志级别 trace");
- log.debug("日志级别 debug");
- log.info("日志级别 info");
- log.warn("日志级别 warn");
- log.error("日志级别 error");
- }
- }
在SpringBoot中声明式事务最常见,就是把需要事务的方法用@Transactional标注一下就行了,这个一般用在Service层。标注后该方法就具备了事务的能力,出错了会自动回滚。但是被标注后的整个方法都在事务中,影响效率
@Transactional作用:
@Transactional失效场景:
spring事务(注解 @Transactional )失效的12种场景_spring事务失效场景_春天的早晨的博客-CSDN博客
在 Spring Boot 中实现编程式事务又有两种实现方法:
- import org.springframework.transaction.support.TransactionTemplate;
-
- @Autowired
- private BaiduUserInfoMapper baiduUserInfoMapper;
-
- @Resource
- private TransactionTemplate transactionTemplate;
-
- /*
- * 测试编程式事务
- * */
- @GetMapping("/test/{sex}")
- public String test(@PathVariable("sex") String sex) {
-
- BaiduUserInfo baiduUserInfo = new BaiduUserInfo();
- baiduUserInfo.setIdCard("213216546546");
- baiduUserInfo.setSex(sex);
-
- Integer execute = transactionTemplate.execute(transactionStatus -> {
- // 进行数据更改操作
- int i = baiduUserInfoMapper.updateBaiduUserInfo(baiduUserInfo);
- // 故意设置一个报错,经过测试,此处使用try...catch捕获依旧生效
- int a = 1 / 0;
- return i;
- });
-
- return "成功" + execute;
- }
测试:修改性别
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- xml的版本和编码-->
- <!-- xml 可扩展标记语言(EXtensible Markup Language)-->
- <!-- xml 被设计用来传输和存储数据 html 被设计用来显示数据-->
-
- <!-- xmlns-命名空间,类似包名,因为xml的标签可以自定义,所以需要命名空间来区分-->
- <!-- xmlns:xsi-xml遵循的标签规范-->
- <!-- xsi:schemaLocation-用来定义xmlschema的地址,也就是xml书写时需要遵循的语法,
- 两部分组成,前面部分就是命名空间的名字,后面是xsd(xmlschema)的地址-->
- <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">
-
- <!-- pom模型的版本-->
- <modelVersion>4.0.0</modelVersion>
-
- <!-- 父级项目,parent的引用是固定的;当我们创建一个 Spring Boot 工程时,可以继承自一个 spring-boot-starter-parent;父项目中定义了依赖的版本,我们继承了它,所以依赖dependence可以不写版本号,若不用父项目中的版本号则自己用<version>标签指定-->
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.6.0</version>
- <relativePath/>
- <!-- lookup parent from repository(从存储库中查找父级项目) -->
- </parent>
-
- <!-- groupId主要用来唯一标识一个项目或者一组项目,通常是java包名的全称-->
- <groupId>com.upc.pipeline</groupId>
- <!-- 用来标识同一groupId下不同的项目,例如spring-boot-starter-thymeleaf,都是这种格式的-->
- <artifactId>pdfs</artifactId>
- <!-- 版本-->
- <version>0.0.1-SNAPSHOT</version>
- <!-- 项目的名称,Maven产生的文档用-->
- <name>pdfs</name>
- <!-- 项目的描述,Maven产生的文档用-->
- <description>Demo project for Spring Boot</description>
-
- <!-- 定义变量,版本管理;使用格式:${java.version}-->
- <properties>
- <java.version>1.8</java.version>
- </properties>
-
-
- <!-- 依赖管理-->
- <dependencies>
- <!-- lombok能通过注解帮我们消除那些必须要写但是重复的代码,比如setter,getter,构造函数之类的方法-->
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <!-- <optional>-标记依赖是否可以传递,默认值是false,可以用来减少项目之间jar包的冲突-->
- <optional>true</optional>
- </dependency>
-
- <!-- 单元测试-->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <!-- 用来表示当前的这个依赖(通过pom加载进来的包)所作用的场景,就是说应该把它添加到哪个环境当中,例如只在测试时此jar包生效,取值主要有compile-编译时(若未指定则为该默认值) runtime-运行时 test-测试时 等 -->
- <scope>test</scope>
- </dependency>
-
- <!-- Mybatis分页插件-->
- <dependency>
- <groupId>com.github.pagehelper</groupId>
- <artifactId>pagehelper</artifactId>
- <version>4.1.0</version>
- </dependency>
-
- <!-- Oracle11g 连接驱动依赖。这里是个坑,官方提供的不能用 -->
- <dependency>
- <groupId>cn.easyproject</groupId>
- <artifactId>ojdbc6</artifactId>
- <version>12.1.0.2.0</version>
- </dependency>
-
- <!-- jdbcTemplate -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-jdbc</artifactId>
- </dependency>
- </dependencies>
-
- <!-- 编译-->
- <build>
- <!-- 用于指定使用的插-->
- <plugins>
- <!-- Maven插件-->
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- <!-- <configuration>-指定插件配置-->
- <configuration>
- <!-- <excludes>-指定哪些文件将被忽略-->
- <excludes>
- <exclude>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </exclude>
- </excludes>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </project>
首先我们可以在idea中ctrl+右键点开父依赖spring-boot-starter-parent
进入如下文件,接着ctrl+右键点击spring-boot-dependencies
进入如下文件
可以看见在spring-boot-dependencies里面看到声明了很多第三方依赖的版本。
那么所有当子项目再次引入此依赖jar包时则无需显式的列出版本号。Maven会沿着父子层级向上寻找拥有dependencyManagement 元素的项目,然后使用它指定的版本号。而这些依赖的版本号,就是第二张图片里面的properties中对应的版本号,也就是被锁定的版本号
加载顺序: bootstrap.yml > application.yml > application.properties > application.yaml
由前到后依次读取,也就是说不同配置文件中相同配置后加载的会覆盖先加载的,不同配置文件中不同配置则会全部保留。
bootstrap.yml 用来程序引导时执行,应用于更加早期配置信息读取. 可以理解成系统级别的一些参数配置,这些参数一般是不会变动的。
yml文件默认字符集采用UTF-8编码 可以写中文
- server:
- port: 8080
- mysql:
- username: root
- password: root
- text: ${mysql.username} # 获取本文件内的其他属性值
方式一:使用注解@Autowired注入Environment类
- file:
- caseinfo:
- image:
- savepath: /SmartCityFile/Case/Img/
- @Autowired
- private Environment environment;
-
- @GetMapping("/get")
- public String get() {
- return environment.getProperty("file.caseinfo.image.savepath");
- }
局限1:如果要在静态方法中读取配置信息,不能简单的将Environment定义成static就完了
局限2:Environment 无法直接读取自定义的Yml配置文件,需要通过增加一个配置类,将自定义的Yml文件暴露到spring environment中。
局限3:由于加载顺序的原因,使用注解的方法不适用于在静态代码块(static{})中读取配置,即便用了局限1的解决方法也不行,目前还没找出解决方法
方式二: @Value注解直接注入配置信息
- @Value("${mysql.password}")
- private String password;
-
- @Value("${mysql.password:8080}")//可以直接给默认值
- private String password;
同第一个方法一样,key要写完整,有几层就写几层,每一层用点分开;该方法同第一种方法的局限性一样。
方式三:定义一个工具类,使用@Component注解成为配置类,再继承ApplicationRunner 重写run(),再注入Environment 类获取配置,可以做到在任何地方随时随地获取配置信息。
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.ApplicationArguments;
- import org.springframework.boot.ApplicationRunner;
- import org.springframework.core.env.Environment;
- import org.springframework.stereotype.Component;
-
- @Component
- public class BaseConfig implements ApplicationRunner {
- @Autowired
- private Environment environment;
-
- public static String pro1;
- public static String pro2;
-
- @Override
- public void run(ApplicationArguments args){
- pro1=environment.getProperty("file.caseinfo.image.savepath");
- pro2=environment.getProperty("file.caseinfo.image.readpath");
- }
- }
直接用调用配置类的静态属性即可获取配置信息,不限于常规方法,静态方法,静态代码块,其实相当于时使用一个配置类迂回一下间接获取配置信息。
- @GetMapping("/get")
- public String get() {
- return BaseConfig.pro2;
- }
方式一:同一个配置文件配置多个环境
- # 环境分割
- spring:
- profiles:
- active: dev #指定默认配置
- --- #环境分割
- server:
- port: 8080
- spring:
- config:
- activate:
- on-profile: dev #环境名字
- ---
- server:
- port: 9000
- spring:
- config:
- activate:
- on-profile: prod #环境名字
方式二:不同环境在不同配置文件
创建多个配置文件
- application.yml #主配置文件
- application-dev.yml #开发环境的配置
- application-prod.yml #生产环境的配置
- application-test.yml #测试环境的配置
applicaiton.yml中指定配置;在application.yml中选择需要使用的配置文件(当选择的文件和application.yml文件存在相同的配置时,application.yml中的配置会被覆盖掉)
- spring:
- profiles:
- active: dev #需要使用的配置文件的后缀
- spring:
- servlet:
- multipart:
- max-file-size: 3000000MB # 指定上传文件允许的最大大小。 默认值为1MB
- max-request-size: 3000000MB # 指定multipart/form-data请求允许的最大大小。 默认值为10MB。
数据结构类型: key=value 特别注意不要有空格;字符集编码: 程序读取文件时,默认采用ISO-8859-1编码,写入中文,读取的时候一定会中文乱码。
- server.port=8083
- person.name=xiaoming
- person.age=55
- person,.address=wudalu
方式一:@Value注解直接注入配置信息
- // 获取PropertySource配置文件的信息
- // @PropertySource("xxxxxx/xxx.properties") 将指定路径的配置文件交给Spring容器管理
- @RestController
- // value属性指定路径 // encoding属性指定配置文件编码格式
- @PropertySource(value="classpath:/mysql.properties",encoding = "UTF-8")
- public class JDBCController {
-
- @Value("${mysql.username}")
- private String username;
-
- @Value("${mysql.password}")
- private String password;
-
- @Value("${mysql.password:8080}")//可以直接给默认值
- private String password;
- }
方式二:使用@ConfigurationProperties注解读取
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.stereotype.Component;
-
- @Component
- @ConfigurationProperties(prefix = "person")
- public class Person {
-
- private String name;
-
- private int age;
-
- private String address;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getAddress() {
- return address;
- }
- public void setAddress(String address) {
- this.address = address;
- }
- public Person(String name, int age, String address) {
- super();
- this.name = name;
- this.age = age;
- this.address = address;
- }
- public Person() {
- super();
- // TODO Auto-generated constructor stub
- }
- @Override
- public String toString() {
- return "Person [name=" + name + ", age=" + age + ", address=" + address + "]";
- }
-
- }
@Component 表示将该类标识为Bean
@ConfigurationProperties(prefix = "person")用于绑定属性,其中prefix表示所绑定的属性的前缀。
将这个前缀下面的对应属性值,直接注入至实体类的属性值中
如果未写前缀,在配置文件中出现多个name时,他可能就无法识别是person下面的name值,所以需要有这个前缀进行区分
这边通过@ConfigurationProperties(prefix = "person")注释完之后,就不需要像@value一样一个个配置过去,他会自动将配置文件中的对应属性值直接一一对应上去
使用时,先使用@Autowired自动装载Person,然后再进行取值,示例如下:
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- import com.cmj.springBootTEST.CmjConfig;
- import com.cmj.springBootTEST.Person;
-
- @RestController
- @RequestMapping("hello2")
- public class OneController {
-
- @Autowired
- private Person person;
-
- @GetMapping("/get")
- public String hello() {
- System.out.println(person);
- }
- }
// 相对路径绝对路径都可
java -jar myspring.jar --spring.config.location=D:\JavaSite\config\application.properties
引用的优先级和下面的顺序是一样的。
1、当前目录下的 /config 子目录
2、与jar包目录同级
3、classpath下的config目录
4、classpath中
@AutoWired、@Qualifier、@Resource这3个注解都是基于注解方式进行自动装配,在容器里面将查找到的bean返回
注解 | 说明 |
@AutoWired | spring提供。 @Autowired默认按类型装配,如果发现找到多个bean,则按照name方式比对 |
@Qualifier | /ˈkwɒ lɪ faɪ ə(r)/ 快 spring提供。 配合@AutoWired使用,当出现两个及以上bean时,根据Bean的名字找Bean |
@Resource | jdk的注解。 1、指定name属性,也不指定type属性,则自动按属性名字查找Bean名字。如果没有找到符合的bean,则根据类型查找 @Resource 2、只是指定了@Resource注解的name,则按name后的名字去bean元素里查找有与之相等的name属性的bean 3、只指定@Resource注解的type属性,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常。type使用实现类的类型 4、既指定了@Resource的name属性又指定了type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常 |
这里补充一下@Server的作用:
标记当前类是一个service类,加上该注解会将当前类自动注入到spring容器中。默认是单例。默认bean的名字是当前类的小驼峰格式
比如下面这个类:
@Service("courseDAO") public class CourseDAOImpl implements CourseDAO{ ...... }其作用就相当于applicationContext.xml文件里面的:
既指定了bean的名字,也记录了bean的类型
<bean id="courseDAO" class="com.hzhi.course.dao.CourseDAOImpl"> ...... </bean>
@Resource的type属性使用示例
@Autowired 和 @Resource 来自不同的“父类”,其中 @Autowired 是 Spring 定义的注解,而 @Resource 是 Java 定义的注解,它来自于 JSR-250(Java 250 规范提案)。
@Autowired 是先根据类型(byType)查找,如果存在多个 Bean 再根据名称(byName)进行查找
@Resource 是先根据名称查找,如果(根据名称)查找不到,再根据类型进行查找
二者支持的参数以及参数的个数完全不同,其中 @Autowired 只支持设置一个 required 的参数。而 @Resource 支持 7 个参数,比如给 @Resource 注解设置 name 和 type 参数,实现代码如下:
- @Resource(name = "userinfo", type = UserInfo.class)
- private UserInfo user;
需要注意的是:
(1)如果实现类里,注解 @Service 没有指定实现类的 bean 名称,则注入的时候默认用该实现类首字母小写的bean的名字
(2)如果用注解 @Service(“dog”) 指定了实现类的 bean 名称,则用注解 @Qualifier(“dog”) 注入的时候,注意名称保持一致
/ˈkwɒlɪfaɪə(r)/ kuao 雷 fai 额
@Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired
@Autowired 注释,它可以对类成员变量、方法及构造函数进行标注,让 spring 完成 bean 自动装配的工作。
@Autowired 默认是按照类型去匹配注入,配合 @Qualifier 按照指定的 name 名称去装配 bean
- @Qualifier("dogPlays" )
- @Autowired
- private PetInterface petInterface;
-
- @Qualifier("catPlays" )
- @Autowired
- private PetInterface petInterface2;
用注解 @Resource(name = " ") 或 @Resource(type = )
替换 @Autowired 、 @Qualifier
这两个组合注解
(1)@Resource后面没有任何内容(既没有指定name,又没有指定type),默认通过 name 属性去匹配 bean 进行装配,如果找不到再按 type 去匹配
(2)如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。
(3)如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,不到则抛出异找常。
(4)如果只指定@Resource注解的type属性,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。
- @Resource(name = "dogPlays")
- private PetInterface petInterface;
-
- @Resource(name = "catPlays")
- private PetInterface petInterface2;
-
- // 或者
-
- @Resource(name = "dogPlays")
- private PetInterface petInterface;
-
- @Resource(type = CatPlays.class)
- private PetInterface petInterface2;
特别需要注意:
boot1.0 配置数据源的过程中主要是写成:spring.datasource.url 和spring.datasource.driverClassName。而在2.0升级之后需要变更成:spring.datasource.jdbc-url和spring.datasource.driver-class-name
否则会报错找不到这些东西
- #整合1.数据源
- spring:
- datasource:
- # 数据源1
- cun-chu-guo-cheng:
- driver-class-name: com.mysql.cj.jdbc.Driver
- jdbc-url: jdbc:mysql://41.18.127.27:3306/cun_chu_guo_cheng?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
- username: root
- password: root
- # 数据源2
- user-infos:
- driver-class-name: com.mysql.cj.jdbc.Driver
- jdbc-url: jdbc:mysql://41.18.127.27:3306/redis?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
- username: root
- password: root
sql日志就不能配置在yml文件中了,需要在代码中设置,其他配置同样如此,比如驼峰映射
数据源1配置
- import org.apache.ibatis.logging.stdout.StdOutImpl;
- import org.apache.ibatis.session.SqlSessionFactory;
- import org.mybatis.spring.SqlSessionFactoryBean;
- import org.mybatis.spring.SqlSessionTemplate;
- import org.mybatis.spring.annotation.MapperScan;
- import org.springframework.beans.factory.annotation.Qualifier;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.boot.jdbc.DataSourceBuilder;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.context.annotation.Primary;
- import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
- import org.springframework.jdbc.datasource.DataSourceTransactionManager;
-
- import javax.sql.DataSource;
-
-
- /**
- * @Description cun-chu-guo-cheng数据源配置
- * @ClassName DataSourceCunChuGuoChengConfig
- * @Author syh
- * @Date 2023/4/21 15:36
- */
- @Configuration
- @MapperScan(basePackages = "com.syh.demo.mapper", sqlSessionFactoryRef = "cunChuGuoChengSqlSessionFactorySecondary")
- public class DataSourceCunChuGuoChengConfig {
-
- /**
- * 创建数据源
- * @return DataSource
- */
- // @Primary: 用于指定bean的注入优先级。被@Primary修饰的bean对象优先注入
- @Primary
- @Bean("cunChuGuoChengDataSource")
- @ConfigurationProperties(prefix = "spring.datasource.cun-chu-guo-cheng")
- public DataSource cunChuGuoChengDataSource() {
- return DataSourceBuilder.create().build();
- }
-
- /**
- * 创建工厂
- *@param dataSource
- *@throws Exception
- *@return SqlSessionFactory
- */
- @Primary
- @Bean(name = "cunChuGuoChengSqlSessionFactorySecondary")
- public SqlSessionFactory sqlSessionFactorySecondary(@Qualifier("cunChuGuoChengDataSource") DataSource dataSource) throws Exception {
- SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
- bean.setDataSource(dataSource);
- bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
-
- //此处创建一个Configuration 注意包不要引错了
- org.apache.ibatis.session.Configuration configuration=new org.apache.ibatis.session.Configuration();
- //配置日志实现
- configuration.setLogImpl(StdOutImpl.class);
- //此处可以添加其他mybatis配置 例如转驼峰命名
- //configuration.setMapUnderscoreToCamelCase(true);
- //bena工厂装载上面配置的Configuration
- bean.setConfiguration(configuration);
-
- return bean.getObject();
- }
-
- /**
- * 创建事务
- *@param dataSource
- *@return DataSourceTransactionManager
- */
- @Bean(name = "cunChuGuoChengTransactionManager")
- @Primary
- public DataSourceTransactionManager masterDataSourceTransactionManager(@Qualifier("cunChuGuoChengDataSource") DataSource dataSource) {
- return new DataSourceTransactionManager(dataSource);
- }
-
- /**
- * 创建模板
- *@param sqlSessionFactory
- *@return SqlSessionTemplate
- */
- @Primary
- @Bean(name = "cunChuGuoChengDataSourceTransactionManager")
- public SqlSessionTemplate SecondaryDataSourceManager(@Qualifier("cunChuGuoChengSqlSessionFactorySecondary")SqlSessionFactory sqlSessionFactory) {
- return new SqlSessionTemplate(sqlSessionFactory);
- }
- }
数据源二配置
- import org.apache.ibatis.logging.stdout.StdOutImpl;
- import org.apache.ibatis.session.SqlSessionFactory;
- import org.mybatis.spring.SqlSessionFactoryBean;
- import org.mybatis.spring.SqlSessionTemplate;
- import org.mybatis.spring.annotation.MapperScan;
- import org.springframework.beans.factory.annotation.Qualifier;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.boot.jdbc.DataSourceBuilder;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
- import org.springframework.jdbc.datasource.DataSourceTransactionManager;
-
- import javax.sql.DataSource;
-
- /**
- * @Description user-infos数据源配置
- * @ClassName DataSourceRedisConfig
- * @Author syh
- * @Date 2023/4/21 15:41
- */
- @Configuration
- @MapperScan(basePackages = "com.syh.demo.mapper1", sqlSessionFactoryRef = "userInfosSqlSessionFactorySecondary")
- public class DataSourceUserInfosConfig {
-
- /**
- * 创建数据源
- * @return DataSource
- * @Primary: 用于指定bean的注入优先级。被@Primary修饰的bean对象优先注入
- */
- @Bean("userInfosDataSource")
- @ConfigurationProperties(prefix = "spring.datasource.user-infos")
- public DataSource userInfosDataSource() {
- return DataSourceBuilder.create().build();
- }
-
- /**
- * 创建工厂
- *@param dataSource
- *@throws Exception
- *@return SqlSessionFactory
- */
- @Bean(name = "userInfosSqlSessionFactorySecondary")
- public SqlSessionFactory sqlSessionFactorySecondary(@Qualifier("userInfosDataSource") DataSource dataSource) throws Exception {
- SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
- bean.setDataSource(dataSource);
- bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper1/*.xml"));
-
- //此处创建一个Configuration 注意包不要引错了
- org.apache.ibatis.session.Configuration configuration=new org.apache.ibatis.session.Configuration();
- //配置日志实现
- configuration.setLogImpl(StdOutImpl.class);
- //bena工厂装载上面配置的Configuration
- bean.setConfiguration(configuration);
-
- return bean.getObject();
- }
-
- /**
- * 创建事务
- *@param dataSource
- *@return DataSourceTransactionManager
- */
- @Bean(name = "userInfosTransactionManager")
- public DataSourceTransactionManager masterDataSourceTransactionManager(@Qualifier("userInfosDataSource") DataSource dataSource) {
- return new DataSourceTransactionManager(dataSource);
- }
-
- /**
- * 创建模板
- *@param sqlSessionFactory
- *@return SqlSessionTemplate
- */
- @Bean(name = "userInfosDataSourceTransactionManager")
- public SqlSessionTemplate SecondaryDataSourceManager(@Qualifier("userInfosSqlSessionFactorySecondary") SqlSessionFactory sqlSessionFactory) {
- return new SqlSessionTemplate(sqlSessionFactory);
- }
- }
为每个数据源添加事务
进行测试
no hang pu
第一步:查询nohup是否安装
which nohup
第二步:下载nohup
yum install coreutils
第三步:查看下载的nohup位置
which nohup
第四步:配置nohup路径,全局使用
vi ~/.bash_profile
在PATH= $PATH: $HOME/bin后面添加:/usr/bin
第五步:是配置的nohup立即生效
source ~/.bash_profile
第六步:测试
nohup --version
第七步:使用示例
- 日志输出
-
- nohup java -jar HsMenQianSiBao-0.0.1.jar >HsMenQianSiBao.log 2>&1 a
-
- 不输出日志
-
- nohup java -jar HsMenQianSiBao-0.0.1-SNAPSHOT.jar &>/dev/null &
- @EnableScheduling
- public class HSSmartCityApplication {
- public static void main(String[] args) {
- SpringApplication.run(HSSmartCityApplication.class, args);
- }
- }
- import org.springframework.scheduling.annotation.Scheduled;
- //服务实现类
- @Service
- public class 类名 extends ServiceImpl<泛型> implements XXXService {
- //定时任务,每15分钟执行一次 /ˈʃedjuːld/
- @Scheduled(cron = "0 0/15 * * * ?")
- public void timingTask(){
- // 定时执行的任务具体内容
- }
- }
- // 每小时0分0秒执行一次
- @Scheduled(cron = "0 0 * * * ?")
-
- // 每两个小时执行一次
- @Scheduled(cron = "0 0 */2 * * ?")
-
- // 每天凌晨两点执行
- @Scheduled(cron = "0 0 2 * * ?")
-
异步easyPoi实现导入功能模板
- 1、启动类加注解
- @EnableAsync
- public class Starter {
- public static void main(String[] args) throws Exception {
- ConfigurableApplicationContext configurableApplicationContext = SpringApplication.run(Starter.class);
- }
-
- }
- 2、controller调用异步方法
- 注意:不能向异步传入MultipartFile 类,步执行的时候,主线程结束,临时文件就会被清空了,就会报错,转换成流的形式传入
- public ResponseJson<String> exportWellLid(MultipartFile multipartFile) {
-
- if (multipartFile == null) {
- return ResponseBuilder.error("30001", "导入数据为空!");
- }
- // 数据的获取需要放到异步之外
- byte [] byteArr= new byte[0];
- try {
- byteArr = multipartFile.getBytes();
- } catch (IOException e) {
- e.printStackTrace();
- }
- InputStream inputStream = new ByteArrayInputStream(byteArr);
- // 开启异步操作
- lidInfoService.exportWellLid(inputStream);
- return ResponseBuilder.success(null,null,"模板后台导入中!");
- }
- 3、异步方法加注解
- @Override
- @Async
- public void exportWellLid(InputStream inputStream) {
-
- ImportParams params = new ImportParams();
- // 设置大标题占几行
- params.setTitleRows(1);
- // 设置小标题占几行
- params.setHeadRows(1);
-
- List<LidInfoSelectPageEntity> excelList = null;
- try {
- // 参数一:导入的文件流 参数二:导入的类型 参数三:导入的配置对象
- excelList = ExcelImportUtil.importExcel(inputStream, LidInfoSelectPageEntity.class, params);
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- // 数据入库
- for (int i = 0; i < excelList.size(); i++) {
- LidInfoSelectPageEntity lidInfoSelectPageEntity = new LidInfoSelectPageEntity();
- // BeanUtils.copyProperties(excelList.get(i), lidInfoSelectPageEntity);
- // System.out.println(lidInfoSelectPageEntity.getLidNum());
- System.out.println(i + "" + excelList.get(i));
- }
- }
定义全局异常处理的类
- @ControllerAdvice
- public class GlobalExceptionHandler {
-
- /**
- * 全局异常捕捉处理
- * @param ex
- * @return
- */
- @ResponseBody
- @ExceptionHandler(value = Exception.class)
- public Result javaExceptionHandler(Exception ex){
- return ResultUtil.error(ResultEnum.SYS_EXCEPTION.getCode(),ex.getMessage());
- }
-
-
- /**
- * 拦截捕捉自定义异常 MyException.class
- * @param ex
- * @return
- */
- @ResponseBody
- @ExceptionHandler(value = UnauthorizedException.class)
- public Result UnauthorizedException(UnauthorizedException ex) {
- return ResultUtil.error(ResultEnum.UNAUTHOR_ERROR);
- }
- }
springboot默认使用jackson作为默认的json解析器
当前端传来的时间格式为字符串,后端使用date。使用这个注解自动转换
当后端将date格式返回给前端,使用注解,可以返回前端时间格式化字符串
- // pattern:你想要其转换的日期格式
- // timezone:是时间设置为东八区,避免时间在转换中差8个钟
- // 评优开始时间
- @JsonFormat(pattern="yyyy-MM-dd",timezone="GMT+8")
- private Date startTime;
在配置文件中添加如下配置
- spring:
- jackson:
- # 全局json时间格式化 date 转 String
- date-format: yyyy-MM-dd HH:mm:ss
- time-zone: GMT+8
- mvc:
- # 表单接收date String 转 date
- format:
- date: yyyy-MM-dd HH:mm:ss
- # 日志配置
- logging:
- level:
- com.mzz.example: warn # 配置example包下的日志级别为waen
上述提到过 lombok 可以实现,这里介绍其他的
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
-
- public class MakeLoggerDemo {
- private static Logger logger = LoggerFactory.getLogger(MakeLoggerDemo.class);
-
- public static void main(String[] args) {
- logger.error("error");
- logger.info("info");
- logger.debug("debug");
- }
- }
默认情况下,SpringBoot内部使用logback作为系统日志实现的框架,将日志输出到控制台,不会写到日志文。
如果在application.properties或application.yml配置,这样只能配置简单的场景,保存路径、日志格式等。复杂的场景(区分 info 和 error 的日志、每天产生一个日志文件等)满足不了
优势:
- <?xml version="1.0" encoding="UTF-8"?>
- <configuration>
- <include resource="org/springframework/boot/logging/logback/base.xml"/>
- <!-- <include resource="org/springframework/boot/logging/logback/defaults.xml"/>-->
- <logger name="org.springframework.web" level="debug"/>
-
- <!-- 定义日志文件 输入位置 -->
- <property name="logDir" value="./logs" />
- <!-- <property name="logDir" value="D:/logs" />-->
- <!-- 日志最大的历史 30天 -->
- <property name="maxHistory" value="30"/>
-
- <!-- 控制台输出日志 -->
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger -%msg%n</pattern>
- <charset class="java.nio.charset.Charset">UTF-8</charset>
- <!-- <pattern>${CONSOLE_LOG_PATTERN}</pattern>-->
- </encoder>
- </appender>
-
- <!-- ERROR级别日志 -->
- <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <filter class="ch.qos.logback.classic.filter.LevelFilter">
- <level>ERROR</level>
- <onMatch>ACCEPT</onMatch>
- <onMismatch>DENY</onMismatch>
- </filter>
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${logDir}\%d{yyyy-MM-dd}\error.log</fileNamePattern>
- <maxHistory>${maxHistory}</maxHistory>
- </rollingPolicy>
- <encoder>
- <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
- <charset class="java.nio.charset.Charset">UTF-8</charset>
- <!-- <pattern>${CONSOLE_LOG_PATTERN}</pattern>-->
- </encoder>
- <append>false</append>
- <prudent>false</prudent>
- </appender>
-
- <!-- WARN级别日志 -->
- <appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <filter class="ch.qos.logback.classic.filter.LevelFilter">
- <level>WARN</level>
- <onMatch>ACCEPT</onMatch>
- <onMismatch>DENY</onMismatch>
- </filter>
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${logDir}\%d{yyyy-MM-dd}\warn.log</fileNamePattern>
- <maxHistory>${maxHistory}</maxHistory>
- </rollingPolicy>
- <encoder>
- <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
- <charset class="java.nio.charset.Charset">UTF-8</charset>
- <!-- <pattern>${CONSOLE_LOG_PATTERN}</pattern>-->
- </encoder>
- <append>false</append>
- <prudent>false</prudent>
- </appender>
-
- <!-- INFO级别日志 -->
- <appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <filter class="ch.qos.logback.classic.filter.LevelFilter">
- <level>INFO</level>
- <onMatch>ACCEPT</onMatch>
- <onMismatch>DENY</onMismatch>
- </filter>
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${logDir}\%d{yyyy-MM-dd}\info.log</fileNamePattern>
- <maxHistory>${maxHistory}</maxHistory>
- </rollingPolicy>
- <encoder>
- <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
- <charset class="java.nio.charset.Charset">UTF-8</charset>
- <!-- <pattern>${CONSOLE_LOG_PATTERN}</pattern>-->
- </encoder>
- <append>false</append>
- <prudent>false</prudent>
- </appender>
-
- <!-- DEBUG级别日志 -->
- <appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <filter class="ch.qos.logback.classic.filter.LevelFilter">
- <level>DEBUG</level>
- <onMatch>ACCEPT</onMatch>
- <onMismatch>DENY</onMismatch>
- </filter>
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${logDir}\%d{yyyy-MM-dd}\debug.log</fileNamePattern>
- <maxHistory>${maxHistory}</maxHistory>
- </rollingPolicy>
- <encoder>
- <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
- <charset class="java.nio.charset.Charset">UTF-8</charset>
- <!-- <pattern>${CONSOLE_LOG_PATTERN}</pattern>-->
- </encoder>
- <append>false</append>
- <prudent>false</prudent>
- </appender>
-
- <!-- root级别 DEBUG -->
- <root level="INFO">
- <!-- 控制台输出 -->
- <appender-ref ref="STDOUT" />
- <!-- 文件输出 -->
- <appender-ref ref="ERROR" />
- <appender-ref ref="INFO" />
- <appender-ref ref="WARN" />
- <appender-ref ref="DEBUG" />
- </root>
- </configuration>
是SpringBoot的最核心的注解,在SpringBoot的主类上,标识是SpringBoot应用,用来开启SpringBoot的各项能力。
由@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan 三个注解组成。这三个注解是一起使用,所以SpringBoot提供了一个统一的注解@SpringBootApplication
/kənˌfɪɡəˈreɪʃ(ə)n/
允许SpringBoot自动装配,开启改注解,SpringBoot能根据当前类路径下的包或者类来配置Spring Bean。@EnableAutoConfiguration实现的关键在于引入了AutoConfigurationImportantSelector,其核心逻辑为selectImports方法,从配置文件MATA-INF/spring.factories加载所有可能用到的自动装配类;exclude excludeName 属性携带的类排除;过滤,将满足条件@Conditional的自动配置类返回。
/kənˌfɪɡəˈreɪʃ(ə)n/
改注解就是@Configuration注解的变体,用来修改SpringBoot配置。
常用的注解@Controller @Service @Repository,有一个共同的注解@Component,@ComponentScan 标注的就会扫描这些注解标注的类到Spring容器中
还有其他
- <!-- Oracle11g 连接驱动依赖。这里是个坑,官方提供的不能用 -->
- <dependency>
- <groupId>cn.easyproject</groupId>
- <artifactId>ojdbc6</artifactId>
- <version>12.1.0.2.0</version>
- </dependency>
- server:
- port: 7100
-
- spring:
- datasource:
- driver-class-name: oracle.jdbc.OracleDriver
- url: jdbc:oracle:thin:@127.0.0.1:1521:syh
- username: SYH
- password: syh
就是用lombok了,同时使用slf4j和lombok的时候会出现这个问题。原因是slf4j和lombok自带的slf4j冲突了
解决:
- //把这俩注释掉
- import com.sun.org.slf4j.internal.Logger;
- import com.sun.org.slf4j.internal.LoggerFactory;
把这俩加上
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
原因:
打包失败,找到这个目录显示“拒绝访问”。也删不掉,这个文件夹在被占用的情况下clean了
解决
第一步:打开资源管理器
第二步:选择性能,再选择打开资源监视器
第三步:管理句柄中搜索 target ,将相关资源关闭掉
- <!-- 测试方法存在问题,打包时需要设置跳过测试忽略问题,直接打包(不影响jar包的部署使用)。-->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <testFailureIgnore>true</testFailureIgnore>
- </configuration>
- </plugin>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。