springboot 基础

巩固基础,砥砺前行 。
只有不断重复,才能做到超越自己。
能坚持把简单的事情做到极致,也是不容易的。

SpringBoot JavaEE 简介

JavaEE的局限性:
1、过于复杂,JavaEE正对的是复杂的分布式企业应用,然而现实情况是大部分应用都是比较简单,复杂的架构带来了复杂的开发方式和部署方式。

2、最求分布式,大部分引用并非都是JavaEE 嘉定的分布式系统,Spring曾经反对过这种分布式架构,并只提供了容器管理,名词获得了成功,大型应用采用分布式架构不可避免,Spring提供了其他的技术支持,eg:RestFul架构

3、不能及时和流行开源技术整合,比如消息处理,除了有了标准的JMS支持,现在还有新能更好的RabbitMQ和kalfa。JavaEE 并没有与之相对应的标准,方二十Spring,具有统一的实现消息处理模式

4、JavaEE 应用服务器都有商业公司提供价格不菲,少有公司采用管理引用服务器和部署应用对初学者和自学者有一定门槛

Spring
Spring通过ioc管理bean,通过Aop方式增强bean功能,它没有像JavaEE那样纤细规定容器提供的是何种服务和容器运行的具体组件类型。

Spring的缺点
尽管Spring很强大,但是他也有JavaEE的缺点:

1、使用门槛升高,要入门spring需要较长时间

2、对过时技术支持,导致使用复杂度升高

3、xml配置已经不再是流行的系统配置方式

4、集成第三方工具的时候,程序员还要考虑工具之间的兼容性

5、系统启动慢,不具备热部署功能,完全依赖虚拟机或者web服务器的热部署

SpringBoot
springboot简化了spring应用配置,不需要配置就能就能运行spring应用,springboot管理spring容器、第三方插件,并提供了许多默认系统级的服务。大部分的spring应用,无论是简单还是复杂,都只需要少量的配置和代码就能完成。springboot通过starter来提供系统级别的服务。在使用的时候,在pom.xml中引入对应的starter即可使用。

相比于spring,springboot优点:

1、实现约定大于配置,是一个低配置的应用系统架构,不像spring那样需要大量的配置。仅仅需要少量的配置就能完成大量的功能

2、提供了内置的tomcat或者jetty功能

3、通过加载jar包管理、自动装配技术,容易支持与其他技术体系、工具集成

4、支持热加载,开发体检好,也支持springboot监控,方便了解系统运行情况。

springboot 配置、加载

加载外部类的几种方式

  1. 使用@Configuration + @Bean 的方式引入
  2. 使用@Configuration + @ImportResource 方式引入
  3. 使用@Configuration + @Import 方式引入

加载配置文件中的属性的方式

  1. @Value(“${}”) 加载单一的配置文件
person.last-name=张三3333333333${random.uuid}
application.properties 文件中
@Value("${person.last-name}")
private String lastName;
  1. 使用@Component、@ConfigurationProperties(prefix = “person”) 从全局的默认配置文件中加载属性
@Component
@ConfigurationProperties(prefix = "person")
public class Person {}application.properties文件中
person.last-name=张三3333333333${random.uuid}
person.age=${random.int}
person.birth=2017/12/15
person.boss=false
person.maps.k1=v1
person.maps.k2=14
person.lists=a,b,c
person.dog.name=${person.hello:hello}_dog
person.dog.age=15
  1. 使用 @Component、@ConfigurationProperties 、@PropertySource 三个注解 从指定位置加载属性
@PropertySource(value = {"classpath:person.properties"})
@Component
@ConfigurationProperties(prefix = "person")
public class Person {private String lastName;private Integer age;private Boolean boss;private Date birth;private Map<String,Object> maps;private List<Object> lists;private Dog dog;
}
classPath 路径下 person.properties 文件中
person.last-name=李四
person.age=12
person.birth=2017/12/15
person.boss=false
person.maps.k1=v1
person.maps.k2=14
person.lists=a,b,c
person.dog.name=dog
person.dog.age=15

profiles

application.yml 中的文档块模式


server:port: 8081
spring:profiles:active: prod  # 激活指定配置文件---
server:port: 8083
spring:profiles: dev---server:port: 8084
spring:profiles: prod  # 该文件被激活

在启动jar包的时候 动态指定jar的端口号

java -jar demo.jar --spring.profiles.active=dev

配置虚拟机参数

-Dspring.profiles.active=dev

在启动jar的时候指定外部的配置文件

 java -jar demo.jar --spring.config.location=G:/application.properties

配置文件的加载顺序

  1. 在相同位置的application.properties 和application.yml 配置文件的加载顺序:从上到下加载,谁在上就加载谁
application.propertiesserver.port=8082application.ymlserver:port: 8081

application.properties 在 application.yml 之上,所以启动的端口号 是8082

在这里插入图片描述

maven简介

maven实现的目标

  1. 是构建项目变得同意,maven屏蔽了构建的复杂过程
  2. 统一了构建下项目的方式,不同人、不同公司的羡慕都有同样的描述和构建项目的方式。maven通过pom.xml来描述项目,并提供了一系列插件来构建项目。
  3. 提出了一套开发项目的最佳实践。而不用每个项目都有不同机构和构建方式。比如源代码出现在scr/main/java中,测试代码出现在scr/main/test中,项目需要的配置文件放在scr/main/resources中
  4. 包含不同环境项目的构建方式
  5. 解决了依赖的问题,只要申明使用的类库,maven会自动冲仓库下载依赖的jar包,并能协助你管理jar之间的冲突

pom中元素介绍

groupId

表示项目所属的组,通常是一个公司或者组织的名称。如。org.springframework

artifactId

项目的唯一标识,如。spring-boot-start-web。groupId 和 artifactId 能唯一标识一个项目或者一个库,通常称之为项目坐标。

packaging

项目类型,常用的有jar和war两种

version

项目的版本号。通常来说,项目版本号分为三段,主版本、此版本、修订版本

主版本:代表脚骨变动或者不见同实现

次版本:是兼容性修改,功能增强

修订版:bug修复

modelVersion

代表pom文件的maven版本。

scope

scope 代表次类库和项目的关系,默认是compile,也就是编译和打包都需要此类库。

test:仅仅在单元测试的时候需要

provided:标识在编译阶段需要词此类库,但是打包不需要,因为项目的目标环境已经提供了

runtime:标识在编译和打包的时候都不需要,但是在运行的时候需要

build

此项目在pom中可选,build包含多个插件plugin,用来辅助构建项目


面试的时候,问过scope

spring boot 发送邮件

1.引入jar

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

2.application.yml配置

spring: mail: #发送消息的邮箱配置username: XXX@qq.com#password是QQ邮箱的授权码 password: snnaaprastgfdebghost: smtp.qq.comproperties: mail: smtp: ssl: enable: true

3.发送简单文本信息

@Autowired
JavaMailSenderImpl mailSender;public void testContext() {SimpleMailMessage message = new SimpleMailMessage();//邮件设置message.setSubject("Topic主题");message.setText("Message……");//发送到哪里message.setTo("XXX@163.com");//从哪里发送message.setFrom("XXX@qq.com");mailSender.send(message);
}

4.发送带有附件的


public void testAA() throws  Exception{//1、创建一个复杂的消息邮件MimeMessage mimeMessage = mailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);//邮件设置helper.setSubject("XXXX");helper.setText("<b style='color:red'>CCCC</b>",true);helper.setTo("15513@163.com");helper.setFrom("291506@qq.com");//上传文件helper.addAttachment("1.jpg",new File("C:\\Users\\DELL\\Pictures\\1.jpg"));helper.addAttachment("2.mp4",new File("C:\\\\Users\\\\DELL\\\\Pictures\\\\2.mp4"));mailSender.send(mimeMessage);}

springboot和redis缓存

redis缓存

1)在pom中新增

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

2)在application.yml中新增redis配置.ookk

	spring: redis: host: localhost

3)配置redis序列化

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;@Configuration
public class MyRedisConfig {@Beanpublic RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(redisConnectionFactory);// 使用Jackson2JsonRedisSerialize 替换默认序列化Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper objectMapper = new ObjectMapper();objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(objectMapper);// 设置value的序列化规则和 key的序列化规则redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);redisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.afterPropertiesSet();return redisTemplate;}
}
  1. java操作redis工具类
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
@SuppressWarnings(value = { "unchecked", "rawtypes" })
@Component
public class RedisCache
{@Autowiredpublic RedisTemplate redisTemplate;/*** 缓存基本的对象,Integer、String、实体类等** @param key 缓存的键值* @param value 缓存的值*/public <T> void setCacheObject(final String key, final T value){redisTemplate.opsForValue().set(key, value);}/*** 缓存基本的对象,Integer、String、实体类等** @param key 缓存的键值* @param value 缓存的值* @param timeout 时间* @param timeUnit 时间颗粒度*/public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit){redisTemplate.opsForValue().set(key, value, timeout, timeUnit);}/*** 设置有效时间** @param key Redis键* @param timeout 超时时间* @return true=设置成功;false=设置失败*/public boolean expire(final String key, final long timeout){return expire(key, timeout, TimeUnit.SECONDS);}/*** 设置有效时间** @param key Redis键* @param timeout 超时时间* @param unit 时间单位* @return true=设置成功;false=设置失败*/public boolean expire(final String key, final long timeout, final TimeUnit unit){return redisTemplate.expire(key, timeout, unit);}/*** 获得缓存的基本对象。** @param key 缓存键值* @return 缓存键值对应的数据*/public <T> T getCacheObject(final String key){ValueOperations<String, T> operation = redisTemplate.opsForValue();return operation.get(key);}/*** 删除单个对象** @param key*/public void deleteObject(final String key){redisTemplate.delete(key);}/*** 删除集合对象** @param collection 多个对象* @return*/public void deleteObject(final Collection collection){redisTemplate.delete(collection);}/*** 缓存List数据** @param key 缓存的键值* @param dataList 待缓存的List数据* @return 缓存的对象*/public <T> long setCacheList(final String key, final List<T> dataList){Long count = redisTemplate.opsForList().rightPushAll(key, dataList);return count == null ? 0 : count;}/*** 获得缓存的list对象** @param key 缓存的键值* @return 缓存键值对应的数据*/public <T> List<T> getCacheList(final String key){return redisTemplate.opsForList().range(key, 0, -1);}/*** 缓存Set** @param key 缓存键值* @param dataSet 缓存的数据* @return 缓存数据的对象*/public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet){BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);Iterator<T> it = dataSet.iterator();while (it.hasNext()){setOperation.add(it.next());}return setOperation;}/*** 获得缓存的set** @param key* @return*/public <T> Set<T> getCacheSet(final String key){return redisTemplate.opsForSet().members(key);}/*** 缓存Map** @param key* @param dataMap*/public <T> void setCacheMap(final String key, final Map<String, T> dataMap){if (dataMap != null) {redisTemplate.opsForHash().putAll(key, dataMap);}}/*** 获得缓存的Map** @param key* @return*/public <T> Map<String, T> getCacheMap(final String key){return redisTemplate.opsForHash().entries(key);}/*** 往Hash中存入数据** @param key Redis键* @param hKey Hash键* @param value 值*/public <T> void setCacheMapValue(final String key, final String hKey, final T value){redisTemplate.opsForHash().put(key, hKey, value);}/*** 获取Hash中的数据** @param key Redis键* @param hKey Hash键* @return Hash中的对象*/public <T> T getCacheMapValue(final String key, final String hKey){HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();return opsForHash.get(key, hKey);}/*** 获取多个Hash中的数据** @param key Redis键* @param hKeys Hash键集合* @return Hash对象集合*/public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys){return redisTemplate.opsForHash().multiGet(key, hKeys);}/*** 获得缓存的基本对象列表** @param pattern 字符串前缀* @return 对象列表*/public Collection<String> keys(final String pattern){return redisTemplate.keys(pattern);}
}

springboot本地缓存

缓存

本地缓存
1)启动类增加注解 @EnableCaching // 开启缓存
2)在service层代码中增加注解,进行测试
本地缓存使用的是currentHashMap

	```import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cache.annotation.CacheEvict;import org.springframework.cache.annotation.CachePut;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Service;import com.ttzz.bean.Dog;import com.ttzz.mapper.DataDemo;@Service/*** @CacheConfig(cacheNames = {},cacheManager=AAAA,cacheResolver = {})*/public class DogService {@Autowiredprivate DataDemo dataDemo;/*** @Cacheable:先在缓存中查找,如果没有该缓存,则创建,查询数据,放入缓存,并返回数据* 			 参数:1)cacheNames/value:* 				 2)key:* 				 3)keyGenerator:* 				 4)cacheManager:* 				 5)condition:* 				 6)unless:	* 				 7)sync:*/@Cacheable(value = "dog",/*cacheNames = ,keyGenerator = ,condition = ,unless =  ,sync = true*/key = "#id")public Dog getById(String id) {return dataDemo.getById(id);}/*** @CachePut: 先调用目标方法,然后调用缓存信息*/@CachePut(value = "dog",key="#dog.id")public void save(Dog dog) {dataDemo.save(dog);}@CachePut(value = "dog",key="#dog.id")public void update(Dog dog) {dataDemo.update(dog);}/*** @CacheEvict:* allEntries:删除整个缓存中的数据* beforeInvocation:执行方法前删除还是执行方法后删除*/@CacheEvict(value = "dog" /* allEntries = true, beforeInvocation = true*/,key="#id")public void delete(String id) {dataDemo.delete(id);}/*** @Caching:复合注解* @Caching(cacheable = {@Cacheable(value = )},put = {@CachePut()})*/}```

SpringBoot以jar启动加载外部配置文件

SpringBoot以jar启动加载外部配置文件

通常需要将SpringBoot打成jar的方式来启动,有时候也需要将配置文件放到项目(jar)外。如何访问外部的配置文件呢?


使用以下命令来操作
命令1
java -jar XXX.jar -Dspring.config.location=D:\workspace-test\work02\seed-java\seed-framework\target\_config\application.yml
命令2
java -jar D:\workspace-test\work02\seed-java\seed-framework\target\XXX.jar -Dspring.config.location=D:\workspace-test\work02\seed-java\seed-framework\target\_config\application.yml -Dspring.profiles.active=test

SpringBoot 读取应用配置文件

springboot读取配置文件有三种方式
  1. 使用environment类,可以通过key-value的方式读取到application.properties中的数据
  2. 使用@value注解,使用spel表达式,注入属性值
  3. 使用@configurationProperties注解
environment

environment是一个通用的读取应用运行时的环境变量的类,可以读取application。properties,命令函输入参数、系统属性、操作系统环境变量等

@Autowired
private Environment env;

使用方法:env.getProperty(XXXX)

@value

直接通过@value注入一个配置信息到bean

@configurationProperties

该注解可以将同样类型的配置映射成为一个类,方便使用。一般和@Configuration注解配合使用。它和@value功能差不多,它不能读取yml文件中的属性信息,@value可以,@value支持spel表达式。

SpringBoot之Jackson注解

Jackson有多个注解,用来在序列化和反序列化操作

@JsonProperty("XXXX") //为key指定一个别名
private String aa;
@JsonIgnore("XXXX") //忽略此属性
private String aa;
@JsonIgnoreProperties({"XXXX","BBBB"}) //忽略多个属性,作用在类上
private class aa{}
@JsonFormat(pattern = "yyyy-mm-dd") //忽略此属性
private Date aa;

Jackson支持三种序列化和反序列化的方式

  1. 使用JsonParser来解析json,解析结果是一串tokens,采用jsonGenerator来生成json,这是最底层的方式
  2. 采用树遍历的方式 json被读入到jsonnode对象中,可以像操作xmldom那样读取json
  3. 采用dataBind方式,将实体类对象序列化成json,或者反序列化成实体对象,这是最简单的一种。对于应用程序来说最常用的是第三种。

SpringBoot Mock代码测试

增删改查代码


import java.net.URI;
import javax.annotation.Resource;import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.WebApplicationContext;@RunWith(SpringRunner.class)
@SpringBootTest(classes = XXXX.class)
@WebAppConfiguration
//配置事务的回滚,对数据库的增删改都会回滚,便于测试用例的循环利用
@Transactional(transactionManager = "transactionManager")
@Rollback(value = true)
public class BySpecimenControllerTest {@Autowiredprivate WebApplicationContext webApplicationContext;private MockMvc mockMvc;public String token;@Resourceprivate SysLoginService loginService;@Beforepublic void setupMockMvc() {mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
//        token = }@Testpublic void testDeleteBySpecimen () throws Exception{String id = "1";mockMvc.perform(MockMvcRequestBuilders.delete("/bySpecimens/delete/"+id)
//    		.header("Authorization", "Bearer "+token+"")).andExpect(MockMvcResultMatchers.status().isOk()).andDo(MockMvcResultHandlers.print());}@Testpublic void testFindBySpecimenById() throws Exception {String id = "1";mockMvc.perform(MockMvcRequestBuilders.get(new URI("/bySpecimens/info")).param("opertationId", id)).andExpect(MockMvcResultMatchers.status().isOk()).andDo(MockMvcResultHandlers.print());}@Testpublic void testFindBySpecimens () throws Exception{mockMvc.perform(MockMvcRequestBuilders.get("/bySpecimens/list")
//    			 .header("Authorization", "Bearer "+token+"")).andExpect(MockMvcResultMatchers.status().isOk()).andDo(MockMvcResultHandlers.print());}@Testpublic void testSaveBySpecimen() throws Exception {mockMvc.perform(MockMvcRequestBuilders.post("/bySpecimens/save")
//    	 		.header("Authorization", "Bearer "+token+"")// 标本标识.param("specimenId", "value") .param("status", "0") ).andExpect(MockMvcResultMatchers.status().isOk()).andDo(MockMvcResultHandlers.print());}@Testpublic void testUpdateBySpecimen () throws Exception {mockMvc.perform(MockMvcRequestBuilders.put("/bySpecimens/save")
//   	 			.header("Authorization", "Bearer "+token+"")// 标本标识.param("specimenId", "1") .param("status", "1") ).andExpect(MockMvcResultMatchers.status().isOk()).andDo(MockMvcResultHandlers.print());}}
使用实体作为参数,需要在Controller 的参数 使用@RequestBody 标记A domain = new A();//设置参数//domain.setString jsonStr = JSONObject.toJSONString(domain);mockMvc.perform(MockMvcRequestBuilders.put("/As/save").header("Authorization", "Bearer "+token+"").accept(MediaType.APPLICATION_JSON_UTF8).contentType(MediaType.APPLICATION_JSON_UTF8).content(jsonStr)).andExpect(MockMvcResultMatchers.status().isOk()).andDo(MockMvcResultHandlers.print());

SpringBoot+Mybatis 实现多数据源配置(基于分包管理)、Swagger配置

1.本文主要是基于分包管理来实现多数据源的方式,简单易用
2.Swagger配置

pom.xml配置

<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><groupId>XXX</groupId><artifactId>XXX</artifactId><version>0.0.1-SNAPSHOT</version><name>sXXX</name><description>XXX</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.13.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><java.version>1.8</java.version><mybatis-plus.version>3.1.2</mybatis-plus.version><pagehelper.spring.boot.starter.version>1.2.5</pagehelper.spring.boot.starter.version><druid.version>1.1.17</druid.version><jwt.version>0.9.1</jwt.version><fastjson.version>1.2.60</fastjson.version><swagger.version>2.9.2</swagger.version><commons.version>2.6</commons.version><bitwalker.version>1.19</bitwalker.version><guava.version>26.0-jre</guava.version><commons.io.version>2.5</commons.io.version><oshi.version>3.9.1</oshi.version><seed.common.version>0.0.1-SNAPSHOT</seed.common.version><oracle.version>12.1.0.2</oracle.version></properties><dependencies><!-- https://mvnrepository.com/artifact/org.apache.clerezza.ext/org.json.simple --><dependency><groupId>org.apache.clerezza.ext</groupId><artifactId>org.json.simple</artifactId><version>0.4</version></dependency><!--常用工具类 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency><!--io常用工具类 --><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId></dependency><!-- poi --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.15</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.15</version></dependency><!-- 解析客户端操作系统、浏览器等 --><dependency><groupId>eu.bitwalker</groupId><artifactId>UserAgentUtils</artifactId></dependency><!-- 获取系统信息 --><dependency><groupId>com.github.oshi</groupId><artifactId>oshi-core</artifactId></dependency><dependency><groupId>net.java.dev.jna</groupId><artifactId>jna</artifactId></dependency><dependency><groupId>net.java.dev.jna</groupId><artifactId>jna-platform</artifactId></dependency><!--Spring框架基本的核心工具--><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId></dependency><!-- pagehelper 分页插件 --><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><exclusions><exclusion><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId></exclusion><exclusion><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId></exclusion></exclusions></dependency><!-- oracle 驱动 --><dependency><groupId>com.oracle</groupId><artifactId>ojdbc7</artifactId><version>12.1.0.2</version></dependency><!-- mysql 驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.46</version></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-core</artifactId><version>5.1.8.RELEASE</version><scope>compile</scope></dependency><!-- 引入freeMarker的依赖包. --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><dependency><groupId>net.hasor</groupId><artifactId>hasor-spring</artifactId><version>4.1.3</version></dependency><dependency><groupId>net.hasor</groupId><artifactId>hasor-dataway</artifactId><version>4.1.3-fix20200414</version><!-- 4.1.3 包存在UI资源缺失问题 --></dependency><!-- 集成SpringMvc框架并实现自动配置 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><!-- Redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency><!-- mybatis-plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis-plus.version}</version></dependency><!-- druid --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>${druid.version}</version></dependency><!-- json --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version></dependency><!-- oracle驱动 --><!--<dependency><groupId>com.oracle</groupId><artifactId>ojdbc7</artifactId><version>${oracle.version}</version></dependency>--><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- Swagger API文档 --><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>${swagger.version}</version><exclusions><exclusion><groupId>io.swagger</groupId><artifactId>swagger-annotations</artifactId></exclusion><exclusion><groupId>io.swagger</groupId><artifactId>swagger-models</artifactId></exclusion></exclusions></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>${swagger.version}</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-bean-validators</artifactId><version>${swagger.version}</version></dependency><!-- 防止进入swagger页面报类型转换错误,排除2.9.2中的引用,手动增加1.5.22版本 --><dependency><groupId>io.swagger</groupId><artifactId>swagger-annotations</artifactId><version>1.5.22</version></dependency><dependency><groupId>io.swagger</groupId><artifactId>swagger-models</artifactId><version>1.5.22</version></dependency><!-- 测试单元 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><dependencyManagement><dependencies><!-- pagehelper 分页插件 --><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>${pagehelper.spring.boot.starter.version}</version></dependency><!--io常用工具类 --><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>${commons.io.version}</version></dependency><!-- 解析客户端操作系统、浏览器等 --><dependency><groupId>eu.bitwalker</groupId><artifactId>UserAgentUtils</artifactId><version>${bitwalker.version}</version></dependency><!-- 获取系统信息 --><dependency><groupId>com.github.oshi</groupId><artifactId>oshi-core</artifactId><version>${oshi.version}</version></dependency></dependencies></dependencyManagement></project>

多数据源配置代码

1.主数据源配置

@Primary 标注的是主数据源

import javax.sql.DataSource;import org.apache.ibatis.annotations.Mapper;
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 org.springframework.transaction.PlatformTransactionManager;@Configuration
@MapperScan(basePackages = {"包路径.mapper.数据库标识1mapper" }, annotationClass = Mapper.class, sqlSessionFactoryRef = "数据库标识1SqlSessionFactory")
public class 数据库标识1MybatisConfig {/*** @return 返回DataSource对象*/@Bean(name = "数据库标识1DataSource")@Qualifier("数据库标识1DataSource")@ConfigurationProperties(prefix = "spring.datasource.数据库标识1")@Primarypublic DataSource cmsDataSource() {return DataSourceBuilder.create().build();}@Bean(name = "数据库标识1SqlSessionFactory")@Primarypublic SqlSessionFactory sqlSessionFactory(@Qualifier("数据库标识1DataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);sqlSessionFactoryBean.setMapperLocati数据库标识1(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/数据库标识1mapper/*.xml"));return sqlSessionFactoryBean.getObject();}@Bean(name = "数据库标识1PlatformTransactionManager")public PlatformTransactionManager transactionManager(@Qualifier("数据库标识1DataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}@Bean("数据库标识1SqlSessionTemplate")// 表示这个数据源是默认数据源@Primarypublic SqlSessionTemplate test1sqlsessiontemplate(@Qualifier("数据库标识1SqlSessionFactory") SqlSessionFactory sessionfactory) {return new SqlSessionTemplate(sessionfactory);}
}

2.第二个数据源配置

如何扩展 第三、第四数据源呢?
(1)复制第二数据源配置类,简单修改注解中的名称
(2)在resource的mapper文件夹下创建XXXmapper,用来存放XXXXMapper.xml文件
特别注意没有primary修饰了哦

import javax.sql.DataSource;import org.apache.ibatis.annotations.Mapper;
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 org.springframework.transaction.PlatformTransactionManager;@Configuration
@MapperScan(basePackages = {"包路径.mapper.数据库标识2mapper" }, annotationClass = Mapper.class, sqlSessionFactoryRef = "数据库标识2SqlSessionFactory")
public class 数据库标识2MybatisConfig {/*** @return 返回DataSource对象*/@Bean(name = "数据库标识2DataSource")@Qualifier("数据库标识2DataSource")@ConfigurationProperties(prefix = "spring.datasource.数据库标识2")public DataSource cmsDataSource() {return DataSourceBuilder.create().build();}@Bean(name = "数据库标识2SqlSessionFactory")@Primarypublic SqlSessionFactory sqlSessionFactory(@Qualifier("数据库标识2DataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);sqlSessionFactoryBean.setMapperLocati数据库标识2(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/数据库标识2mapper/*.xml"));return sqlSessionFactoryBean.getObject();}@Bean(name = "数据库标识2PlatformTransactionManager")public PlatformTransactionManager transactionManager(@Qualifier("数据库标识2DataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}@Bean("数据库标识2SqlSessionTemplate")// 表示这个数据源是默认数据源@Primarypublic SqlSessionTemplate test1sqlsessiontemplate(@Qualifier("数据库标识2SqlSessionFactory") SqlSessionFactory sessionfactory) {return new SqlSessionTemplate(sessionfactory);}
}

resource下application.yml 中的数据源信息配置信息

spring:profiles: active: devmvc: static-path-pattern: /**resource: static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/datasource:
#数据库标识1数据源配置数据库标识1: jdbc-url: jdbc:mysql://ip:3306/d1?useUnicode=true&characterEncoding=utf8&useSSL=falseusername: XXXpassword: XXXmaxActive: 50initialSize: 10maxWait: 60000minIdle: 1timeBetweenEvictionRunsMillis: 60000minEvictableIdleTimeMillis: 300000maxOpenPreparedStatements: 2type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverfilters: statvalidationQuery: select version()testWhileIdle: truetestOnBorrow: falsetestOnReturn: falsepoolPreparedStatements: true
#数据库标识2数据源配置数据库标识2:jdbc-url: jdbc:oracle:thin:@ip:1521:XXXusername: XXXpassword: XXXmaxActive: 50initialSize: 5maxWait: 60000minIdle: 1timeBetweenEvictionRunsMillis: 60000minEvictableIdleTimeMillis: 300000maxOpenPreparedStatements: 2type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: oracle.jdbc.OracleDriverfilters: statvalidationQuery: select * from dualtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsepoolPreparedStatements: true

Swagger类配置 SwaggerConfig.java

import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.Contact;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;import java.util.ArrayList;
import java.util.List;
@Configuration
@EnableSwagger2
public class SwaggerConfig {/*** 创建API*/@Beanpublic Docket createRestApi() {return new Docket(DocumentationType.SWAGGER_2).enable(true).apiInfo(apiInfo()).select().apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).paths(PathSelectors.any()).build()/* 设置安全模式,swagger可以设置访问token */.securitySchemes(securitySchemes()).securityContexts(securityContexts());}/*** 安全模式,这里指定token通过Authorization头请求头传递*/private List<ApiKey> securitySchemes() {List<ApiKey> apiKeyList = new ArrayList<ApiKey>();apiKeyList.add(new ApiKey("Authorization", "Authorization", "header"));return apiKeyList;}/*** 安全上下文*/private List<SecurityContext> securityContexts() {List<SecurityContext> securityContexts = new ArrayList<>();securityContexts.add(SecurityContext.builder().securityReferences(defaultAuth()).forPaths(PathSelectors.regex("^(?!auth).*$")).build());return securityContexts;}/*** 默认的安全上引用*/private List<SecurityReference> defaultAuth() {AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];authorizationScopes[0] = authorizationScope;List<SecurityReference> securityReferences = new ArrayList<>();securityReferences.add(new SecurityReference("Authorization", authorizationScopes));return securityReferences;}/*** 添加摘要信息*/private ApiInfo apiInfo() {// 用ApiInfoBuilder进行定制return new ApiInfoBuilder()// 设置标题.title("XXXX_接口文档")// 描述.description("XXXX所有API接口")// 作者信息.contact(new Contact("XXXX", null, null))// 版本.version("版本号:1.0" ).build();}
}

SpringBoot引入外部jar,并将项目打包成jar包,引发项目运行失败的问题

SpringBoot引入外部jar,并将项目打包成jar包

正常打包操作
  • 在src/main/resource 目录下创建一个lib文件夹,将需要打如到项目中的jar放在这里
  • 通过build path 将这些jar加入到工程中,以方便调用
  • 在pom.xml中增加,其中xxx看实际情况而定
	<dependencies><dependency><groupId>XXX</groupId><artifactId>XXX</artifactId><version>XXX</version><scope>system</scope><systemPath>${project.basedir}/src/main/resources/lib/XXX.jar</systemPath></dependency></dependencies>
  • 在pom.xml中增加build 逻辑
<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><includeSystemScope>true</includeSystemScope></configuration></plugin></plugins><resources><resource><directory>lib</directory><targetPath>BOOT-INF/lib/</targetPath><includes><include>**/*.jar</include></includes></resource><resource><directory>src/main/resources</directory><targetPath>BOOT-INF/classes/</targetPath></resource></resources></build>
特别注意: 上面的build中的代码仅仅是在打包的时候打开,在运行项目的时候,需要将上面的代码注释掉。不然会报错:找不到XXXMapper.xml mybatis对应的xml文件。

【转载】springboot引入外部依赖jar包


今天项目(springboot项目)中需要导入外部的jar包,在打包的时候需要将外部jar打到项目中。就这一个问题,CSDN中有好多的提示的文章。真TM傻逼啊,发文章之前,自己就不测试一下吗?自己在网上随便找一个案例,正好满足自己的要求,就直接用了,标题都TM不调整一下,也不看看人家的标题和你自己写的是不是一个意思。误人子弟。

正解文件连接:

springboot引入外部依赖jar包_springboot引入外部jar包_半山惊竹的博客-CSDN博客

RestTemplateUtil 工具类

两个系统之间做数据交互,一般都是使用接口的方式,在SpringBoot中提供了一个RestTemplate类,方便调用。

以下是一个简单封装,方便使用
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;import com.alibaba.fastjson.JSONObject;import lombok.extern.slf4j.Slf4j;@Slf4j
public class RestTemplateUtil {/*** restTemplate 发送post请求* @param restTemplate* @param url* @param json* @return*/public static ResponseEntity<String> getRestTemplatePost(RestTemplate restTemplate,String url,String json){HttpHeaders headers = new HttpHeaders();headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));headers.setContentType(MediaType.APPLICATION_JSON_UTF8);HttpEntity<String> requestEntity = new HttpEntity<String>(json,headers);ResponseEntity<String> entity = restTemplate.postForEntity(url, requestEntity, String.class);return entity;}/*** restTemplate 发送get请求* @param restTemplate* @param url* @param json* @return*/public static ResponseEntity<String> getRestTemplateGet(RestTemplate restTemplate,String url,String json){HttpHeaders headers = new HttpHeaders();headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));headers.setContentType(MediaType.APPLICATION_JSON_UTF8);HttpEntity<String> requestEntity = new HttpEntity<String>(json,headers);ResponseEntity<String> entity = restTemplate.getForEntity(url, String.class,json);return entity;}public static Map<String, String> parseResponseEntity(ResponseEntity<String> entity) {Map<String,String> map = new HashMap<String,String>();log.info("ResponseEntity="+JSONObject.toJSONString(entity));Integer code = entity.getStatusCodeValue();if(entity.getStatusCodeValue()==200) {JSONObject obj = JSONObject.parseObject(entity.getBody());map.put("code", code+"");map.put("data", obj.getString("data").toString());}log.info(JSONObject.toJSONString(map));return map;}}

关于@Transactional 的sao操作

关于@Transactional 作用的一些测试

    • SpringBoot JavaEE 简介
    • springboot 配置、加载
      • 加载外部类的几种方式
      • 加载配置文件中的属性的方式
      • profiles
        • 在启动jar包的时候 动态指定jar的端口号
        • 配置虚拟机参数
        • 在启动jar的时候指定外部的配置文件
      • 配置文件的加载顺序
    • maven简介
        • maven实现的目标
        • pom中元素介绍
          • groupId
          • artifactId
          • packaging
          • version
        • modelVersion
        • scope
        • build
    • spring boot 发送邮件
      • 1.引入jar
      • 2.application.yml配置
      • 3.发送简单文本信息
      • 4.发送带有附件的
    • springboot和redis缓存
      • redis缓存
    • springboot本地缓存
      • 缓存
    • SpringBoot以jar启动加载外部配置文件
  • SpringBoot以jar启动加载外部配置文件
          • 使用以下命令来操作
            • 命令1
            • 命令2
    • SpringBoot 读取应用配置文件
          • springboot读取配置文件有三种方式
            • environment
            • @value
            • @configurationProperties
    • SpringBoot之Jackson注解
        • Jackson支持三种序列化和反序列化的方式
    • SpringBoot Mock代码测试
    • SpringBoot+Mybatis 实现多数据源配置(基于分包管理)、Swagger配置
      • pom.xml配置
      • 多数据源配置代码
        • 1.主数据源配置
        • 2.第二个数据源配置
        • resource下application.yml 中的数据源信息配置信息
      • Swagger类配置 SwaggerConfig.java
    • SpringBoot引入外部jar,并将项目打包成jar包,引发项目运行失败的问题
            • 正常打包操作
            • **特别注意:** 上面的build中的代码仅仅是在打包的时候打开,在运行项目的时候,需要将上面的代码注释掉。不然会报错:找不到XXXMapper.xml mybatis对应的xml文件。
    • 【转载】springboot引入外部依赖jar包
    • RestTemplateUtil 工具类
            • 以下是一个简单封装,方便使用
    • 关于@Transactional 的sao操作
      • case1 无try catch、无嵌套,没有加 rollbackFor = Exception.class 事务正常回滚
      • case2 无try catch、无嵌套,加 rollbackFor = Exception.class 事务正常回滚
      • case3 没有加 rollbackFor = Exception.class 事务没有回滚
      • case4 有try catch、无嵌套,加 rollbackFor = Exception.class 事务没有回滚
      • case5 有try catch、无嵌套,加 rollbackFor = Exception.class ,抛出异常 。 事务正常回滚
      • case6 有try catch、无嵌套,加 rollbackFor = Exception.class ,抛出异常。方法调用,事务没有回滚
      • case7 事务没有回滚
      • case8 事务回滚
      • case9 事务回滚
      • case10 事务未回滚
      • case11 事务回滚
      • case12 事务未回滚
      • case13 事务回滚
      • case14 事务回滚
      • case15 事务回滚
    • dynamic-datasource 使用

在使用@Transactional  关键字的时候,总会有这样 或者 那有的问题。一下做一些测试来验证问题

case1 无try catch、无嵌套,没有加 rollbackFor = Exception.class 事务正常回滚

@Transactionalpublic int testSave()  {User user = new User();user.setName("岳不群2");user.setAge(70);user.setEmail("lucy@qq.com");userMapper.insert(user);int m = 1/0;return 1;}

case2 无try catch、无嵌套,加 rollbackFor = Exception.class 事务正常回滚

@Transactional(rollbackFor = Exception.class)public int testSave()  {User user = new User();user.setName("岳不群2");user.setAge(70);user.setEmail("lucy@qq.com");userMapper.insert(user);int m = 1/0;return 1;}

case3 没有加 rollbackFor = Exception.class 事务没有回滚

@Transactionalpublic int testSave()  {try {User user = new User();user.setName("岳不群2");user.setAge(70);user.setEmail("lucy@qq.com");userMapper.insert(user);int m = 1/0;return 1;} catch (Exception e) {// TODO: handle exception}return 0;}

case4 有try catch、无嵌套,加 rollbackFor = Exception.class 事务没有回滚

@Transactional(rollbackFor = Exception.class)public int testSave()  {try {User user = new User();user.setName("岳不群2");user.setAge(70);user.setEmail("lucy@qq.com");userMapper.insert(user);int m = 1/0;return 1;} catch (Exception e) {// TODO: handle exception}return 0;}

case5 有try catch、无嵌套,加 rollbackFor = Exception.class ,抛出异常 。 事务正常回滚

@Transactional(rollbackFor = Exception.class)public int testSave() throws Exception  {try {User user = new User();user.setName("岳不群2");user.setAge(70);user.setEmail("lucy@qq.com");userMapper.insert(user);int m = 1/0;return 1;} catch (Exception e) {throw new Exception(e.getMessage());}}

case6 有try catch、无嵌套,加 rollbackFor = Exception.class ,抛出异常。方法调用,事务没有回滚

public int testSave() throws Exception {return testSave2();}@Transactional(rollbackFor = Exception.class)public int testSave2() throws Exception  {try {User user = new User();user.setName("岳不群2");user.setAge(70);user.setEmail("lucy@qq.com");userMapper.insert(user);int m = 1/0;return 1;} catch (Exception e) {System.out.println(e.getMessage());throw new Exception(e.getMessage());}}

case7 事务没有回滚

@Transactionalpublic int testSave() throws Exception {return testSave2();}@Transactional(rollbackFor = Exception.class)public int testSave2() throws Exception  {try {User user = new User();user.setName("岳不群2");user.setAge(70);user.setEmail("lucy@qq.com");userMapper.insert(user);int m = 1/0;return 1;} catch (Exception e) {System.out.println(e.getMessage());throw new Exception(e.getMessage());}}

case8 事务回滚

@Transactional(rollbackFor = Exception.class)public int testSave() throws Exception {return testSave2();}public int testSave2() throws Exception  {try {User user = new User();user.setName("岳不群2");user.setAge(70);user.setEmail("lucy@qq.com");userMapper.insert(user);int m = 1/0;return 1;} catch (Exception e) {System.out.println(e.getMessage());throw new Exception(e.getMessage());}}

case9 事务回滚

@Transactional(rollbackFor = Exception.class)public int testSave() throws Exception {return testSave2();}@Transactional(rollbackFor = Exception.class)public int testSave2() throws Exception  {try {User user = new User();user.setName("岳不群2");user.setAge(70);user.setEmail("lucy@qq.com");userMapper.insert(user);int m = 1/0;return 1;} catch (Exception e) {System.out.println(e.getMessage());throw new Exception(e.getMessage());}}

case10 事务未回滚

@Transactionalpublic int testSave() throws Exception {return testSave2();}@Transactional(rollbackFor = Exception.class)public int testSave2() throws Exception  {try {User user = new User();user.setName("岳不群2");user.setAge(70);user.setEmail("lucy@qq.com");userMapper.insert(user);int m = 1/0;return 1;} catch (Exception e) {System.out.println(e.getMessage());throw new Exception(e.getMessage());}}

case11 事务回滚

@Transactional(rollbackFor = Exception.class)public int testSave() throws Exception {return testSave2();}@Transactionalpublic int testSave2() throws Exception  {try {User user = new User();user.setName("岳不群2");user.setAge(70);user.setEmail("lucy@qq.com");userMapper.insert(user);int m = 1/0;return 1;} catch (Exception e) {System.out.println(e.getMessage());throw new Exception(e.getMessage());}}

case12 事务未回滚

@Transactional(rollbackFor = Exception.class)public int testSave() throws Exception {return testSave2();}@Transactionalpublic int testSave2()  {try {User user = new User();user.setName("岳不群2");user.setAge(70);user.setEmail("lucy@qq.com");userMapper.insert(user);int m = 1/0;return 1;} catch (Exception e) {System.out.println(e.getMessage());}return 0;}

case13 事务回滚

@Transactional(rollbackFor = Exception.class)public int testSave() throws Exception {int m =  testSave2();int n = 1/0;return m;}@Transactionalpublic int testSave2()  {try {User user = new User();user.setName("岳不群2");user.setAge(70);user.setEmail("lucy@qq.com");userMapper.insert(user);return 1;} catch (Exception e) {System.out.println(e.getMessage());}return 0;}

case14 事务回滚

@Transactional(rollbackFor = Exception.class)public int testSave() throws Exception {int m =  testSave2();int n = 1/0;return m;}public int testSave2()  {try {User user = new User();user.setName("岳不群2");user.setAge(70);user.setEmail("lucy@qq.com");userMapper.insert(user);return 1;} catch (Exception e) {System.out.println(e.getMessage());}return 0;}

case15 事务回滚

@Transactional(rollbackFor = Exception.class)public int testSave() throws Exception {int m =  testSave2();int n = 1/0;return m;}@Transactional(rollbackFor = Exception.class)public int testSave2()  {try {User user = new User();user.setName("岳不群2");user.setAge(70);user.setEmail("lucy@qq.com");userMapper.insert(user);return 1;} catch (Exception e) {System.out.println(e.getMessage());}return 0;}

dynamic-datasource 使用

1)在项目中引入dynamic-datasource该modul
2)在application.yml中添加

dynamic:datasource:slave1: driver-class-name: oracle.jdbc.OracleDriverurl: jdbc:oracle:thin:XXX:orcl_tjhusername: XXpassword: XXvalidation-query: SELECT 1 FROM DUALslave2: driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/XXX?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghaiusername: XXXXpassword: XXXX
  1. 在项目中使用,dynamic 配置的都是子数据源。
    在访问的service 方法上 使用@DataSource(数据源表示);如上的slave1

【临渊羡鱼不如退而结网】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/66001.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ajax 笔记(一)—— Ajax 入门

笔记目录 1. Ajax 入门1.1 Ajax 概念1.2 axios 使用1.2.1 URL1.2.2 URL 查询参数1.2.3 小案例-查询地区列表1.2.4 常用请求方法和数据提交1.2.5 错误处理 1.3 HTTP 协议1.3.1 请求报文1.3.2 响应报文 1.4 接口文档1.5 案例1.5.1 用户登录&#xff08;主要业务&#xff09;1.5.2…

二、编写第一个 Spring MVC 程序

文章目录 一、编写第一个 Spring MVC 程序 一、编写第一个 Spring MVC 程序 创建 maven 项目&#xff0c;以此项目为父项目&#xff0c;在父项目的 pom.xml 中导入相关依赖 <dependencies><dependency><groupId>junit</groupId><artifactId>…

Spring Gateway+Security+OAuth2+RBAC 实现SSO统一认证平台

背景&#xff1a;新项目准备用SSO来整合之前多个项目的登录和权限&#xff0c;同时引入网关来做后续的服务限流之类的操作&#xff0c;所以搭建了下面这个系统雏形。 关键词&#xff1a;Spring Gateway, Spring Security, JWT, OAuth2, Nacos, Redis, Danymic datasource, Jav…

Android学习之路(3) 布局

线性布局LinearLayout 前几个小节的例程中&#xff0c;XML文件用到了LinearLayout布局&#xff0c;它的学名为线性布局。顾名思义&#xff0c;线性布局 像是用一根线把它的内部视图串起来&#xff0c;故而内部视图之间的排列顺序是固定的&#xff0c;要么从左到右排列&#xf…

【Java】项目管理工具Maven的安装与使用

文章目录 1. Maven概述2. Maven的下载与安装2.1 下载2.2 安装 3. Maven仓库配置3.1 修改本地仓库配置3.2 修改远程仓库配置3.3 修改后的settings.xml 4. 使用Maven创建项目4.1 手工创建Java项目4.2 原型创建Java项目4.3 原型创建Web项目 5. Tomcat启动Web项目5.1 使用Tomcat插件…

C# OpenCvSharp 颜色反转

效果 灰度图 黑白色反转 彩色反转 项目 代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using OpenCvSharp; using Ope…

JDK、JRE、JVM:揭秘Java的关键三者关系

文章目录 JDK&#xff1a;Java开发工具包JRE&#xff1a;Java运行环境JVM&#xff1a;Java虚拟机关系概述 案例示例&#xff1a;Hello World结语 在Java世界中&#xff0c;你可能经常听到JDK、JRE和JVM这几个概念&#xff0c;它们分别代表了Java开发工具包、Java运行环境和Java…

Web framework-Gin

一、Gin Go Web--Go Module 软件框架&#xff08;software framework&#xff09;&#xff0c;通常指的是为了实现某个业界标准或完成特定基本任务的软件组件规范&#xff0c;也指为了实现某个软件组件规范时&#xff0c;提供规范所要求之基础功能的软件产品。 框架就是&#…

Hugging Face 的文本生成和大语言模型的开源生态

[更新于 2023 年 7 月 23 日: 添加 Llama 2。] 文本生成和对话技术已经出现多年了。早期的挑战在于通过设置参数和分辨偏差&#xff0c;同时控制好文本忠实性和多样性。更忠实的输出一般更缺少创造性&#xff0c;并且和原始训练数据更加接近&#xff0c;也更不像人话。最近的研…

webpack中常见的Loader

目录 1.webpack中的loader是什么&#xff1f;配置方式 2. loader特性3.常见的loader 1.webpack中的loader是什么&#xff1f; loader 用于对模块的"源代码"进行转换&#xff0c;在 import 或"加载"模块时预处理文件 webpack做的事情&#xff0c;仅仅是分…

优化堆排序(Java 实例代码)

目录 优化堆排序 Java 实例代码 src/runoob/heap/HeapSort.java 文件代码&#xff1a; 优化堆排序 上一节的堆排序&#xff0c;我们开辟了额外的空间进行构造堆和对堆进行排序。这一小节&#xff0c;我们进行优化&#xff0c;使用原地堆排序。 对于一个最大堆&#xff0c;首…

selenium常见等待机制及其特点和使用方法

目录 1、强制等待 2、隐式等待 3、显示等待 1、强制等待 强制等待是在程序中直接调用Thread.sleep(timeout) ,来完成的&#xff0c;该用法的优点是使用起来方便&#xff0c;语法也比较简单&#xff0c;缺点就是需要强制等待固定的时间&#xff0c;可能会造成测试的时间过…