æ¬ææºä»£ç ä½ç½®ï¼https://gitee.com/zhangchao19890805/csdnBlog.git ä»åºä¸ç blog133 æ件夹就æ¯é¡¹ç®æ件夹ã
ä½¿ç¨ Spring Boot å Spring Cloud ååå¸å¼å¾®æå¡ç³»ç»ï¼é¾å ä¼ç¢°å°è·¨æ°æ®åºçäºå¡ãä¼æå¨ç¥çCAPååï¼å³ä¸è´æ§ï¼Cï¼ãå¯ç¨æ§ï¼Aï¼åååºå®¹éæ§ï¼Pï¼åªè½åå°å ¶ä¸ä¸¤ä¸ªæ¯è¾å¼ºï¼å©ä¸ä¸ä¸ªè¾å¼±ãSpring Cloud åå¸å¼å¾®æå¡ç³»ç»å¤©çå¯ç¨æ§ï¼Aï¼åååºå®¹éæ§ï¼Pï¼è¾å¼ºãå¦ä½ä¿è¯ä¸è´æ§å°±æ¯ä¸ªéè¦çé®é¢ãæåå¤å°±è¿ä¸ªé®é¢åå¤ç¯æç« ï¼ç»åå®ä¾ï¼å读è ä¸æ¥ä¸æ¥å±ç¤ºå¦ä½å®ç°åå¸å¼äºå¡ï¼ä¿è¯æ°æ®çä¸è´æ§ãæçæç« ä¼ä»æç®åçæ¹æ³å¼å§ï¼ä¸æ¥ä¸æ¥çä¸æå®åç³»ç»ï¼éæ¸å¢å¼ºç³»ç»çä¸è´æ§ãè¿ä¹æ°å¥½ç¬¦åæå¨å®è·µä¸ç»åã
é¦å ï¼æå 模æä¸ä¸ªåºæ¯ï¼æ们å¨æ·»å ç¨æ·çæ¶åï¼æ¢è¦æ·»å ç¨æ·çåºæ¬ä¿¡æ¯ï¼åè¦æ·»å ç¨æ·ç身份è¯ä¿¡æ¯ãè¿ä¸¤ä¸ªä¿¡æ¯å¨åå¨ä¸¤å°ç©çæºçæ°æ®åºä¸ãå¨æ·»å ç¨æ·çæ¶åï¼è¦ä¿è¯èº«ä»½è¯ä¹ä¸èµ·æ·»å ï¼è¿ææäºä¸ä¸ªäºå¡ãå¯ç¨ç¨æ·åºæ¬ä¿¡æ¯åå¨ t_user 表ä¸ï¼èº«ä»½è¯ä¿¡æ¯åå¨ t_card 表ä¸ãt_user å t_card ä¸ä¸å¯¹åºã
ä¸é¢æ¯æ°æ®ç»æï¼
å¨åt_userçç©çæº
CREATE DATABASE `db_test`
CREATE TABLE `t_user` (
`c_id` varchar(70) CHARACTER SET utf8 NOT NULL,
`c_user_name` varchar(45) CHARACTER SET utf8 NOT NULL,
`c_password` varchar(45) CHARACTER SET utf8 NOT NULL,
`c_create_time` datetime NOT NULL,
`c_balance` decimal(9,2) NOT NULL DEFAULT '0.00',
PRIMARY KEY (`c_id`),
UNIQUE KEY `c_user_name_UNIQUE` (`c_user_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `t_log` (
`c_id` varchar(80) NOT NULL,
`c_content` text,
`c_datetime` datetime NOT NULL,
PRIMARY KEY (`c_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
å¨å t_card çç©çæº
CREATE DATABASE `db_home_2` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */;
CREATE TABLE `t_card` (
`c_id` varchar(80) NOT NULL,
`c_user_id` varchar(80) NOT NULL,
`c_no` varchar(30) NOT NULL,
`c_create_time` datetime NOT NULL,
PRIMARY KEY (`c_id`),
UNIQUE KEY `c_user_id_UNIQUE` (`c_user_id`),
UNIQUE KEY `c_no_UNIQUE` (`c_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
æ¥ä¸æ¥æ¯å ³é®ä»£ç ã
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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>zhangchao</groupId>
<artifactId>blog133</artifactId>
<version>0.0.1</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.17.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<!-- çé¨ç½²æ¨¡å -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- è¿ä¸ªéè¦ä¸º true çé¨ç½²æææ -->
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
å¿ é¡»è¦å±è½æ Spring Boot 1 é»è®¤çæ°æ®æºé ç½®ï¼å¦åä½ åªè¦æ²¡å¨ application.properties æ application.yml éé ç½®æ°æ®æºï¼å¯å¨æ¶å°±ä¼æ¥éãéè¦å¨ main æ¹æ³ä¸å±è½ã
Blog133Application.java
package zhangchao;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class
})
public class Blog133Application {
public static void main(String[] args) {
SpringApplication.run(Blog133Application.class, args);
}
}
两个æ°æ®æºçä¿¡æ¯åå«åå° mybatis-config.xml å mybatis-config-2.xml 两个æ件ä¸ã
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/db_test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
<mapper resource="mapper/LogMapper.xml"/>
</mappers>
</configuration>
mybatis-config-2.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.1.230:3306/db_home_2"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/CardMapper.xml"/>
</mappers>
</configuration>
为两个æ°æ®æºé 置两个ä¸åç SqlSessionFactoryã
FirstDBFactory.java
package zhangchao.common.db;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
/**
* ä¿å第ä¸ä¸ªæ°æ®åºçSqlSessionFactory
* @author å¼ è¶
*/
public class FirstDBFactory {
private static SqlSessionFactory sqlSessionFactory = null;
static {
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
public static SqlSessionFactory getInstance(){
return sqlSessionFactory;
}
}
SecondDBFactory.java
package zhangchao.common.db;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
/**
* ä¿å第äºä¸ªæ°æ®åºçSqlSessionFactory
* @author å¼ è¶
*
*/
public class SecondDBFactory {
private static SqlSessionFactory sqlSessionFactory = null;
static {
String resource = "mybatis-config-2.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
public static SqlSessionFactory getInstance(){
return sqlSessionFactory;
}
}
ææäºå¡æ¾å° Service å±ä¸ï¼åºæ¬æè·¯æ¯å æå¼ä¸¤ä¸ªæ°æ®åºçSqlSessionï¼ç¶åæ§è¡ SQL è¯å¥ï¼çæ§è¡å®ååæ交两个æ°æ®åºçäºå¡ãå¦ææå¼å¸¸ï¼å å¤æäºå¡æ没ææ交ï¼æ²¡æ交就æ¯å¸¸è§çåæ»ï¼å·²ç»æ交äºçå°±æ§è¡è¡¥å¿æä½ã
ä¸æ¤åæ¶ï¼å¯¹å¼å¸¸çå¤çè¿åäºå¦ä¸å 强ï¼å¦ææ°å·§å¨åä¸ä¸ªæ°æ®åºåæ»æè è¡¥å¿æä½çæ¶ååºç°æ°æ®åºå®æºï¼é£ä¹åæ»æè è¡¥å¿æä½å°±ä¼æåºå¼å¸¸ï¼é æç¨åºæ²¡ææ§è¡ä¸ä¸ä¸ªæ°æ®åºçåæ»æè è¡¥å¿æä½ã为äºé¿å ä¸è¿°æ åµï¼è¿ç¹æ为åæ»åè¡¥å¿æä½å äº try ⦠catch ï¼å¹¶å¢å äºå并å¼å¸¸ç代ç ãä¸é¢æ¯æå ³é®çé¨åï¼
UserService.java
package zhangchao.service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import zhangchao.common.db.FirstDBFactory;
import zhangchao.common.db.SecondDBFactory;
import zhangchao.common.exception.ExceptionUtils;
import zhangchao.dao.CardDao;
import zhangchao.dao.UserDao;
import zhangchao.domain.*;
/**
* ç¨æ·çæå¡ç±»
* @author å¼ è¶
*
*/
@Service
public class UserService {
@Autowired
private UserDao userDao;
@Autowired
private CardDao cardDao;
public List<User> selectList(){
SqlSession sqlSession = FirstDBFactory.getInstance().openSession(true);
List<User> r = null;
try {
r = this.userDao.selectList(sqlSession);
} finally{
sqlSession.close();
}
return r;
}
/**
* å é¤ç¨æ·
* @param id
*/
public void delete(String id) {
SqlSession sqlSession = FirstDBFactory.getInstance().openSession(true);
try {
this.userDao.delete(sqlSession, id);
} finally{
sqlSession.close();
}
}
public void save(User user, Card card) {
// 第ä¸ä¸ªæ°æ®åºï¼æ¾User表
SqlSession sqlSession_1 = FirstDBFactory.getInstance().openSession();
// 第äºä¸ªæ°æ®åºï¼æ¾Card表
SqlSession sqlSession_2 = SecondDBFactory.getInstance().openSession();
boolean firstSessionCommit = false;
try {
this.userDao.save(sqlSession_1, user);
this.cardDao.save(sqlSession_2, card);
new BigDecimal("11").divide(user.getBalance(),2);
// æ交
sqlSession_1.commit();
firstSessionCommit = true;
new BigDecimal("11").divide(new BigDecimal(card.getNo()), 2);
sqlSession_2.commit();
} catch (Exception e) {
throw ExceptionUtils.catchException(e,
sqlSession_1, firstSessionCommit, ()->{
this.delete(user.getId());
System.out.println("è°ç¨UserService.deleteæ¹æ³");
},
sqlSession_2);
} finally {
sqlSession_1.close();
sqlSession_2.close();
}
}
}
ExceptionUtils.java
package zhangchao.common.exception;
import org.apache.ibatis.session.SqlSession;
/**
* ç»ä¸çå¼å¸¸å¤ç
* @author å¼ è¶
*
*/
public class ExceptionUtils {
/**
* å¼å¸¸è½¬æå符串
* @param t å¼å¸¸
* @return å¼å¸¸ç详ç»ä¿¡æ¯çå符串
*/
private static String throwable2Str (Throwable t) {
StackTraceElement[] steArr = t.getStackTrace();
String[] details = new String[steArr.length];
for (int i = 0; i < details.length; i++) {
details[i] = steArr[i].toString();
}
String message = t.getMessage();
StringBuilder content = new StringBuilder();
for (String str : details) {
content.append(str).append("\n");
}
content.append("\n").append(message).append("\n");
return content.toString();
}
/**
* æå¤ä¸ªå¼å¸¸å并æä¸ä¸ªå¼å¸¸ã
* @param arr
*/
public static RuntimeException join(Throwable[] arr){
StringBuilder sb = new StringBuilder();
if (null == arr || arr.length == 0) {
return null;
}
for (int i = 0; i < arr.length; i++) {
Throwable t = arr[i];
if (null != t) {
sb.append(throwable2Str(t)).append("\n");
}
}
return new RuntimeException(sb.toString());
}
/**
* ç»ä¸å¤çå¼å¸¸
* @param e
*/
public static RuntimeException catchException(Exception e,
SqlSession sqlSession_1, boolean sessionCommit_1, Compensate c1,
SqlSession sqlSession_2, boolean sessionCommit_2, Compensate c2){
Exception rbEx_1 = null;
Exception rbEx_2 = null;
try{
// å¦æUser表已ç»æ交ï¼åè¡¥å¿æä½
if (sessionCommit_1){
if (null != c1) {
c1.compensate();
}
} else {
// å¦æUser表è¿æ²¡æ交ï¼åæ»
sqlSession_1.rollback();
System.out.println("sqlSession.rollback()");
}
} catch (Exception ex1) {
// è¿éå å
¥ try ... catch çåå æ¯ï¼å¦æ user 表ç
// æ°æ®åºåæ¢ï¼ä¸é¢ä»£ç æåºå¼å¸¸ï¼å¦æä¸å¤çï¼
// åé¢ç代ç å°±æ æ³æ§è¡ï¼ä¹å°±æ æ³åé sqlSession_2 åå
è£
å¼å¸¸ã
rbEx_1 = ex1;
}
try {
if (sessionCommit_2) {
if (null != c2) {
c2.compensate();
}
} else {
sqlSession_2.rollback();
System.out.println("sqlSession_2.rollback()");
}
} catch(Exception ex2) {
rbEx_2 = ex2;
}
RuntimeException r = ExceptionUtils.join(new Exception[]{e, rbEx_1, rbEx_2});
return r;
}
public static RuntimeException catchException(Exception e,
SqlSession sqlSession_1, boolean sessionCommit_1, Compensate c1,
SqlSession sqlSession_2){
RuntimeException r = catchException(e, sqlSession_1, sessionCommit_1, c1,
sqlSession_2, false, null);
return r;
}
}
为äºæ¹ä¾¿è¡¥å¿æä½èå çæ¥å£ Compensate
package zhangchao.common.exception;
/**
* å¼å¸¸å¤çä¸çè¡¥å¿æä½æ¥å£
* @author å¼ è¶
*
*/
public interface Compensate {
void compensate();
}
ExceptionHandleAdvice.java
package zhangchao.common.exception;
import java.sql.Timestamp;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import zhangchao.common.core.R;
import zhangchao.domain.Log;
import zhangchao.service.LogService;
/**
* Spring Boot 1 ç»ä¸å°è£
å¼å¸¸
* @author å¼ è¶
*
*/
@RestControllerAdvice
public class ExceptionHandleAdvice {
@Autowired
private LogService logService;
@ExceptionHandler(value=Throwable.class)
public R exception(Throwable t){
StackTraceElement[] steArr = t.getStackTrace();
String[] details = new String[steArr.length];
for (int i = 0; i < details.length; i++) {
details[i] = steArr[i].toString();
}
String message = t.getMessage();
StringBuilder content = new StringBuilder();
for (String str : details) {
content.append(str).append("\n");
}
content.append("\n").append(message).append("\n");
Log log = new Log();
log.setId(UUID.randomUUID().toString());
log.setContent(content.toString());
log.setDatetime(new Timestamp(System.currentTimeMillis()));
// è¿éå ä¸try catchï¼å°±ç®æ°æ®åºåæ¢äºï¼ä¹è½å¤çå¼å¸¸ã
try {
logService.save(log);
} catch (Exception e) {
// æ¤å¤ä¹å¯ä»¥æ¹æåå
¥æ¥å¿æ件ä¸
e.printStackTrace();
}
return R.error().put("msg", message);
}
}
好äºï¼æå ³é®çé¨åå°±æ¯è¿äºãæ³æ¥çæ´å¤ç»è建议å éä¸ä»£ç åä»ç»æ¥çãè¿è¡Blog133Application åï¼æµè§å¨ä¸è¾å ¥
http://localhost/test.html
å°±å¯ä»¥æ§è¡æ·»å ç¨æ·çæä½ãæµè§å¨ä¸è¾å ¥
http://localhost/api/user
å°±è½ççå·²ç»æ·»å çç¨æ·ã
åææ们ç代ç ï¼è½ç¶æ们为äºä¿è¯äºå¡çä¸è´æ§å å ¥äºåæ»åè¡¥å¿æä½ï¼ä½æ¯ç³»ç»çä¸è´æ§ä»ç¶æççµãåå¦ç³»ç»æ§è¡å® t_user 表çæ°æ®åºæ交æä½åï¼Tomcat çªç¶å®æºï¼ä¼é æ t_card æ°æ®åºæ²¡æ交ï¼å¯¼è´ä¸¤å°æºå¨çæ°æ®ä¸ä¸è´ãä¹å°±æ¯ t_user 表已ç»æè®°å½äºï¼è t_card 表å´æ²¡æ对åºçè®°å½ãè¿ä¸ªé®é¢è¯¥æä¹è§£å³å¢ï¼æä¼å¨ä¸ä¸ç¯æç« ä¸è®²å°ã
ã134ãSpring Boot 1 + MyBatis å¤æ°æ®æºåå¸å¼äºå¡ï¼äºï¼