userList = userSerivce.getByName("Oscar");
Assert.assertEquals(21, userList.get(0).getAge().intValue());
// 查数据库,应该有5个用户
Assert.assertEquals(5, userSerivce.getAllUsers());
// 删除两个用户
userSerivce.deleteByName("Tom");
userSerivce.deleteByName("Mike");
// 查数据库,应该有5个用户
Assert.assertEquals(3, userSerivce.getAllUsers());
}
}
================================================
FILE: 2.x/chapter3-10/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter3-10/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.3.RELEASE
com.didispace
chapter3-10
0.0.1-SNAPSHOT
事务管理入门
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-actuator
mysql
mysql-connector-java
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter3-10/src/main/java/com/didispace/chapter310/Chapter310Application.java
================================================
package com.didispace.chapter310;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class Chapter310Application {
public static void main(String[] args) {
SpringApplication.run(Chapter310Application.class, args);
}
@RestController
static class TextController {
@GetMapping("/hello")
public String hello() {
return "hello world";
}
}
}
================================================
FILE: 2.x/chapter3-10/src/main/java/com/didispace/chapter310/User.java
================================================
package com.didispace.chapter310;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import javax.validation.constraints.Max;
@Entity
@Data
@NoArgsConstructor
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
@Max(50)
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
}
================================================
FILE: 2.x/chapter3-10/src/main/java/com/didispace/chapter310/UserRepository.java
================================================
package com.didispace.chapter310;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
/**
* Created by 程序猿DD/翟永超 on 2020/7/9.
*
* Blog: http://blog.didispace.com/
* Github: https://github.com/dyc87112/
*/
public interface UserRepository extends JpaRepository {
User findByName(String name);
User findByNameAndAge(String name, Integer age);
@Query("from User u where u.name=:name")
User findUser(@Param("name") String name);
}
================================================
FILE: 2.x/chapter3-10/src/main/resources/application.properties
================================================
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=12345678
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto=create
================================================
FILE: 2.x/chapter3-10/src/test/java/com/didispace/chapter310/Chapter310ApplicationTests.java
================================================
package com.didispace.chapter310;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
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.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter310ApplicationTests {
@Autowired
private UserRepository userRepository;
@Test
@Transactional
public void test() throws Exception {
// 创建10条记录
userRepository.save(new User("AAA", 10));
userRepository.save(new User("BBB", 20));
userRepository.save(new User("CCC", 30));
userRepository.save(new User("DDD", 40));
userRepository.save(new User("EEE", 50));
userRepository.save(new User("FFF", 60));
userRepository.save(new User("GGG", 70));
userRepository.save(new User("HHH", 80));
userRepository.save(new User("III", 90));
userRepository.save(new User("JJJ", 100));
// 测试findAll, 查询所有记录
Assert.assertEquals(10, userRepository.findAll().size());
// 测试findByName, 查询姓名为FFF的User
Assert.assertEquals(60, userRepository.findByName("FFF").getAge().longValue());
// 测试findUser, 查询姓名为FFF的User
Assert.assertEquals(60, userRepository.findUser("FFF").getAge().longValue());
// 测试findByNameAndAge, 查询姓名为FFF并且年龄为60的User
Assert.assertEquals("FFF", userRepository.findByNameAndAge("FFF", 60).getName());
// 测试删除姓名为AAA的User
userRepository.delete(userRepository.findByName("AAA"));
// 测试findAll, 查询所有记录, 验证上面的删除是否成功
Assert.assertEquals(9, userRepository.findAll().size());
}
}
================================================
FILE: 2.x/chapter3-11/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter3-11/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.4.1
com.didispace
chapter3-11
0.0.1-SNAPSHOT
使用Flyway管理数据库版本
1.8
org.springframework.boot
spring-boot-starter-jdbc
mysql
mysql-connector-java
org.flywaydb
flyway-core
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter3-11/src/main/java/com/didispace/chapter311/Chapter311Application.java
================================================
package com.didispace.chapter311;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Chapter311Application {
public static void main(String[] args) {
SpringApplication.run(Chapter311Application.class, args);
}
}
================================================
FILE: 2.x/chapter3-11/src/main/java/com/didispace/chapter311/User.java
================================================
package com.didispace.chapter311;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
}
================================================
FILE: 2.x/chapter3-11/src/main/java/com/didispace/chapter311/UserService.java
================================================
package com.didispace.chapter311;
import java.util.List;
public interface UserService {
/**
* 新增一个用户
*
* @param name
* @param age
*/
int create(String name, Integer age);
/**
* 根据name查询用户
*
* @param name
* @return
*/
List getByName(String name);
/**
* 根据name删除用户
*
* @param name
*/
int deleteByName(String name);
/**
* 获取用户总量
*/
int getAllUsers();
/**
* 删除所有用户
*/
int deleteAllUsers();
}
================================================
FILE: 2.x/chapter3-11/src/main/java/com/didispace/chapter311/UserServiceImpl.java
================================================
package com.didispace.chapter311;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
private JdbcTemplate jdbcTemplate;
UserServiceImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public int create(String name, Integer age) {
return jdbcTemplate.update("insert into USER(NAME, AGE) values(?, ?)", name, age);
}
@Override
public List getByName(String name) {
List users = jdbcTemplate.query("select * from USER where NAME = ?", (resultSet, i) -> {
User user = new User();
user.setId(resultSet.getLong("ID"));
user.setName(resultSet.getString("NAME"));
user.setAge(resultSet.getInt("AGE"));
return user;
}, name);
return users;
}
@Override
public int deleteByName(String name) {
return jdbcTemplate.update("delete from USER where NAME = ?", name);
}
@Override
public int getAllUsers() {
return jdbcTemplate.queryForObject("select count(1) from USER", Integer.class);
}
@Override
public int deleteAllUsers() {
return jdbcTemplate.update("delete from USER");
}
}
================================================
FILE: 2.x/chapter3-11/src/main/resources/application.properties
================================================
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=12345678
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.flyway.locations=classpath:db/migration
================================================
FILE: 2.x/chapter3-11/src/main/resources/db/migration/V1_1__alter_table_user.sql
================================================
ALTER TABLE `user` ADD COLUMN `address` VARCHAR(20) DEFAULT NULL;
================================================
FILE: 2.x/chapter3-11/src/main/resources/db/migration/V1__Base_version.sql
================================================
DROP TABLE IF EXISTS user ;
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(20) NOT NULL COMMENT '姓名',
`age` int(5) DEFAULT NULL COMMENT '年龄',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
================================================
FILE: 2.x/chapter3-11/src/test/java/com/didispace/chapter311/Chapter311ApplicationTests.java
================================================
package com.didispace.chapter311;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@Slf4j
@SpringBootTest
public class Chapter311ApplicationTests {
@Autowired
private UserService userSerivce;
@Test
public void test() throws Exception {
userSerivce.deleteAllUsers();
// 插入5个用户
userSerivce.create("Tom", 10);
userSerivce.create("Mike", 11);
userSerivce.create("Didispace", 30);
userSerivce.create("Oscar", 21);
userSerivce.create("Linda", 17);
// 查询名为Oscar的用户,判断年龄是否匹配
List userList = userSerivce.getByName("Oscar");
Assertions.assertEquals(21, userList.get(0).getAge().intValue());
// 查数据库,应该有5个用户
Assertions.assertEquals(5, userSerivce.getAllUsers());
// 删除两个用户
userSerivce.deleteByName("Tom");
userSerivce.deleteByName("Mike");
// 查数据库,应该有5个用户
Assertions.assertEquals(3, userSerivce.getAllUsers());
}
}
================================================
FILE: 2.x/chapter3-12/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter3-12/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.4.2
com.didispace
chapter3-12
0.0.1-SNAPSHOT
使用JTA实现多数据源的事务
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-jdbc
org.springframework.boot
spring-boot-starter-jta-atomikos
mysql
mysql-connector-java
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter3-12/src/main/java/com/didispace/chapter312/Chapter312Application.java
================================================
package com.didispace.chapter312;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Chapter312Application {
public static void main(String[] args) {
SpringApplication.run(Chapter312Application.class, args);
}
}
================================================
FILE: 2.x/chapter3-12/src/main/java/com/didispace/chapter312/DataSourceConfiguration.java
================================================
package com.didispace.chapter312;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
@Configuration
public class DataSourceConfiguration {
@Primary
@Bean
@ConfigurationProperties(prefix = "spring.jta.atomikos.datasource.primary")
public DataSource primaryDataSource() {
return new AtomikosDataSourceBean();
}
@Bean
@ConfigurationProperties(prefix = "spring.jta.atomikos.datasource.secondary")
public DataSource secondaryDataSource() {
return new AtomikosDataSourceBean();
}
@Bean
public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource") DataSource primaryDataSource) {
return new JdbcTemplate(primaryDataSource);
}
@Bean
public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondaryDataSource") DataSource secondaryDataSource) {
return new JdbcTemplate(secondaryDataSource);
}
}
================================================
FILE: 2.x/chapter3-12/src/main/java/com/didispace/chapter312/TestService.java
================================================
package com.didispace.chapter312;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class TestService {
private JdbcTemplate primaryJdbcTemplate;
private JdbcTemplate secondaryJdbcTemplate;
public TestService(JdbcTemplate primaryJdbcTemplate, JdbcTemplate secondaryJdbcTemplate) {
this.primaryJdbcTemplate = primaryJdbcTemplate;
this.secondaryJdbcTemplate = secondaryJdbcTemplate;
}
@Transactional
public void tx() {
// 修改test1库中的数据
primaryJdbcTemplate.update("update user set age = ? where name = ?", 30, "aaa");
// 修改test2库中的数据
secondaryJdbcTemplate.update("update user set age = ? where name = ?", 30, "aaa");
}
@Transactional
public void tx2() {
// 修改test1库中的数据
primaryJdbcTemplate.update("update user set age = ? where name = ?", 40, "aaa");
// 模拟:修改test2库之前抛出异常
throw new RuntimeException();
}
}
================================================
FILE: 2.x/chapter3-12/src/main/resources/application.properties
================================================
spring.jta.enabled=true
spring.jta.atomikos.datasource.primary.xa-properties.url=jdbc:mysql://localhost:3306/test1
spring.jta.atomikos.datasource.primary.xa-properties.user=root
spring.jta.atomikos.datasource.primary.xa-properties.password=12345678
spring.jta.atomikos.datasource.primary.xa-data-source-class-name=com.mysql.cj.jdbc.MysqlXADataSource
spring.jta.atomikos.datasource.primary.unique-resource-name=test1
spring.jta.atomikos.datasource.primary.max-pool-size=25
spring.jta.atomikos.datasource.primary.min-pool-size=3
spring.jta.atomikos.datasource.primary.max-lifetime=20000
spring.jta.atomikos.datasource.primary.borrow-connection-timeout=10000
spring.jta.atomikos.datasource.secondary.xa-properties.url=jdbc:mysql://localhost:3306/test2
spring.jta.atomikos.datasource.secondary.xa-properties.user=root
spring.jta.atomikos.datasource.secondary.xa-properties.password=12345678
spring.jta.atomikos.datasource.secondary.xa-data-source-class-name=com.mysql.cj.jdbc.MysqlXADataSource
spring.jta.atomikos.datasource.secondary.unique-resource-name=test2
spring.jta.atomikos.datasource.secondary.max-pool-size=25
spring.jta.atomikos.datasource.secondary.min-pool-size=3
spring.jta.atomikos.datasource.secondary.max-lifetime=20000
spring.jta.atomikos.datasource.secondary.borrow-connection-timeout=10000
#spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1
#spring.datasource.primary.username=root
#spring.datasource.primary.password=12345678
#spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver
#
#spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/test2
#spring.datasource.secondary.username=root
#spring.datasource.secondary.password=12345678
#spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver
================================================
FILE: 2.x/chapter3-12/src/test/java/com/didispace/chapter312/Chapter312ApplicationTests.java
================================================
package com.didispace.chapter312;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;
@SpringBootTest(classes = Chapter312Application.class)
public class Chapter312ApplicationTests {
@Autowired
protected JdbcTemplate primaryJdbcTemplate;
@Autowired
protected JdbcTemplate secondaryJdbcTemplate;
@Autowired
private TestService testService;
@Test
public void test1() throws Exception {
// 正确更新的情况
testService.tx();
Assertions.assertEquals(30, primaryJdbcTemplate.queryForObject("select age from user where name=?", Integer.class, "aaa"));
Assertions.assertEquals(30, secondaryJdbcTemplate.queryForObject("select age from user where name=?", Integer.class, "aaa"));
}
@Test
public void test2() throws Exception {
// 更新失败的情况
try {
testService.tx2();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 部分更新失败,test1中的更新应该回滚
Assertions.assertEquals(30, primaryJdbcTemplate.queryForObject("select age from user where name=?", Integer.class, "aaa"));
Assertions.assertEquals(30, secondaryJdbcTemplate.queryForObject("select age from user where name=?", Integer.class, "aaa"));
}
}
}
================================================
FILE: 2.x/chapter3-13/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter3-13/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.5.0
com.didispace
chapter3-13
0.0.1-SNAPSHOT
2.5版本之后的数据脚本初始化
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-jdbc
mysql
mysql-connector-java
org.projectlombok
lombok
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter3-13/src/main/java/com/didispace/chapter313/Chapter313Application.java
================================================
package com.didispace.chapter313;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Chapter313Application {
public static void main(String[] args) {
SpringApplication.run(Chapter313Application.class, args);
}
}
================================================
FILE: 2.x/chapter3-13/src/main/resources/application.properties
================================================
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# Spring Boot 2.5.0 init schema & data
spring.sql.init.username=root
spring.sql.init.password=
spring.sql.init.schema-locations=classpath*:schema-all.sql
#spring.sql.init.enabled=true
#spring.sql.init.data-locations=classpath*:
#spring.sql.init.encoding=UTF-8
#spring.sql.init.separator=;
#spring.sql.init.continue-on-error=true
================================================
FILE: 2.x/chapter3-13/src/main/resources/schema-all.sql
================================================
create table test.user_info
(
id int unsigned auto_increment comment '用户id'
primary key,
open_id varchar(255) default '' null comment '微信小程序openid',
nick_name varchar(255) default '' null comment '微信名',
head_img varchar(255) default '' null comment '微信头像',
sex varchar(255) default '' null comment '性别',
phone varchar(255) default '' null comment '手机',
province varchar(255) default '' null comment '注册地址:省',
city varchar(255) default '' null comment '注册地址:城市',
country varchar(255) default '' null comment '注册地址:县/区',
status tinyint unsigned default 0 not null comment '是否标记删除 0:否 1:是',
create_time datetime not null comment '创建时间',
update_time datetime not null comment '更新时间'
)
comment '用户表';
================================================
FILE: 2.x/chapter3-13/src/test/java/com/didispace/chapter31/Chapter31ApplicationTests.java
================================================
package com.didispace.chapter31;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class Chapter31ApplicationTests {
@Test
public void test() throws Exception {
}
}
================================================
FILE: 2.x/chapter3-2/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter3-2/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.3.RELEASE
com.didispace
chapter3-2
0.0.1-SNAPSHOT
默认数据源Hikari的配置详解
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-jdbc
mysql
mysql-connector-java
org.projectlombok
lombok
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter3-2/src/main/java/com/didispace/chapter32/Chapter32Application.java
================================================
package com.didispace.chapter32;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Chapter32Application {
public static void main(String[] args) {
SpringApplication.run(Chapter32Application.class, args);
}
}
================================================
FILE: 2.x/chapter3-2/src/main/java/com/didispace/chapter32/User.java
================================================
package com.didispace.chapter32;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class User {
private String name;
private Integer age;
}
================================================
FILE: 2.x/chapter3-2/src/main/java/com/didispace/chapter32/UserService.java
================================================
package com.didispace.chapter32;
import java.util.List;
public interface UserService {
/**
* 新增一个用户
*
* @param name
* @param age
*/
int create(String name, Integer age);
/**
* 根据name查询用户
*
* @param name
* @return
*/
List getByName(String name);
/**
* 根据name删除用户
*
* @param name
*/
int deleteByName(String name);
/**
* 获取用户总量
*/
int getAllUsers();
/**
* 删除所有用户
*/
int deleteAllUsers();
}
================================================
FILE: 2.x/chapter3-2/src/main/java/com/didispace/chapter32/UserServiceImpl.java
================================================
package com.didispace.chapter32;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
private JdbcTemplate jdbcTemplate;
UserServiceImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public int create(String name, Integer age) {
return jdbcTemplate.update("insert into USER(NAME, AGE) values(?, ?)", name, age);
}
@Override
public List getByName(String name) {
List users = jdbcTemplate.query("select NAME, AGE from USER where NAME = ?", (resultSet, i) -> {
User user = new User();
user.setName(resultSet.getString("NAME"));
user.setAge(resultSet.getInt("AGE"));
return user;
}, name);
return users;
}
@Override
public int deleteByName(String name) {
return jdbcTemplate.update("delete from USER where NAME = ?", name);
}
@Override
public int getAllUsers() {
return jdbcTemplate.queryForObject("select count(1) from USER", Integer.class);
}
@Override
public int deleteAllUsers() {
return jdbcTemplate.update("delete from USER");
}
}
================================================
FILE: 2.x/chapter3-2/src/main/resources/application.properties
================================================
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 最小空闲连接,默认值10,小于0或大于maximum-pool-size,都会重置为maximum-pool-size
spring.datasource.hikari.minimum-idle=10
# 最大连接数,小于等于0会被重置为默认值10;大于零小于1会被重置为minimum-idle的值
spring.datasource.hikari.maximum-pool-size=20
# 空闲连接超时时间,默认值600000(10分钟),大于等于max-lifetime且max-lifetime>0,会被重置为0;不等于0且小于10秒,会被重置为10秒。
spring.datasource.hikari.idle-timeout=500000
# 连接最大存活时间.不等于0且小于30秒,会被重置为默认值30分钟.设置应该比mysql设置的超时时间短
spring.datasource.hikari.max-lifetime=540000
# 连接超时时间:毫秒,小于250毫秒,否则被重置为默认值30秒
spring.datasource.hikari.connection-timeout=60000
# 用于测试连接是否可用的查询语句
spring.datasource.hikari.connection-test-query=SELECT 1
================================================
FILE: 2.x/chapter3-2/src/test/java/com/didispace/chapter32/Chapter32ApplicationTests.java
================================================
package com.didispace.chapter32;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
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.http.MediaType;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import javax.sql.DataSource;
import java.util.List;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter32ApplicationTests {
@Autowired
private UserService userSerivce;
@Autowired
private DataSource dataSource;
@Before
public void setUp() {
// 准备,清空user表
userSerivce.deleteAllUsers();
}
@Test
public void test() throws Exception {
// 插入5个用户
userSerivce.create("Tom", 10);
userSerivce.create("Mike", 11);
userSerivce.create("Didispace", 30);
userSerivce.create("Oscar", 21);
userSerivce.create("Linda", 17);
// 查询名为Oscar的用户,判断年龄是否匹配
List userList = userSerivce.getByName("Oscar");
Assert.assertEquals(21, userList.get(0).getAge().intValue());
// 查数据库,应该有5个用户
Assert.assertEquals(5, userSerivce.getAllUsers());
// 删除两个用户
userSerivce.deleteByName("Tom");
userSerivce.deleteByName("Mike");
// 查数据库,应该有5个用户
Assert.assertEquals(3, userSerivce.getAllUsers());
}
}
================================================
FILE: 2.x/chapter3-3/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter3-3/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.3.RELEASE
com.didispace
chapter3-3
0.0.1-SNAPSHOT
使用国产数据库连接池Druid
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-jdbc
com.alibaba
druid-spring-boot-starter
1.1.21
org.springframework.boot
spring-boot-starter-actuator
mysql
mysql-connector-java
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter3-3/src/main/java/com/didispace/chapter33/Chapter33Application.java
================================================
package com.didispace.chapter33;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class Chapter33Application {
public static void main(String[] args) {
SpringApplication.run(Chapter33Application.class, args);
}
@RestController
static class TextController {
@GetMapping("/hello")
public String hello() {
return "hello world";
}
}
}
================================================
FILE: 2.x/chapter3-3/src/main/java/com/didispace/chapter33/User.java
================================================
package com.didispace.chapter33;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class User {
private String name;
private Integer age;
}
================================================
FILE: 2.x/chapter3-3/src/main/java/com/didispace/chapter33/UserController.java
================================================
package com.didispace.chapter33;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* Created by 程序猿DD/翟永超 on 2020/2/8.
*
* Blog: http://blog.didispace.com/
* Github: https://github.com/dyc87112/
*/
@Data
@AllArgsConstructor
@RestController
public class UserController {
private UserService userService;
@PostMapping("/user")
public int create(@RequestBody User user) {
return userService.create(user.getName(), user.getAge());
}
@GetMapping("/user/{name}")
public List getByName(@PathVariable String name) {
return userService.getByName(name);
}
@DeleteMapping("/user/{name}")
public int deleteByName(@PathVariable String name) {
return userService.deleteByName(name);
}
@GetMapping("/user/count")
public int getAllUsers() {
return userService.getAllUsers();
}
@DeleteMapping("/user/all")
public int deleteAllUsers() {
return userService.deleteAllUsers();
}
}
================================================
FILE: 2.x/chapter3-3/src/main/java/com/didispace/chapter33/UserService.java
================================================
package com.didispace.chapter33;
import java.util.List;
public interface UserService {
/**
* 新增一个用户
*
* @param name
* @param age
*/
int create(String name, Integer age);
/**
* 根据name查询用户
*
* @param name
* @return
*/
List getByName(String name);
/**
* 根据name删除用户
*
* @param name
*/
int deleteByName(String name);
/**
* 获取用户总量
*/
int getAllUsers();
/**
* 删除所有用户
*/
int deleteAllUsers();
}
================================================
FILE: 2.x/chapter3-3/src/main/java/com/didispace/chapter33/UserServiceImpl.java
================================================
package com.didispace.chapter33;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
private JdbcTemplate jdbcTemplate;
UserServiceImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public int create(String name, Integer age) {
return jdbcTemplate.update("insert into USER(NAME, AGE) values(?, ?)", name, age);
}
@Override
public List getByName(String name) {
List users = jdbcTemplate.query("select NAME, AGE from USER where NAME = ?", (resultSet, i) -> {
User user = new User();
user.setName(resultSet.getString("NAME"));
user.setAge(resultSet.getInt("AGE"));
return user;
}, name);
return users;
}
@Override
public int deleteByName(String name) {
return jdbcTemplate.update("delete from USER where NAME = ?", name);
}
@Override
public int getAllUsers() {
return jdbcTemplate.queryForObject("select count(1) from USER", Integer.class);
}
@Override
public int deleteAllUsers() {
return jdbcTemplate.update("delete from USER");
}
}
================================================
FILE: 2.x/chapter3-3/src/main/resources/application.properties
================================================
# 基础配置
spring.datasource.druid.url=jdbc:mysql://localhost:3306/test
spring.datasource.druid.username=root
spring.datasource.druid.password=
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
# 连接池配置
spring.datasource.druid.initialSize=10
spring.datasource.druid.maxActive=20
spring.datasource.druid.maxWait=60000
spring.datasource.druid.minIdle=1
spring.datasource.druid.timeBetweenEvictionRunsMillis=60000
spring.datasource.druid.minEvictableIdleTimeMillis=300000
spring.datasource.druid.testWhileIdle=true
spring.datasource.druid.testOnBorrow=true
spring.datasource.druid.testOnReturn=false
spring.datasource.druid.poolPreparedStatements=true
spring.datasource.druid.maxOpenPreparedStatements=20
spring.datasource.druid.validationQuery=SELECT 1
spring.datasource.druid.validation-query-timeout=500
spring.datasource.druid.filters=stat,wall
# 监控配置
spring.datasource.druid.stat-view-servlet.enabled=true
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
spring.datasource.druid.stat-view-servlet.reset-enable=true
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=admin
================================================
FILE: 2.x/chapter3-3/src/test/java/com/didispace/chapter33/Chapter33ApplicationTests.java
================================================
package com.didispace.chapter33;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
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.http.MediaType;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import javax.sql.DataSource;
import java.util.List;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter33ApplicationTests {
@Autowired
private UserService userSerivce;
@Autowired
private DataSource dataSource;
@Before
public void setUp() {
// 准备,清空user表
userSerivce.deleteAllUsers();
}
@Test
public void test() throws Exception {
// 插入5个用户
userSerivce.create("Tom", 10);
userSerivce.create("Mike", 11);
userSerivce.create("Didispace", 30);
userSerivce.create("Oscar", 21);
userSerivce.create("Linda", 17);
// 查询名为Oscar的用户,判断年龄是否匹配
List userList = userSerivce.getByName("Oscar");
Assert.assertEquals(21, userList.get(0).getAge().intValue());
// 查数据库,应该有5个用户
Assert.assertEquals(5, userSerivce.getAllUsers());
// 删除两个用户
userSerivce.deleteByName("Tom");
userSerivce.deleteByName("Mike");
// 查数据库,应该有5个用户
Assert.assertEquals(3, userSerivce.getAllUsers());
}
}
================================================
FILE: 2.x/chapter3-4/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter3-4/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.3.RELEASE
com.didispace
chapter3-4
0.0.1-SNAPSHOT
使用Spring Data JPA访问MySQL
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-actuator
mysql
mysql-connector-java
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter3-4/src/main/java/com/didispace/chapter34/Chapter34Application.java
================================================
package com.didispace.chapter34;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class Chapter34Application {
public static void main(String[] args) {
SpringApplication.run(Chapter34Application.class, args);
}
@RestController
static class TextController {
@GetMapping("/hello")
public String hello() {
return "hello world";
}
}
}
================================================
FILE: 2.x/chapter3-4/src/main/java/com/didispace/chapter34/User.java
================================================
package com.didispace.chapter34;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
@Data
@NoArgsConstructor
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
}
================================================
FILE: 2.x/chapter3-4/src/main/java/com/didispace/chapter34/UserRepository.java
================================================
package com.didispace.chapter34;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
/**
* Created by 程序猿DD/翟永超 on 2020/2/15.
*
* Blog: http://blog.didispace.com/
* Github: https://github.com/dyc87112/
*/
public interface UserRepository extends JpaRepository {
User findByName(String name);
User findByNameAndAge(String name, Integer age);
@Query("from User u where u.name=:name")
User findUser(@Param("name") String name);
}
================================================
FILE: 2.x/chapter3-4/src/main/resources/application.properties
================================================
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop
================================================
FILE: 2.x/chapter3-4/src/test/java/com/didispace/chapter34/Chapter34ApplicationTests.java
================================================
package com.didispace.chapter34;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
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.context.junit4.SpringRunner;
import javax.sql.DataSource;
import java.util.List;
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter34ApplicationTests {
@Autowired
private UserRepository userRepository;
@Test
public void test() throws Exception {
// 创建10条记录
userRepository.save(new User("AAA", 10));
userRepository.save(new User("BBB", 20));
userRepository.save(new User("CCC", 30));
userRepository.save(new User("DDD", 40));
userRepository.save(new User("EEE", 50));
userRepository.save(new User("FFF", 60));
userRepository.save(new User("GGG", 70));
userRepository.save(new User("HHH", 80));
userRepository.save(new User("III", 90));
userRepository.save(new User("JJJ", 100));
// 测试findAll, 查询所有记录
Assert.assertEquals(10, userRepository.findAll().size());
// 测试findByName, 查询姓名为FFF的User
Assert.assertEquals(60, userRepository.findByName("FFF").getAge().longValue());
// 测试findUser, 查询姓名为FFF的User
Assert.assertEquals(60, userRepository.findUser("FFF").getAge().longValue());
// 测试findByNameAndAge, 查询姓名为FFF并且年龄为60的User
Assert.assertEquals("FFF", userRepository.findByNameAndAge("FFF", 60).getName());
// 测试删除姓名为AAA的User
userRepository.delete(userRepository.findByName("AAA"));
// 测试findAll, 查询所有记录, 验证上面的删除是否成功
Assert.assertEquals(9, userRepository.findAll().size());
}
}
================================================
FILE: 2.x/chapter3-5/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter3-5/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.3.RELEASE
com.didispace
chapter3-5
0.0.1-SNAPSHOT
使用MyBatis访问MySQL
1.8
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.1
mysql
mysql-connector-java
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter3-5/src/main/java/com/didispace/chapter35/Chapter35Application.java
================================================
package com.didispace.chapter35;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Chapter35Application {
public static void main(String[] args) {
SpringApplication.run(Chapter35Application.class, args);
}
}
================================================
FILE: 2.x/chapter3-5/src/main/java/com/didispace/chapter35/User.java
================================================
package com.didispace.chapter35;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
}
================================================
FILE: 2.x/chapter3-5/src/main/java/com/didispace/chapter35/UserMapper.java
================================================
package com.didispace.chapter35;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
/**
* Created by 程序猿DD/翟永超 on 2020/2/15.
*
* Blog: http://blog.didispace.com/
* Github: https://github.com/dyc87112/
*/
@Mapper
public interface UserMapper {
@Select("SELECT * FROM USER WHERE NAME = #{name}")
User findByName(@Param("name") String name);
@Insert("INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age})")
int insert(@Param("name") String name, @Param("age") Integer age);
}
================================================
FILE: 2.x/chapter3-5/src/main/resources/application.properties
================================================
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=12345678
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
================================================
FILE: 2.x/chapter3-5/src/test/java/com/didispace/chapter35/Chapter35ApplicationTests.java
================================================
package com.didispace.chapter35;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
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.transaction.annotation.Transactional;
import javax.sql.DataSource;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class Chapter35ApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
@Rollback
public void test() throws Exception {
userMapper.insert("AAA", 20);
User u = userMapper.findByName("AAA");
Assert.assertEquals(20, u.getAge().intValue());
}
}
================================================
FILE: 2.x/chapter3-6/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter3-6/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.3.RELEASE
com.didispace
chapter3-6
0.0.1-SNAPSHOT
使用MyBatis(xml配置方式)
1.8
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.1
mysql
mysql-connector-java
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter3-6/src/main/java/com/didispace/chapter36/Chapter36Application.java
================================================
package com.didispace.chapter36;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan("com.didispace.chapter36.mapper")
@SpringBootApplication
public class Chapter36Application {
public static void main(String[] args) {
SpringApplication.run(Chapter36Application.class, args);
}
}
================================================
FILE: 2.x/chapter3-6/src/main/java/com/didispace/chapter36/entity/User.java
================================================
package com.didispace.chapter36.entity;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
}
================================================
FILE: 2.x/chapter3-6/src/main/java/com/didispace/chapter36/mapper/UserMapper.java
================================================
package com.didispace.chapter36.mapper;
import com.didispace.chapter36.entity.User;
import org.apache.ibatis.annotations.Param;
/**
* Created by 程序猿DD/翟永超 on 2020/2/28.
*
* Blog: http://blog.didispace.com/
* Github: https://github.com/dyc87112/
*/
public interface UserMapper {
User findByName(@Param("name") String name);
int insert(@Param("name") String name, @Param("age") Integer age);
}
================================================
FILE: 2.x/chapter3-6/src/main/resources/application.properties
================================================
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=12345678
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
mybatis.mapper-locations=classpath:mapper/*.xml
================================================
FILE: 2.x/chapter3-6/src/main/resources/mapper/UserMapper.xml
================================================
INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age})
================================================
FILE: 2.x/chapter3-6/src/test/java/com/didispace/chapter36/Chapter36ApplicationTests.java
================================================
package com.didispace.chapter36;
import com.didispace.chapter36.entity.User;
import com.didispace.chapter36.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
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.transaction.annotation.Transactional;
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class Chapter36ApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
@Rollback
public void test() throws Exception {
userMapper.insert("AAA", 20);
User u = userMapper.findByName("AAA");
Assert.assertEquals(20, u.getAge().intValue());
}
}
================================================
FILE: 2.x/chapter3-7/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter3-7/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.3.RELEASE
com.didispace
chapter3-7
0.0.1-SNAPSHOT
JdbcTemplate的多数据源配置
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-jdbc
mysql
mysql-connector-java
org.projectlombok
lombok
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter3-7/src/main/java/com/didispace/chapter37/Chapter37Application.java
================================================
package com.didispace.chapter37;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Chapter37Application {
public static void main(String[] args) {
SpringApplication.run(Chapter37Application.class, args);
}
}
================================================
FILE: 2.x/chapter3-7/src/main/java/com/didispace/chapter37/DataSourceConfiguration.java
================================================
package com.didispace.chapter37;
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.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
@Configuration
public class DataSourceConfiguration {
@Primary
@Bean
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource") DataSource primaryDataSource) {
return new JdbcTemplate(primaryDataSource);
}
@Bean
public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondaryDataSource") DataSource secondaryDataSource) {
return new JdbcTemplate(secondaryDataSource);
}
}
================================================
FILE: 2.x/chapter3-7/src/main/resources/application.properties
================================================
# pring boot 1.x的配置:spring.datasource.primary.url=jdbc:mysql://localhost:3306/test1
spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1
spring.datasource.primary.username=root
spring.datasource.primary.password=123456
spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver
# spring boot 1.x的配置:spring.datasource.secondary.url=jdbc:mysql://localhost:3306/test2
spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/test2
spring.datasource.secondary.username=root
spring.datasource.secondary.password=123456
spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver
================================================
FILE: 2.x/chapter3-7/src/test/java/com/didispace/chapter37/Chapter37ApplicationTests.java
================================================
package com.didispace.chapter37;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter37ApplicationTests {
@Autowired
protected JdbcTemplate primaryJdbcTemplate;
@Autowired
protected JdbcTemplate secondaryJdbcTemplate;
@Before
public void setUp() {
primaryJdbcTemplate.update("DELETE FROM USER ");
secondaryJdbcTemplate.update("DELETE FROM USER ");
}
@Test
public void test() throws Exception {
// 往第一个数据源中插入 2 条数据
primaryJdbcTemplate.update("insert into user(name,age) values(?, ?)", "aaa", 20);
primaryJdbcTemplate.update("insert into user(name,age) values(?, ?)", "bbb", 30);
// 往第二个数据源中插入 1 条数据,若插入的是第一个数据源,则会主键冲突报错
secondaryJdbcTemplate.update("insert into user(name,age) values(?, ?)", "ccc", 20);
// 查一下第一个数据源中是否有 2 条数据,验证插入是否成功
Assert.assertEquals("2", primaryJdbcTemplate.queryForObject("select count(1) from user", String.class));
// 查一下第一个数据源中是否有 1 条数据,验证插入是否成功
Assert.assertEquals("1", secondaryJdbcTemplate.queryForObject("select count(1) from user", String.class));
}
}
================================================
FILE: 2.x/chapter3-8/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter3-8/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.3.RELEASE
com.didispace
chapter3-8
0.0.1-SNAPSHOT
Spring Data JPA的多数据源配置
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-actuator
mysql
mysql-connector-java
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter3-8/src/main/java/com/didispace/chapter38/Chapter38Application.java
================================================
package com.didispace.chapter38;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class Chapter38Application {
public static void main(String[] args) {
SpringApplication.run(Chapter38Application.class, args);
}
}
================================================
FILE: 2.x/chapter3-8/src/main/java/com/didispace/chapter38/DataSourceConfiguration.java
================================================
package com.didispace.chapter38;
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.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
@Configuration
public class DataSourceConfiguration {
@Primary
@Bean
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
}
================================================
FILE: 2.x/chapter3-8/src/main/java/com/didispace/chapter38/PrimaryConfig.java
================================================
package com.didispace.chapter38;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef="entityManagerFactoryPrimary",
transactionManagerRef="transactionManagerPrimary",
basePackages= { "com.didispace.chapter38.p" }) //设置Repository所在位置
public class PrimaryConfig {
@Autowired
@Qualifier("primaryDataSource")
private DataSource primaryDataSource;
@Autowired
private JpaProperties jpaProperties;
@Autowired
private HibernateProperties hibernateProperties;
private Map getVendorProperties() {
return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
}
@Primary
@Bean(name = "entityManagerPrimary")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
}
@Primary
@Bean(name = "entityManagerFactoryPrimary")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) {
// HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
// jpaVendorAdapter.setGenerateDdl(true);
return builder
.dataSource(primaryDataSource)
.packages("com.didispace.chapter38.p") //设置实体类所在位置
.persistenceUnit("primaryPersistenceUnit")
.properties(getVendorProperties())
.build();
}
@Primary
@Bean(name = "transactionManagerPrimary")
public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}
================================================
FILE: 2.x/chapter3-8/src/main/java/com/didispace/chapter38/SecondaryConfig.java
================================================
package com.didispace.chapter38;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef="entityManagerFactorySecondary",
transactionManagerRef="transactionManagerSecondary",
basePackages= { "com.didispace.chapter38.s" }) //设置Repository所在位置
public class SecondaryConfig {
@Autowired
@Qualifier("secondaryDataSource")
private DataSource secondaryDataSource;
@Autowired
private JpaProperties jpaProperties;
@Autowired
private HibernateProperties hibernateProperties;
private Map getVendorProperties() {
return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
}
@Bean(name = "entityManagerSecondary")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactorySecondary(builder).getObject().createEntityManager();
}
@Bean(name = "entityManagerFactorySecondary")
public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary (EntityManagerFactoryBuilder builder) {
return builder
.dataSource(secondaryDataSource)
.packages("com.didispace.chapter38.s") //设置实体类所在位置
.persistenceUnit("secondaryPersistenceUnit")
.properties(getVendorProperties())
.build();
}
@Bean(name = "transactionManagerSecondary")
PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
}
}
================================================
FILE: 2.x/chapter3-8/src/main/java/com/didispace/chapter38/p/User.java
================================================
package com.didispace.chapter38.p;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
@Data
@NoArgsConstructor
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
}
================================================
FILE: 2.x/chapter3-8/src/main/java/com/didispace/chapter38/p/UserRepository.java
================================================
package com.didispace.chapter38.p;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
/**
* Created by 程序猿DD/翟永超 on 2020/6/22.
*
* Blog: http://blog.didispace.com/
* Github: https://github.com/dyc87112/
*/
public interface UserRepository extends JpaRepository {
}
================================================
FILE: 2.x/chapter3-8/src/main/java/com/didispace/chapter38/s/Message.java
================================================
package com.didispace.chapter38.s;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
@Data
@NoArgsConstructor
public class Message {
@Id
@GeneratedValue
private Long id;
private String title;
private String message;
public Message(String title, String message) {
this.title = title;
this.message = message;
}
}
================================================
FILE: 2.x/chapter3-8/src/main/java/com/didispace/chapter38/s/MessageRepository.java
================================================
package com.didispace.chapter38.s;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* Created by 程序猿DD/翟永超 on 2020/6/22.
*
* Blog: http://blog.didispace.com/
* Github: https://github.com/dyc87112/
*/
public interface MessageRepository extends JpaRepository {
}
================================================
FILE: 2.x/chapter3-8/src/main/resources/application.properties
================================================
# pring boot 1.x的配置:spring.datasource.primary.url=jdbc:mysql://localhost:3306/test1
spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1
spring.datasource.primary.username=root
spring.datasource.primary.password=12345678
spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver
# spring boot 1.x的配置:spring.datasource.secondary.url=jdbc:mysql://localhost:3306/test2
spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/test2
spring.datasource.secondary.username=root
spring.datasource.secondary.password=12345678
spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver
# 日志打印执行的SQL
spring.jpa.show-sql=true
# Hibernate的DDL策略
spring.jpa.hibernate.ddl-auto=create-drop
================================================
FILE: 2.x/chapter3-8/src/test/java/com/didispace/chapter38/Chapter38ApplicationTests.java
================================================
package com.didispace.chapter38;
import com.didispace.chapter38.p.User;
import com.didispace.chapter38.p.UserRepository;
import com.didispace.chapter38.s.Message;
import com.didispace.chapter38.s.MessageRepository;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
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.context.junit4.SpringRunner;
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter38ApplicationTests {
@Autowired
private UserRepository userRepository;
@Autowired
private MessageRepository messageRepository;
@Test
public void test() throws Exception {
userRepository.save(new User("aaa", 10));
userRepository.save(new User("bbb", 20));
userRepository.save(new User("ccc", 30));
userRepository.save(new User("ddd", 40));
userRepository.save(new User("eee", 50));
Assert.assertEquals(5, userRepository.findAll().size());
messageRepository.save(new Message("o1", "aaaaaaaaaa"));
messageRepository.save(new Message("o2", "bbbbbbbbbb"));
messageRepository.save(new Message("o3", "cccccccccc"));
Assert.assertEquals(3, messageRepository.findAll().size());
}
}
================================================
FILE: 2.x/chapter3-9/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter3-9/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.3.RELEASE
com.didispace
chapter3-9
0.0.1-SNAPSHOT
MyBatis的多数据源配置
1.8
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.1
mysql
mysql-connector-java
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter3-9/src/main/java/com/didispace/chapter39/Chapter39Application.java
================================================
package com.didispace.chapter39;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Chapter39Application {
public static void main(String[] args) {
SpringApplication.run(Chapter39Application.class, args);
}
}
================================================
FILE: 2.x/chapter3-9/src/main/java/com/didispace/chapter39/DataSourceConfiguration.java
================================================
package com.didispace.chapter39;
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 javax.sql.DataSource;
@Configuration
public class DataSourceConfiguration {
@Primary
@Bean
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
}
================================================
FILE: 2.x/chapter3-9/src/main/java/com/didispace/chapter39/PrimaryConfig.java
================================================
package com.didispace.chapter39;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
@MapperScan(
basePackages = "com.didispace.chapter39.p",
sqlSessionFactoryRef = "sqlSessionFactoryPrimary",
sqlSessionTemplateRef = "sqlSessionTemplatePrimary")
public class PrimaryConfig {
private DataSource primaryDataSource;
public PrimaryConfig(@Qualifier("primaryDataSource") DataSource primaryDataSource) {
this.primaryDataSource = primaryDataSource;
}
@Bean
public SqlSessionFactory sqlSessionFactoryPrimary() throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(primaryDataSource);
return bean.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplatePrimary() throws Exception {
return new SqlSessionTemplate(sqlSessionFactoryPrimary());
}
}
================================================
FILE: 2.x/chapter3-9/src/main/java/com/didispace/chapter39/SecondaryConfig.java
================================================
package com.didispace.chapter39;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
@MapperScan(
basePackages = "com.didispace.chapter39.s",
sqlSessionFactoryRef = "sqlSessionFactorySecondary",
sqlSessionTemplateRef = "sqlSessionTemplateSecondary")
public class SecondaryConfig {
private DataSource secondaryDataSource;
public SecondaryConfig(@Qualifier("secondaryDataSource") DataSource secondaryDataSource) {
this.secondaryDataSource = secondaryDataSource;
}
@Bean
public SqlSessionFactory sqlSessionFactorySecondary() throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(secondaryDataSource);
return bean.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplateSecondary() throws Exception {
return new SqlSessionTemplate(sqlSessionFactorySecondary());
}
}
================================================
FILE: 2.x/chapter3-9/src/main/java/com/didispace/chapter39/p/entity/UserPrimary.java
================================================
package com.didispace.chapter39.p.entity;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class UserPrimary {
private Long id;
private String name;
private Integer age;
public UserPrimary(String name, Integer age) {
this.name = name;
this.age = age;
}
}
================================================
FILE: 2.x/chapter3-9/src/main/java/com/didispace/chapter39/p/mapper/UserMapperPrimary.java
================================================
package com.didispace.chapter39.p.mapper;
import com.didispace.chapter39.p.entity.UserPrimary;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
/**
* Created by 程序猿DD/翟永超 on 2020/2/28.
*
* Blog: http://blog.didispace.com/
* Github: https://github.com/dyc87112/
*/
public interface UserMapperPrimary {
@Select("SELECT * FROM USER WHERE NAME = #{name}")
UserPrimary findByName(@Param("name") String name);
@Insert("INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age})")
int insert(@Param("name") String name, @Param("age") Integer age);
@Delete("DELETE FROM USER")
int deleteAll();
}
================================================
FILE: 2.x/chapter3-9/src/main/java/com/didispace/chapter39/s/entity/UserSecondary.java
================================================
package com.didispace.chapter39.s.entity;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class UserSecondary {
private Long id;
private String name;
private Integer age;
public UserSecondary(String name, Integer age) {
this.name = name;
this.age = age;
}
}
================================================
FILE: 2.x/chapter3-9/src/main/java/com/didispace/chapter39/s/mapper/UserMapperSecondary.java
================================================
package com.didispace.chapter39.s.mapper;
import com.didispace.chapter39.s.entity.UserSecondary;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
/**
* Created by 程序猿DD/翟永超 on 2020/2/28.
*
* Blog: http://blog.didispace.com/
* Github: https://github.com/dyc87112/
*/
public interface UserMapperSecondary {
@Select("SELECT * FROM USER WHERE NAME = #{name}")
UserSecondary findByName(@Param("name") String name);
@Insert("INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age})")
int insert(@Param("name") String name, @Param("age") Integer age);
@Delete("DELETE FROM USER")
int deleteAll();
}
================================================
FILE: 2.x/chapter3-9/src/main/resources/application.properties
================================================
# pring boot 1.x的配置:spring.datasource.primary.url=jdbc:mysql://localhost:3306/test1
spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1
spring.datasource.primary.username=root
spring.datasource.primary.password=12345678
spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver
# spring boot 1.x的配置:spring.datasource.secondary.url=jdbc:mysql://localhost:3306/test2
spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/test2
spring.datasource.secondary.username=root
spring.datasource.secondary.password=12345678
spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver
#mybatis.mapper-locations=classpath:mapper/*.xml
================================================
FILE: 2.x/chapter3-9/src/main/resources/mapper.primary/UserMapper.xml
================================================
INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age})
================================================
FILE: 2.x/chapter3-9/src/main/resources/mapper.secondary/UserMapper.xml
================================================
INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age})
================================================
FILE: 2.x/chapter3-9/src/test/java/com/didispace/chapter39/Chapter39ApplicationTests.java
================================================
package com.didispace.chapter39;
import com.didispace.chapter39.p.entity.UserPrimary;
import com.didispace.chapter39.p.mapper.UserMapperPrimary;
import com.didispace.chapter39.s.entity.UserSecondary;
import com.didispace.chapter39.s.mapper.UserMapperSecondary;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
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.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class Chapter39ApplicationTests {
@Autowired
private UserMapperPrimary userMapperPrimary;
@Autowired
private UserMapperSecondary userMapperSecondary;
@Before
public void setUp() {
// 清空测试表,保证每次结果一样
userMapperPrimary.deleteAll();
userMapperSecondary.deleteAll();
}
@Test
public void test() throws Exception {
// 往Primary数据源插入一条数据
userMapperPrimary.insert("AAA", 20);
// 从Primary数据源查询刚才插入的数据,配置正确就可以查询到
UserPrimary userPrimary = userMapperPrimary.findByName("AAA");
Assert.assertEquals(20, userPrimary.getAge().intValue());
// 从Secondary数据源查询刚才插入的数据,配置正确应该是查询不到的
UserSecondary userSecondary = userMapperSecondary.findByName("AAA");
Assert.assertNull(userSecondary);
// 往Secondary数据源插入一条数据
userMapperSecondary.insert("BBB", 20);
// 从Primary数据源查询刚才插入的数据,配置正确应该是查询不到的
userPrimary = userMapperPrimary.findByName("BBB");
Assert.assertNull(userPrimary);
// 从Secondary数据源查询刚才插入的数据,配置正确就可以查询到
userSecondary = userMapperSecondary.findByName("BBB");
Assert.assertEquals(20, userSecondary.getAge().intValue());
}
}
================================================
FILE: 2.x/chapter4-1/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter4-1/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.3.RELEASE
com.didispace
chapter4-1
0.0.1-SNAPSHOT
使用 Thymeleaf开发Web页面
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-thymeleaf
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter4-1/src/main/java/com/didispace/chapter41/Chapter41Application.java
================================================
package com.didispace.chapter41;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Chapter41Application {
public static void main(String[] args) {
SpringApplication.run(Chapter41Application.class, args);
}
}
================================================
FILE: 2.x/chapter4-1/src/main/java/com/didispace/chapter41/HelloController.java
================================================
package com.didispace.chapter41;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HelloController {
@GetMapping("/")
public String index(ModelMap map) {
// 加入一个属性,用来在模板中读取
map.addAttribute("host", "http://blog.didispace.com");
// return模板文件的名称,对应src/main/resources/templates/index.html
return "index";
}
}
================================================
FILE: 2.x/chapter4-1/src/main/resources/application.properties
================================================
================================================
FILE: 2.x/chapter4-1/src/main/resources/templates/index.html
================================================
Hello World
================================================
FILE: 2.x/chapter4-2/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter4-2/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.3.RELEASE
com.didispace
chapter4-2
0.0.1-SNAPSHOT
使用 ECharts 绘制折线图
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-thymeleaf
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter4-2/src/main/java/com/didispace/chapter42/Chapter42Application.java
================================================
package com.didispace.chapter42;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Chapter42Application {
public static void main(String[] args) {
SpringApplication.run(Chapter42Application.class, args);
}
}
================================================
FILE: 2.x/chapter4-2/src/main/java/com/didispace/chapter42/HelloController.java
================================================
package com.didispace.chapter42;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HelloController {
@GetMapping("/")
public String index(ModelMap map) {
// return模板文件的名称,对应src/main/resources/templates/index.html
return "index";
}
}
================================================
FILE: 2.x/chapter4-2/src/main/resources/application.properties
================================================
================================================
FILE: 2.x/chapter4-2/src/main/resources/templates/index.html
================================================
Spring Boot中使用ECharts
================================================
FILE: 2.x/chapter4-3/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter4-3/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.4.1
com.didispace
chapter4-3
0.0.1-SNAPSHOT
文件上传
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-thymeleaf
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter4-3/src/main/java/com/didispace/chapter43/Chapter43Application.java
================================================
package com.didispace.chapter43;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Chapter43Application {
public static void main(String[] args) {
SpringApplication.run(Chapter43Application.class, args);
}
}
================================================
FILE: 2.x/chapter4-3/src/main/java/com/didispace/chapter43/UploadController.java
================================================
package com.didispace.chapter43;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
@Controller
@Slf4j
public class UploadController {
@Value("${file.upload.path}")
private String path;
@GetMapping("/")
public String uploadPage() {
return "upload";
}
@PostMapping("/upload")
@ResponseBody
public String create(@RequestPart MultipartFile file) throws IOException {
String fileName = file.getOriginalFilename();
String filePath = path + fileName;
File dest = new File(filePath);
Files.copy(file.getInputStream(), dest.toPath());
return "Upload file success : " + dest.getAbsolutePath();
}
}
================================================
FILE: 2.x/chapter4-3/src/main/resources/application.properties
================================================
spring.servlet.multipart.max-file-size=2MB
spring.servlet.multipart.max-request-size=2MB
file.upload.path=/Users/zhaiyongchao/
================================================
FILE: 2.x/chapter4-3/src/main/resources/templates/upload.html
================================================
文件上传页面
文件上传页面
================================================
FILE: 2.x/chapter4-3/src/test/java/FileTest.java
================================================
import com.didispace.chapter43.Chapter43Application;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest(classes = Chapter43Application.class)
public class FileTest {
@Autowired
protected WebApplicationContext context;
protected MockMvc mvc;
@BeforeEach
public void setUp() {
mvc = MockMvcBuilders.webAppContextSetup(context).build();
}
@Test
public void uploadFile() throws Exception {
MockMultipartFile file = new MockMultipartFile(
"file",
"hello.txt",
MediaType.TEXT_PLAIN_VALUE,
"Hello, World!".getBytes()
);
final MvcResult result = mvc.perform(
MockMvcRequestBuilders
.multipart("/upload")
.file(file))
.andDo(print())
.andExpect(status().isOk())
.andReturn();
}
}
================================================
FILE: 2.x/chapter4-4/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter4-4/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.4.1
com.didispace
chapter4-4
0.0.1-SNAPSHOT
多文件上传
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-thymeleaf
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter4-4/src/main/java/com/didispace/chapter44/Chapter44Application.java
================================================
package com.didispace.chapter44;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Chapter44Application {
public static void main(String[] args) {
SpringApplication.run(Chapter44Application.class, args);
}
}
================================================
FILE: 2.x/chapter4-4/src/main/java/com/didispace/chapter44/UploadController.java
================================================
package com.didispace.chapter44;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
@Controller
@Slf4j
public class UploadController {
@Value("${file.upload.path}")
private String path;
@GetMapping("/")
public String uploadPage() {
return "upload";
}
@PostMapping("/upload")
@ResponseBody
public String create(@RequestPart MultipartFile[] files) throws IOException {
StringBuffer message = new StringBuffer();
for (MultipartFile file : files) {
String fileName = file.getOriginalFilename();
String filePath = path + fileName;
File dest = new File(filePath);
Files.copy(file.getInputStream(), dest.toPath());
message.append("Upload file success : " + dest.getAbsolutePath()).append("
");
}
return message.toString();
}
}
================================================
FILE: 2.x/chapter4-4/src/main/resources/application.properties
================================================
spring.servlet.multipart.max-file-size=2MB
spring.servlet.multipart.max-request-size=2MB
file.upload.path=/Users/didi/
================================================
FILE: 2.x/chapter4-4/src/main/resources/templates/upload.html
================================================
文件上传页面
文件上传页面
================================================
FILE: 2.x/chapter4-4/src/test/java/FileTest.java
================================================
import org.junit.jupiter.api.Test;
public class FileTest {
@Test
public void uploadFile() throws Exception {
}
}
================================================
FILE: 2.x/chapter4-5/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.5.1
com.didispace
chapter4-5
0.0.1-SNAPSHOT
Spring Security快速入门
UTF-8
1.8
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-starter-security
org.springframework.boot
spring-boot-maven-plugin
true
================================================
FILE: 2.x/chapter4-5/src/main/java/com/didispace/chapter45/Application.java
================================================
package com.didispace.chapter45;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
*
* @author 程序猿DD
* @version 1.0.0
* @blog http://blog.didispace.com
*
*/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
================================================
FILE: 2.x/chapter4-5/src/main/java/com/didispace/chapter45/HelloController.java
================================================
package com.didispace.chapter45;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
*
* @author 程序猿DD
* @version 1.0.0
* @blog http://blog.didispace.com
*
*/
@Controller
public class HelloController {
@RequestMapping("/")
public String index() {
return "index";
}
@RequestMapping("/hello")
public String hello() {
return "hello";
}
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String login() {
return "login";
}
}
================================================
FILE: 2.x/chapter4-5/src/main/java/com/didispace/chapter45/WebSecurityConfig.java
================================================
package com.didispace.chapter45;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
================================================
FILE: 2.x/chapter4-5/src/main/resources/application.properties
================================================
================================================
FILE: 2.x/chapter4-5/src/main/resources/templates/hello.html
================================================
Hello World!
Hello [[${#httpServletRequest.remoteUser}]]!
================================================
FILE: 2.x/chapter4-5/src/main/resources/templates/index.html
================================================
Spring Security入门
欢迎使用Spring Security!
点击 这里 打个招呼吧
================================================
FILE: 2.x/chapter4-5/src/main/resources/templates/login.html
================================================
Spring Security Example
用户名或密码错
您已注销成功
================================================
FILE: 2.x/chapter5-1/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter5-1/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.3.RELEASE
com.didispace
chapter5-1
0.0.1-SNAPSHOT
使用进程内缓存
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-cache
org.springframework.boot
spring-boot-starter-actuator
mysql
mysql-connector-java
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter5-1/src/main/java/com/didispace/chapter51/Chapter51Application.java
================================================
package com.didispace.chapter51;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@EnableCaching
@SpringBootApplication
public class Chapter51Application {
public static void main(String[] args) {
SpringApplication.run(Chapter51Application.class, args);
}
}
================================================
FILE: 2.x/chapter5-1/src/main/java/com/didispace/chapter51/User.java
================================================
package com.didispace.chapter51;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
@Data
@NoArgsConstructor
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
}
================================================
FILE: 2.x/chapter5-1/src/main/java/com/didispace/chapter51/UserRepository.java
================================================
package com.didispace.chapter51;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
/**
* Created by 程序猿DD/翟永超 on 2020/7/13.
*
* Blog: http://blog.didispace.com/
* Github: https://github.com/dyc87112/
*/
@CacheConfig(cacheNames = "users")
public interface UserRepository extends JpaRepository {
@Cacheable
User findByName(String name);
User findByNameAndAge(String name, Integer age);
@Query("from User u where u.name=:name")
User findUser(@Param("name") String name);
}
================================================
FILE: 2.x/chapter5-1/src/main/resources/application.properties
================================================
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=12345678
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
================================================
FILE: 2.x/chapter5-1/src/test/java/com/didispace/chapter51/Chapter51ApplicationTests.java
================================================
package com.didispace.chapter51;
import lombok.extern.slf4j.Slf4j;
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.cache.CacheManager;
import org.springframework.test.context.junit4.SpringRunner;
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter51ApplicationTests {
@Autowired
private UserRepository userRepository;
@Autowired
private CacheManager cacheManager;
@Test
public void test() throws Exception {
// 创建1条记录
userRepository.save(new User("AAA", 10));
User u1 = userRepository.findByName("AAA");
System.out.println("第一次查询:" + u1.getAge());
User u2 = userRepository.findByName("AAA");
System.out.println("第二次查询:" + u2.getAge());
}
}
================================================
FILE: 2.x/chapter5-2/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter5-2/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.3.RELEASE
com.didispace
chapter5-2
0.0.1-SNAPSHOT
使用进程内缓存 EhCache
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-cache
net.sf.ehcache
ehcache
org.springframework.boot
spring-boot-starter-actuator
mysql
mysql-connector-java
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter5-2/src/main/java/com/didispace/chapter52/Chapter52Application.java
================================================
package com.didispace.chapter52;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@EnableCaching
@SpringBootApplication
public class Chapter52Application {
public static void main(String[] args) {
SpringApplication.run(Chapter52Application.class, args);
}
}
================================================
FILE: 2.x/chapter5-2/src/main/java/com/didispace/chapter52/User.java
================================================
package com.didispace.chapter52;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
@Data
@NoArgsConstructor
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
}
================================================
FILE: 2.x/chapter5-2/src/main/java/com/didispace/chapter52/UserRepository.java
================================================
package com.didispace.chapter52;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
/**
* Created by 程序猿DD/翟永超 on 2020/7/14.
*
* Blog: http://blog.didispace.com/
* Github: https://github.com/dyc87112/
*/
@CacheConfig(cacheNames = "users")
public interface UserRepository extends JpaRepository {
@Cacheable
User findByName(String name);
}
================================================
FILE: 2.x/chapter5-2/src/main/resources/application.properties
================================================
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=12345678
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
================================================
FILE: 2.x/chapter5-2/src/main/resources/ehcache.xml
================================================
================================================
FILE: 2.x/chapter5-2/src/test/java/com/didispace/chapter52/Chapter52ApplicationTests.java
================================================
package com.didispace.chapter52;
import lombok.extern.slf4j.Slf4j;
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.cache.CacheManager;
import org.springframework.test.context.junit4.SpringRunner;
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter52ApplicationTests {
@Autowired
private UserRepository userRepository;
@Autowired
private CacheManager cacheManager;
@Test
public void test() throws Exception {
System.out.println("CacheManager type : " + cacheManager.getClass());
// 创建1条记录
userRepository.save(new User("AAA", 10));
User u1 = userRepository.findByName("AAA");
System.out.println("第一次查询:" + u1.getAge());
User u2 = userRepository.findByName("AAA");
System.out.println("第二次查询:" + u2.getAge());
}
}
================================================
FILE: 2.x/chapter5-3/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter5-3/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.3.RELEASE
com.didispace
chapter5-3
0.0.1-SNAPSHOT
使用EhCache缓存集群
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-cache
net.sf.ehcache
ehcache
org.springframework.boot
spring-boot-starter-actuator
mysql
mysql-connector-java
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter5-3/src/main/java/com/didispace/chapter53/Chapter53Application.java
================================================
package com.didispace.chapter53;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.rmi.registry.LocateRegistry;
@EnableCaching
@SpringBootApplication
public class Chapter53Application {
public static void main(String[] args) throws Exception {
// LocateRegistry.createRegistry(Integer.valueOf(System.getProperty("rmi.port")));
SpringApplication.run(Chapter53Application.class, args);
}
@RestController
static class HelloController {
@Autowired
private UserRepository userRepository;
@GetMapping("/create")
public void create() {
userRepository.save(new User("AAA", 10));
}
@GetMapping("/update")
public User update() {
User u1 = userRepository.findByName("AAA");
u1.setAge(20);
u1 = userRepository.save(u1);
return u1;
}
@GetMapping("/find")
public User find() {
User u1 = userRepository.findByName("AAA");
System.out.println("查询AAA用户:" + u1.getAge());
return u1;
}
}
}
================================================
FILE: 2.x/chapter5-3/src/main/java/com/didispace/chapter53/User.java
================================================
package com.didispace.chapter53;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.io.Serializable;
@Entity
@Data
@NoArgsConstructor
public class User implements Serializable {
@Id
@GeneratedValue
private Long id;
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
}
================================================
FILE: 2.x/chapter5-3/src/main/java/com/didispace/chapter53/UserRepository.java
================================================
package com.didispace.chapter53;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
/**
* Created by 程序猿DD/翟永超 on 2020/7/16.
*
* Blog: http://blog.didispace.com/
* Github: https://github.com/dyc87112/
*/
@CacheConfig(cacheNames = "users")
public interface UserRepository extends JpaRepository {
@Cacheable
User findByName(String name);
}
================================================
FILE: 2.x/chapter5-3/src/main/resources/application.properties
================================================
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=12345678
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create
#logging.level.net.sf.ehcache=debug
# 不同实例的配置
#spring.cache.ehcache.config=classpath:ehcache-1.xml
#spring.cache.ehcache.config=classpath:ehcache-2.xml
# 用不同命令启动不同实例
#-Dserver.port=8001 -Dspring.cache.ehcache.config=classpath:ehcache-1.xml
#-Dserver.port=8002 -Dspring.cache.ehcache.config=classpath:ehcache-2.xml
================================================
FILE: 2.x/chapter5-3/src/main/resources/ehcache-1.xml
================================================
================================================
FILE: 2.x/chapter5-3/src/main/resources/ehcache-2.xml
================================================
================================================
FILE: 2.x/chapter5-3/src/test/java/com/didispace/chapter53/Chapter53ApplicationTests.java
================================================
package com.didispace.chapter53;
import lombok.extern.slf4j.Slf4j;
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.cache.CacheManager;
import org.springframework.test.context.junit4.SpringRunner;
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter53ApplicationTests {
@Autowired
private UserRepository userRepository;
@Autowired
private CacheManager cacheManager;
@Test
public void test() throws Exception {
System.out.println("CacheManager type : " + cacheManager.getClass());
// 创建1条记录
userRepository.save(new User("AAA", 10));
User u1 = userRepository.findByName("AAA");
System.out.println("第一次查询:" + u1.getAge());
User u2 = userRepository.findByName("AAA");
System.out.println("第二次查询:" + u2.getAge());
}
}
================================================
FILE: 2.x/chapter5-4/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter5-4/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.3.RELEASE
com.didispace
chapter5-4
0.0.1-SNAPSHOT
使用集中式缓存Redis
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-data-redis
org.apache.commons
commons-pool2
org.springframework.boot
spring-boot-starter-actuator
mysql
mysql-connector-java
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter5-4/src/main/java/com/didispace/chapter54/Chapter54Application.java
================================================
package com.didispace.chapter54;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@EnableCaching
@SpringBootApplication
public class Chapter54Application {
public static void main(String[] args) {
SpringApplication.run(Chapter54Application.class, args);
}
}
================================================
FILE: 2.x/chapter5-4/src/main/java/com/didispace/chapter54/User.java
================================================
package com.didispace.chapter54;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.io.Serializable;
@Entity
@Data
@NoArgsConstructor
public class User implements Serializable {
@Id
@GeneratedValue
private Long id;
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
}
================================================
FILE: 2.x/chapter5-4/src/main/java/com/didispace/chapter54/UserRepository.java
================================================
package com.didispace.chapter54;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
/**
* Created by 程序猿DD/翟永超 on 2020/7/26.
*
* Blog: http://blog.didispace.com/
* Github: https://github.com/dyc87112/
*/
@CacheConfig(cacheNames = "users")
public interface UserRepository extends JpaRepository {
@Cacheable
User findByName(String name);
User findByNameAndAge(String name, Integer age);
@Query("from User u where u.name=:name")
User findUser(@Param("name") String name);
}
================================================
FILE: 2.x/chapter5-4/src/main/resources/application.properties
================================================
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=12345678
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.min-idle=0
spring.redis.lettuce.shutdown-timeout=100ms
================================================
FILE: 2.x/chapter5-4/src/test/java/com/didispace/chapter54/Chapter54ApplicationTests.java
================================================
package com.didispace.chapter54;
import lombok.extern.slf4j.Slf4j;
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.cache.CacheManager;
import org.springframework.test.context.junit4.SpringRunner;
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter54ApplicationTests {
@Autowired
private UserRepository userRepository;
@Autowired
private CacheManager cacheManager;
@Test
public void test() throws Exception {
System.out.println("CacheManager type : " + cacheManager.getClass());
// 创建1条记录
userRepository.save(new User("AAA", 10));
User u1 = userRepository.findByName("AAA");
System.out.println("第一次查询:" + u1.getAge());
User u2 = userRepository.findByName("AAA");
System.out.println("第二次查询:" + u2.getAge());
}
}
================================================
FILE: 2.x/chapter5-5/.gitignore
================================================
HELP.md
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
### VS Code ###
.vscode/
================================================
FILE: 2.x/chapter5-5/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.5.1
com.didispace
chapter5-5
0.0.1-SNAPSHOT
使用Redis的发布订阅
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-redis
org.apache.commons
commons-pool2
org.springframework.boot
spring-boot-starter-actuator
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter5-5/src/main/java/com/didispace/chapter55/Chapter55Application.java
================================================
package com.didispace.chapter55;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.nio.charset.StandardCharsets;
@SpringBootApplication
public class Chapter55Application {
private static String CHANNEL = "didispace";
public static void main(String[] args) {
SpringApplication.run(Chapter55Application.class, args);
}
@RestController
static class RedisController {
private RedisTemplate redisTemplate;
public RedisController(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
@GetMapping("/publish")
public void publish(@RequestParam String message) {
// 发送消息
redisTemplate.convertAndSend(CHANNEL, message);
}
}
@Slf4j
@Service
static class MessageSubscriber {
public MessageSubscriber(RedisTemplate redisTemplate) {
RedisConnection redisConnection = redisTemplate.getConnectionFactory().getConnection();
redisConnection.subscribe(new MessageListener() {
@Override
public void onMessage(Message message, byte[] bytes) {
// 收到消息的处理逻辑
log.info("Receive message : " + message);
}
}, CHANNEL.getBytes(StandardCharsets.UTF_8));
}
}
}
================================================
FILE: 2.x/chapter5-5/src/main/resources/application.properties
================================================
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.min-idle=0
spring.redis.lettuce.shutdown-timeout=100ms
================================================
FILE: 2.x/chapter6-1/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.4.1
com.didispace
chapter6-1
0.0.1-SNAPSHOT
使用MongoDB
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-mongodb
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter6-1/src/main/java/com/didispace/chapter61/Chapter61Application.java
================================================
package com.didispace.chapter61;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Chapter61Application {
public static void main(String[] args) {
SpringApplication.run(Chapter61Application.class, args);
}
}
================================================
FILE: 2.x/chapter6-1/src/main/java/com/didispace/chapter61/User.java
================================================
package com.didispace.chapter61;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.data.annotation.Id;
/**
* @author 程序猿DD
* @version 1.0.0
* @blog http://blog.didispace.com
*/
@Data
@AllArgsConstructor
public class User {
@Id
private Long id;
private String username;
private Integer age;
}
================================================
FILE: 2.x/chapter6-1/src/main/java/com/didispace/chapter61/UserRepository.java
================================================
package com.didispace.chapter61;
import org.springframework.data.mongodb.repository.MongoRepository;
/**
* @author 程序猿DD
* @version 1.0.0
* @blog http://blog.didispace.com
*/
public interface UserRepository extends MongoRepository {
User findByUsername(String username);
}
================================================
FILE: 2.x/chapter6-1/src/main/resources/application.properties
================================================
spring.data.mongodb.uri=mongodb://localhost:27017/test
================================================
FILE: 2.x/chapter6-1/src/test/java/com/didispace/chapter61/ApplicationTests.java
================================================
package com.didispace.chapter61;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest(classes = Chapter61Application.class)
public class ApplicationTests {
@Autowired
private UserRepository userRepository;
@Test
public void test() throws Exception {
userRepository.deleteAll();
// 创建三个User,并验证User总数
userRepository.save(new User(1L, "didi", 30));
userRepository.save(new User(2L, "mama", 40));
userRepository.save(new User(3L, "kaka", 50));
Assertions.assertEquals(3, userRepository.findAll().size());
// 删除一个User,再验证User总数
User u = userRepository.findById(1L).get();
userRepository.delete(u);
Assertions.assertEquals(2, userRepository.findAll().size());
// 删除一个User,再验证User总数
u = userRepository.findByUsername("mama");
userRepository.delete(u);
Assertions.assertEquals(1, userRepository.findAll().size());
}
}
================================================
FILE: 2.x/chapter6-2/pom.xml
================================================
4.0.0
com.didispace
chapter6-2
1.0.0
jar
使用轻量级树状存储 LDAP
org.springframework.boot
spring-boot-starter-parent
2.5.1
UTF-8
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-ldap
org.projectlombok
lombok
provided
com.unboundid
unboundid-ldapsdk
test
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter6-2/src/main/java/com/didispace/chapter62/Chapter62Application.java
================================================
package com.didispace.chapter62;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Chapter62Application {
public static void main(String[] args) {
SpringApplication.run(Chapter62Application.class, args);
}
}
================================================
FILE: 2.x/chapter6-2/src/main/java/com/didispace/chapter62/Person.java
================================================
package com.didispace.chapter62;
import lombok.Data;
import org.springframework.ldap.odm.annotations.*;
import javax.naming.Name;
@Entry(base = "ou=people,dc=didispace,dc=com", objectClasses = "inetOrgPerson")
@Data
public class Person {
@Id
private Name id;
@DnAttribute(value = "uid", index = 3)
private String uid;
@Attribute(name = "cn")
private String commonName;
@Attribute(name = "sn")
private String userName;
private String userPassword;
}
================================================
FILE: 2.x/chapter6-2/src/main/java/com/didispace/chapter62/PersonRepository.java
================================================
package com.didispace.chapter62;
import org.springframework.data.repository.CrudRepository;
import javax.naming.Name;
public interface PersonRepository extends CrudRepository {
}
================================================
FILE: 2.x/chapter6-2/src/main/resources/application.properties
================================================
#spring.ldap.urls=ldap://localhost:1235
#spring.ldap.base=dc=didispace,dc=com
#spring.ldap.username=didispace
#spring.ldap.password=123456
================================================
FILE: 2.x/chapter6-2/src/test/java/com/didispace/chapter62/ApplicationTests.java
================================================
package com.didispace.chapter62;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@Slf4j
@SpringBootTest
public class ApplicationTests {
@Autowired
private PersonRepository personRepository;
@Test
public void findAll() {
personRepository.findAll().forEach(p -> {
System.out.println(p);
});
}
@Test
public void save() {
Person person = new Person();
person.setUid("uid:1");
person.setUserName("AAA");
person.setCommonName("aaa");
person.setUserPassword("123456");
personRepository.save(person);
personRepository.findAll().forEach(p -> {
System.out.println(p);
});
}
}
================================================
FILE: 2.x/chapter6-2/src/test/resources/application.properties
================================================
spring.ldap.embedded.ldif=classpath:ldap-server.ldif
spring.ldap.embedded.base-dn=dc=didispace,dc=com
================================================
FILE: 2.x/chapter6-2/src/test/resources/ldap-server.ldif
================================================
dn: dc=didispace,dc=com
objectClass: top
objectClass: domain
objectclass: extensibleObject
dc: didispace
dn: ou=people,dc=didispace,dc=com
objectclass: top
objectclass: organizationalUnit
ou: people
dn: uid=ben,ou=people,dc=didispace,dc=com
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: didi
sn: zhaiyongchao
uid: didi
userPassword: {SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=
================================================
FILE: 2.x/chapter6-3/pom.xml
================================================
4.0.0
com.didispace
chapter6-3
1.0.0
jar
使用时序数据库InfluxDB
org.springframework.boot
spring-boot-starter-parent
2.5.1
UTF-8
1.8
org.springframework.boot
spring-boot-starter-web
org.influxdb
influxdb-java
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter6-3/src/main/java/com/didispace/chapter63/Chapter63Application.java
================================================
package com.didispace.chapter63;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling
@SpringBootApplication
public class Chapter63Application {
public static void main(String[] args) {
SpringApplication.run(Chapter63Application.class, args);
}
}
================================================
FILE: 2.x/chapter6-3/src/main/java/com/didispace/chapter63/Monitor.java
================================================
package com.didispace.chapter63;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.influxdb.InfluxDB;
import org.influxdb.dto.Point;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.util.Random;
import java.util.concurrent.TimeUnit;
/**
* Created by 程序猿DD on 2021/8/2.
*
* Blog: http://blog.didispace.com/
* Github: https://github.com/dyc87112/
*/
@Service
@AllArgsConstructor
@Slf4j
public class Monitor {
private InfluxDB influxDB;
@Scheduled(fixedRate = 5000)
public void writeQPS() {
// 模拟要上报的统计数据
int count = (int) (Math.random() * 100);
Point point = Point.measurement("ApiQPS") // ApiQPS表
.tag("url", "/hello") // url字段
.addField("count", count) // 统计数据
.time(System.currentTimeMillis(), TimeUnit.MILLISECONDS) // 时间
.build();
// 往test库写数据
influxDB.write("test", "autogen", point);
log.info("上报统计数据:" + count);
}
}
================================================
FILE: 2.x/chapter6-3/src/main/resources/application.properties
================================================
spring.influx.url=http://localhost:8086
spring.influx.user=admin
spring.influx.password=
================================================
FILE: 2.x/chapter6-3/src/test/java/com/didispace/chapter63/ApplicationTests.java
================================================
package com.didispace.chapter63;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@Slf4j
@SpringBootTest
public class ApplicationTests {
@Test
public void findAll() {
}
@Test
public void save() {
}
}
================================================
FILE: 2.x/chapter6-4/pom.xml
================================================
4.0.0
com.didispace
chapter6-4
1.0.0
jar
使用PostgreSQL数据库
org.springframework.boot
spring-boot-starter-parent
2.5.1
UTF-8
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-jpa
org.postgresql
postgresql
runtime
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter6-4/src/main/java/com/didispace/chapter64/Chapter64Application.java
================================================
package com.didispace.chapter64;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
public class Chapter64Application {
public static void main(String[] args) {
SpringApplication.run(Chapter64Application.class, args);
}
}
================================================
FILE: 2.x/chapter6-4/src/main/java/com/didispace/chapter64/UserInfo.java
================================================
package com.didispace.chapter64;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
@Data
@NoArgsConstructor
public class UserInfo {
@Id
@GeneratedValue
private Long id;
private String name;
private Integer age;
public UserInfo(String name, Integer age) {
this.name = name;
this.age = age;
}
}
================================================
FILE: 2.x/chapter6-4/src/main/java/com/didispace/chapter64/UserInfoRepository.java
================================================
package com.didispace.chapter64;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
/**
* Created by 程序猿DD/翟永超 on 2021/10/08.
*
* Blog: http://blog.didispace.com/
* Github: https://github.com/dyc87112/
*/
public interface UserInfoRepository extends JpaRepository {
UserInfo findByName(String name);
UserInfo findByNameAndAge(String name, Integer age);
@Query("from UserInfo u where u.name=:name")
UserInfo findUser(@Param("name") String name);
}
================================================
FILE: 2.x/chapter6-4/src/main/resources/application.properties
================================================
spring.datasource.url=jdbc:postgresql://localhost:5432/test
spring.datasource.username=postgres
spring.datasource.password=123456
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.hbm2ddl.auto=create
================================================
FILE: 2.x/chapter6-4/src/test/java/com/didispace/chapter64/ApplicationTests.java
================================================
package com.didispace.chapter64;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@Slf4j
@SpringBootTest
public class ApplicationTests {
@Autowired
private UserInfoRepository userRepository;
@Test
public void test() throws Exception {
// 创建10条记录
userRepository.save(new UserInfo("AAA", 10));
userRepository.save(new UserInfo("BBB", 20));
userRepository.save(new UserInfo("CCC", 30));
userRepository.save(new UserInfo("DDD", 40));
userRepository.save(new UserInfo("EEE", 50));
userRepository.save(new UserInfo("FFF", 60));
userRepository.save(new UserInfo("GGG", 70));
userRepository.save(new UserInfo("HHH", 80));
userRepository.save(new UserInfo("III", 90));
userRepository.save(new UserInfo("JJJ", 100));
// 测试findAll, 查询所有记录
Assertions.assertEquals(10, userRepository.findAll().size());
// 测试findByName, 查询姓名为FFF的User
Assertions.assertEquals(60, userRepository.findByName("FFF").getAge().longValue());
// 测试findUser, 查询姓名为FFF的User
Assertions.assertEquals(60, userRepository.findUser("FFF").getAge().longValue());
// 测试findByNameAndAge, 查询姓名为FFF并且年龄为60的User
Assertions.assertEquals("FFF", userRepository.findByNameAndAge("FFF", 60).getName());
// 测试删除姓名为AAA的User
userRepository.delete(userRepository.findByName("AAA"));
// 测试findAll, 查询所有记录, 验证上面的删除是否成功
Assertions.assertEquals(9, userRepository.findAll().size());
}
}
================================================
FILE: 2.x/chapter7-1/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.5.1
com.didispace
chapter7-1
0.0.1-SNAPSHOT
使用@Scheduled实现定时任务
1.8
org.springframework.boot
spring-boot-starter-web
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter7-1/src/main/java/com/didispace/chapter71/Chapter71Application.java
================================================
package com.didispace.chapter71;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling
@SpringBootApplication
public class Chapter71Application {
public static void main(String[] args) {
SpringApplication.run(Chapter71Application.class, args);
}
}
================================================
FILE: 2.x/chapter7-1/src/main/java/com/didispace/chapter71/ScheduledTasks.java
================================================
package com.didispace.chapter71;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
@Slf4j
@Component
@AllArgsConstructor
public class ScheduledTasks {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
@Scheduled(fixedRate = 5000)
public void reportCurrentTime() {
log.info("现在时间:" + dateFormat.format(new Date()));
}
}
================================================
FILE: 2.x/chapter7-1/src/main/resources/application.properties
================================================
================================================
FILE: 2.x/chapter7-2/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.5.1
com.didispace
chapter7-2
0.0.1-SNAPSHOT
使用Elastic Job实现定时任务
1.8
org.apache.shardingsphere.elasticjob
elasticjob-lite-spring-boot-starter
3.0.0
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter7-2/src/main/java/com/didispace/chapter72/Chapter72Application.java
================================================
package com.didispace.chapter72;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Chapter72Application {
public static void main(String[] args) {
SpringApplication.run(Chapter72Application.class, args);
}
}
================================================
FILE: 2.x/chapter7-2/src/main/java/com/didispace/chapter72/MySimpleJob.java
================================================
package com.didispace.chapter72;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.elasticjob.api.ShardingContext;
import org.apache.shardingsphere.elasticjob.simple.job.SimpleJob;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class MySimpleJob implements SimpleJob {
@Override
public void execute(ShardingContext context) {
log.info("MySimpleJob start : didispace.com {}", System.currentTimeMillis());
}
}
================================================
FILE: 2.x/chapter7-2/src/main/resources/application.properties
================================================
elasticjob.reg-center.server-lists=localhost:2181
elasticjob.reg-center.namespace=didispace
elasticjob.jobs.my-simple-job.elastic-job-class=com.didispace.chapter72.MySimpleJob
elasticjob.jobs.my-simple-job.cron=0/5 * * * * ?
elasticjob.jobs.my-simple-job.sharding-total-count=1
================================================
FILE: 2.x/chapter7-3/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.5.1
com.didispace
chapter7-3
0.0.1-SNAPSHOT
使用Elastic Job的分片配置
1.8
org.apache.shardingsphere.elasticjob
elasticjob-lite-spring-boot-starter
3.0.0
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter7-3/src/main/java/com/didispace/chapter73/Chapter73Application.java
================================================
package com.didispace.chapter73;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Chapter73Application {
public static void main(String[] args) {
SpringApplication.run(Chapter73Application.class, args);
}
}
================================================
FILE: 2.x/chapter7-3/src/main/java/com/didispace/chapter73/MyShardingJob.java
================================================
package com.didispace.chapter73;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.elasticjob.api.ShardingContext;
import org.apache.shardingsphere.elasticjob.simple.job.SimpleJob;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class MyShardingJob implements SimpleJob {
@Override
public void execute(ShardingContext context) {
// sharding-total-count=3,所以任务被分为三个分片
switch (context.getShardingItem()) {
case 0:
log.info("分片1:执行任务");
break;
case 1:
log.info("分片2:执行任务");
break;
case 2:
log.info("分片3:执行任务");
break;
}
}
}
================================================
FILE: 2.x/chapter7-3/src/main/resources/application.properties
================================================
elasticjob.reg-center.server-lists=localhost:2181
elasticjob.reg-center.namespace=didispace
elasticjob.jobs.my-sharding-job.elastic-job-class=com.didispace.chapter73.MyShardingJob
elasticjob.jobs.my-sharding-job.cron=0/5 * * * * ?
elasticjob.jobs.my-sharding-job.sharding-total-count=3
================================================
FILE: 2.x/chapter7-4/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.5.1
com.didispace
chapter7-4
0.0.1-SNAPSHOT
Elastic Job的错误处理策略
1.8
org.apache.shardingsphere.elasticjob
elasticjob-lite-spring-boot-starter
3.0.0
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter7-4/src/main/java/com/didispace/chapter74/Chapter74Application.java
================================================
package com.didispace.chapter74;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Chapter74Application {
public static void main(String[] args) {
SpringApplication.run(Chapter74Application.class, args);
}
}
================================================
FILE: 2.x/chapter7-4/src/main/java/com/didispace/chapter74/MySimpleJob.java
================================================
package com.didispace.chapter74;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.elasticjob.api.ShardingContext;
import org.apache.shardingsphere.elasticjob.simple.job.SimpleJob;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class MySimpleJob implements SimpleJob {
@Override
public void execute(ShardingContext context) {
log.info("MySimpleJob start : didispace.com {}", System.currentTimeMillis());
}
}
================================================
FILE: 2.x/chapter7-4/src/main/resources/application.properties
================================================
spring.application.name=chapter74
elasticjob.reg-center.server-lists=localhost:2181
elasticjob.reg-center.namespace=${spring.application.name}
elasticjob.jobs.my-simple-job.elastic-job-class=com.didispace.chapter74.MySimpleJob
elasticjob.jobs.my-simple-job.cron=0/5 * * * * ?
elasticjob.jobs.my-simple-job.sharding-total-count=1
================================================
FILE: 2.x/chapter7-5/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.5.1
com.didispace
chapter7-5
0.0.1-SNAPSHOT
使用@Async实现异步任务
1.8
org.springframework.boot
spring-boot-starter-web
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter7-5/src/main/java/com/didispace/chapter75/AsyncTasks.java
================================================
package com.didispace.chapter75;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
@Slf4j
@Component
public class AsyncTasks {
public static Random random = new Random();
@Async
public CompletableFuture doTaskOne() throws Exception {
log.info("开始做任务一");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
log.info("完成任务一,耗时:" + (end - start) + "毫秒");
return CompletableFuture.completedFuture("任务一完成");
}
@Async
public CompletableFuture doTaskTwo() throws Exception {
log.info("开始做任务二");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
log.info("完成任务二,耗时:" + (end - start) + "毫秒");
return CompletableFuture.completedFuture("任务二完成");
}
@Async
public CompletableFuture doTaskThree() throws Exception {
log.info("开始做任务三");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
log.info("完成任务三,耗时:" + (end - start) + "毫秒");
return CompletableFuture.completedFuture("任务三完成");
}
}
================================================
FILE: 2.x/chapter7-5/src/main/java/com/didispace/chapter75/Chapter75Application.java
================================================
package com.didispace.chapter75;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@EnableAsync
@SpringBootApplication
public class Chapter75Application {
public static void main(String[] args) {
SpringApplication.run(Chapter75Application.class, args);
}
}
================================================
FILE: 2.x/chapter7-5/src/main/resources/application.properties
================================================
================================================
FILE: 2.x/chapter7-5/src/test/java/com/didispace/chapter75/Chapter75ApplicationTests.java
================================================
package com.didispace.chapter75;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
@Slf4j
@SpringBootTest
public class Chapter75ApplicationTests {
@Autowired
private AsyncTasks asyncTasks;
@Test
public void test() throws Exception {
long start = System.currentTimeMillis();
CompletableFuture task1 = asyncTasks.doTaskOne();
CompletableFuture task2 = asyncTasks.doTaskTwo();
CompletableFuture task3 = asyncTasks.doTaskThree();
CompletableFuture.allOf(task1, task2, task3).join();
long end = System.currentTimeMillis();
log.info("任务全部完成,总耗时:" + (end - start) + "毫秒");
}
}
================================================
FILE: 2.x/chapter7-6/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.5.1
com.didispace
chapter7-6
0.0.1-SNAPSHOT
@Async异步任务的线程池配置
1.8
org.springframework.boot
spring-boot-starter-web
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter7-6/src/main/java/com/didispace/chapter76/AsyncTasks.java
================================================
package com.didispace.chapter76;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
@Slf4j
@Component
public class AsyncTasks {
public static Random random = new Random();
@Async
public CompletableFuture doTaskOne() throws Exception {
log.info("开始做任务一");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
log.info("完成任务一,耗时:" + (end - start) + "毫秒");
return CompletableFuture.completedFuture("任务一完成");
}
@Async
public CompletableFuture doTaskTwo() throws Exception {
log.info("开始做任务二");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
log.info("完成任务二,耗时:" + (end - start) + "毫秒");
return CompletableFuture.completedFuture("任务二完成");
}
@Async
public CompletableFuture doTaskThree() throws Exception {
log.info("开始做任务三");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
log.info("完成任务三,耗时:" + (end - start) + "毫秒");
return CompletableFuture.completedFuture("任务三完成");
}
}
================================================
FILE: 2.x/chapter7-6/src/main/java/com/didispace/chapter76/Chapter76Application.java
================================================
package com.didispace.chapter76;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@EnableAsync
@SpringBootApplication
public class Chapter76Application {
public static void main(String[] args) {
SpringApplication.run(Chapter76Application.class, args);
}
}
================================================
FILE: 2.x/chapter7-6/src/main/resources/application.properties
================================================
spring.task.execution.pool.core-size=2
spring.task.execution.pool.max-size=5
spring.task.execution.pool.queue-capacity=10
spring.task.execution.pool.keep-alive=60s
spring.task.execution.pool.allow-core-thread-timeout=true
spring.task.execution.thread-name-prefix=task-
spring.task.execution.shutdown.await-termination=false
spring.task.execution.shutdown.await-termination-period=30s
================================================
FILE: 2.x/chapter7-6/src/test/java/com/didispace/chapter76/Chapter76ApplicationTests.java
================================================
package com.didispace.chapter76;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.concurrent.CompletableFuture;
@Slf4j
@SpringBootTest
public class Chapter76ApplicationTests {
@Autowired
private AsyncTasks asyncTasks;
@Test
public void test1() throws Exception {
long start = System.currentTimeMillis();
CompletableFuture task1 = asyncTasks.doTaskOne();
CompletableFuture task2 = asyncTasks.doTaskTwo();
CompletableFuture task3 = asyncTasks.doTaskThree();
CompletableFuture.allOf(task1, task2, task3).join();
long end = System.currentTimeMillis();
log.info("任务全部完成,总耗时:" + (end - start) + "毫秒");
}
}
================================================
FILE: 2.x/chapter7-7/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.5.1
com.didispace
chapter7-7
0.0.1-SNAPSHOT
如何隔离@Async异步任务的线程池
1.8
org.springframework.boot
spring-boot-starter-web
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter7-7/src/main/java/com/didispace/chapter77/AsyncTasks.java
================================================
package com.didispace.chapter77;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
@Slf4j
@Component
public class AsyncTasks {
public static Random random = new Random();
@Async("taskExecutor1")
public CompletableFuture doTaskOne(String taskNo) throws Exception {
log.info("开始任务:{}", taskNo);
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
log.info("完成任务:{},耗时:{} 毫秒", taskNo, end - start);
return CompletableFuture.completedFuture("任务完成");
}
@Async("taskExecutor2")
public CompletableFuture doTaskTwo(String taskNo) throws Exception {
log.info("开始任务:{}", taskNo);
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
log.info("完成任务:{},耗时:{} 毫秒", taskNo, end - start);
return CompletableFuture.completedFuture("任务完成");
}
}
================================================
FILE: 2.x/chapter7-7/src/main/java/com/didispace/chapter77/Chapter77Application.java
================================================
package com.didispace.chapter77;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
@EnableAsync
@SpringBootApplication
public class Chapter77Application {
public static void main(String[] args) {
SpringApplication.run(Chapter77Application.class, args);
}
@EnableAsync
@Configuration
class TaskPoolConfig {
@Bean
public Executor taskExecutor1() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(10);
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("executor-1-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
@Bean
public Executor taskExecutor2() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(10);
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("executor-2-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
}
}
================================================
FILE: 2.x/chapter7-7/src/main/resources/application.properties
================================================
================================================
FILE: 2.x/chapter7-7/src/test/java/com/didispace/chapter77/Chapter77ApplicationTests.java
================================================
package com.didispace.chapter77;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
@Slf4j
@SpringBootTest
public class Chapter77ApplicationTests {
@Autowired
private AsyncTasks asyncTasks;
@Test
public void test() throws Exception {
long start = System.currentTimeMillis();
// 线程池1
CompletableFuture task1 = asyncTasks.doTaskOne("1");
CompletableFuture task2 = asyncTasks.doTaskOne("2");
CompletableFuture task3 = asyncTasks.doTaskOne("3");
// 线程池2
CompletableFuture task4 = asyncTasks.doTaskTwo("4");
CompletableFuture task5 = asyncTasks.doTaskTwo("5");
CompletableFuture task6 = asyncTasks.doTaskTwo("6");
// 一起执行
CompletableFuture.allOf(task1, task2, task3, task4, task5, task6).join();
long end = System.currentTimeMillis();
log.info("任务全部完成,总耗时:" + (end - start) + "毫秒");
}
}
================================================
FILE: 2.x/chapter7-8/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.5.1
com.didispace
chapter7-8
0.0.1-SNAPSHOT
为@Async异步任务线程池配置拒绝策略
1.8
org.springframework.boot
spring-boot-starter-web
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
================================================
FILE: 2.x/chapter7-8/src/main/java/com/didispace/chapter78/AsyncTasks.java
================================================
package com.didispace.chapter78;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
@Slf4j
@Component
public class AsyncTasks {
public static Random random = new Random();
@Async("taskExecutor1")
public CompletableFuture doTaskOne(String taskNo) throws Exception {
log.info("开始任务:{}", taskNo);
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
log.info("完成任务:{},耗时:{} 毫秒", taskNo, end - start);
return CompletableFuture.completedFuture("任务完成");
}
}
================================================
FILE: 2.x/chapter7-8/src/main/java/com/didispace/chapter78/Chapter78Application.java
================================================
package com.didispace.chapter78;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
@EnableAsync
@SpringBootApplication
public class Chapter78Application {
public static void main(String[] args) {
SpringApplication.run(Chapter78Application.class, args);
}
@EnableAsync
@Configuration
class TaskPoolConfig {
@Bean
public Executor taskExecutor1() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(2);
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("executor-1-");
/**配置拒绝策略**/
// AbortPolicy策略:默认策略,如果线程池队列满了丢掉这个任务并且抛出RejectedExecutionException异常。
// executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
// DiscardPolicy策略:如果线程池队列满了,会直接丢掉这个任务并且不会有任何异常。
// executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
// DiscardOldestPolicy策略:如果队列满了,会将最早进入队列的任务删掉腾出空间,再尝试加入队列。
// executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
// CallerRunsPolicy策略:如果添加到线程池失败,那么主线程会自己去执行该任务,不会等待线程池中的线程去执行。
// executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 自定义策略
// executor.setRejectedExecutionHandler(new RejectedExecutionHandler() {
// @Override
// public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
//
// }
// });
return executor;
}
}
}
================================================
FILE: 2.x/chapter7-8/src/main/resources/application.properties
================================================
================================================
FILE: 2.x/chapter7-8/src/test/java/com/didispace/chapter78/Chapter78ApplicationTests.java
================================================
package com.didispace.chapter78;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
@Slf4j
@SpringBootTest
public class Chapter78ApplicationTests {
@Autowired
private AsyncTasks asyncTasks;
@Test
public void test() throws Exception {
// 线程池配置:core-2,max-2,queue=2,可以容纳4个任务提交
long start = System.currentTimeMillis();
// 线程池1
CompletableFuture task1 = asyncTasks.doTaskOne("1");
CompletableFuture task2 = asyncTasks.doTaskOne("2");
CompletableFuture task3 = asyncTasks.doTaskOne("3");
CompletableFuture task4 = asyncTasks.doTaskOne("4");
// 一起执行
CompletableFuture.allOf(task1, task2, task3, task4).join();
long end = System.currentTimeMillis();
log.info("任务全部完成,总耗时:" + (end - start) + "毫秒");
}
@Test
public void test2() throws Exception {
// 线程池配置:core-2,max-2,queue=2,同时有5个任务,出现下面异常:
// org.springframework.core.task.TaskRejectedException: Executor [java.util.concurrent.ThreadPoolExecutor@59901c4d[Running, pool size = 2,
// active threads = 0, queued tasks = 2, completed tasks = 4]] did not accept task: java.util.concurrent.CompletableFuture$AsyncSupply@408e96d9
long start = System.currentTimeMillis();
// 线程池1
CompletableFuture task1 = asyncTasks.doTaskOne("1");
CompletableFuture task2 = asyncTasks.doTaskOne("2");
CompletableFuture task3 = asyncTasks.doTaskOne("3");
CompletableFuture task4 = asyncTasks.doTaskOne("4");
CompletableFuture task5 = asyncTasks.doTaskOne("5");
// 一起执行
CompletableFuture.allOf(task1, task2, task3, task4, task5).join();
long end = System.currentTimeMillis();
log.info("任务全部完成,总耗时:" + (end - start) + "毫秒");
}
}
================================================
FILE: 2.x/chapter8-1/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.5.1
com.didispace
chapter8-1
0.0.1-SNAPSHOT
默认日志管理与Logback配置详解
UTF-8
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-maven-plugin
true
================================================
FILE: 2.x/chapter8-1/src/main/java/com/didispace/chapter81/Chapter81Application.java
================================================
package com.didispace.chapter81;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author 程序猿DD
* @version 1.0.0
* @blog https://blog.didispace.com
*/
@Slf4j
@SpringBootApplication
public class Chapter81Application {
public static void main(String[] args) {
SpringApplication.run(Chapter81Application.class, args);
log.error("Hello World");
log.warn("Hello World");
log.info("Hello World");
log.debug("Hello World");
log.trace("Hello World");
}
}
================================================
FILE: 2.x/chapter8-1/src/main/resources/application.properties
================================================
debug=true
spring.output.ansi.enabled=detect
logging.file.name=run.log
logging.file.path=./
logging.level.com.didispace=debug
logging.logback.rollingpolicy.clean-history-on-start=false
logging.logback.rollingpolicy.file-name-pattern=
logging.logback.rollingpolicy.max-history=7
logging.logback.rollingpolicy.max-file-size=10MB
logging.logback.rollingpolicy.total-size-cap=0B
================================================
FILE: 2.x/chapter8-2/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.6.1
com.didispace
chapter8-2
0.0.1-SNAPSHOT
使用log4j2记录日志
UTF-8
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-logging
org.springframework.boot
spring-boot-starter-log4j2
org.springframework.boot
spring-boot-starter-test
test
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-maven-plugin
true
================================================
FILE: 2.x/chapter8-2/src/main/java/com/didispace/chapter82/Chapter82Application.java
================================================
package com.didispace.chapter82;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author 程序猿DD
* @version 1.0.0
* @blog https://blog.didispace.com
*/
@Slf4j
@SpringBootApplication
public class Chapter82Application {
public static void main(String[] args) {
SpringApplication.run(Chapter82Application.class, args);
log.error("Hello World");
log.warn("Hello World");
log.info("Hello World");
log.debug("Hello World");
log.trace("Hello World");
}
}
================================================
FILE: 2.x/chapter8-2/src/main/resources/application.properties
================================================
logging.config=classpath:log4j2.xml
================================================
FILE: 2.x/chapter8-2/src/main/resources/log4j2.xml
================================================
================================================
FILE: 2.x/chapter8-3/pom.xml
================================================
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.6.1
com.didispace
chapter8-3
0.0.1-SNAPSHOT
使用tinylog记录日志
UTF-8
1.8
2.4.1
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-logging
org.tinylog
tinylog-api
${tinylog.version}
org.tinylog
tinylog-impl
${tinylog.version}
org.tinylog
slf4j-tinylog
${tinylog.version}
org.tinylog
jcl-tinylog
${tinylog.version}
org.tinylog
log4j1.2-api
${tinylog.version}
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-maven-plugin
true
================================================
FILE: 2.x/chapter8-3/src/main/java/com/didispace/chapter83/Chapter83Application.java
================================================
package com.didispace.chapter83;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author 程序猿DD
* @version 1.0.0
* @blog https://blog.didispace.com
*/
@Slf4j
@SpringBootApplication
public class Chapter83Application {
public static void main(String[] args) {
SpringApplication.run(Chapter83Application.class, args);
log.error("Hello World");
log.warn("Hello World");
log.info("Hello World");
log.debug("Hello World");
log.trace("Hello World");
}
}
================================================
FILE: 2.x/chapter8-3/src/main/resources/application.properties
================================================
================================================
FILE: 2.x/chapter8-3/src/main/resources/tinylog.properties
================================================
writer=console
writer.format={date: HH:mm:ss.SSS} {level}: {message}
================================================
FILE: 2.x/pom.xml
================================================
4.0.0
com.didispace
2.x
2.0-SNAPSHOT
pom
全网Star最多的Spring Boot基础教程
chapter1-1
chapter1-2
chapter1-3
chapter1-4
chapter1-5
chapter2-1
chapter2-2
chapter2-3
chapter2-4
chapter2-5
chapter2-6
chapter2-7
chapter2-8
chapter3-1
chapter3-2
chapter3-3
chapter3-4
chapter3-5
chapter3-6
chapter3-7
chapter3-8
chapter3-9
chapter3-10
chapter3-11
chapter3-12
chapter3-13
chapter4-1
chapter4-2
chapter4-3
chapter4-4
chapter4-5
chapter5-1
chapter5-2
chapter5-3
chapter5-4
chapter5-5
chapter6-1
chapter6-2
chapter6-3
chapter6-4
chapter7-1
chapter7-2
chapter7-3
chapter7-4
chapter7-5
chapter7-6
chapter7-7
chapter7-8
chapter8-1
chapter8-2
chapter8-3
================================================
FILE: README.md
================================================
# Spring Boot基础教程
**专题目标**:打造全网内容最全,比收费教程更好的Spring Boot免费教程!
**如何支持**:
1. 关注我的公众号”**程序猿DD**“
2. 点个`Star`并`Follow`我
3. 把该仓库分享给更多的朋友
**加入社群**:如果你正在学习Spring Boot,不妨加入我们的[Spring技术交流群](https://blog.didispace.com/join-group-spring/index.html) ,一起成长
**Spring社区**:如果您在学习过程中碰到问题,可以访问[SpringForAll社区](http://spring4all.com),描述你的问题,我们会尽快给你答复。当然,如果你想分享你的学习经验,也可以在这里发表你的文章
## 教程目录
该教程自2016年连载至今,因内容较多,经历过多个版本的迭代。
为方便查看学习,这里重新做了整理,根据1.x版本和2.x版本做了区分汇总,后续还会继续跟进3.x版本!
可以通过下面的链接,进入具体版本的教程目录:
- [Spring Boot 2.x](./2.x)
- [Spring Boot 1.x](./1.x)
> **关注公众号:“程序猿DD”**,领取我整理的免费学习资料。
## 推荐内容
- [我的博客](http://blog.didispace.com):分享平时学习和实践过的技术内容
- [Spring Boot教程](https://blog.didispace.com/spring-boot-learning-2x/):全网Star最多的免费Spring Boot基础教程
- [Spring Cloud教程](https://blog.didispace.com/spring-cloud-learning/):全网最早最全的免费Spring Cloud基础教程
- [知识星球](https://t.xiaomiquan.com/zfEiY3v):聊聊技术人的斜杠生活
**关注公众号,获得更多技术资讯**
================================================
FILE: README_zh.md
================================================
# Spring Boot基础教程
**专题目标**:打造全网内容最全,比收费教程更好的Spring Boot免费教程!
**如何支持**:
1. 关注我的公众号”**程序猿DD**“
2. 点个`Star`并`Follow`我
3. 把该仓库分享给更多的朋友
**加入社群**:如果你正在学习Spring Boot,不妨加入我们的[Spring技术交流群](https://blog.didispace.com/join-group-spring/index.html) ,一起成长
**Spring社区**:如果您在学习过程中碰到问题,可以访问[SpringForAll社区](http://spring4all.com),描述你的问题,我们会尽快给你答复。当然,如果你想分享你的学习经验,也可以在这里发表你的文章
## 教程目录
该教程自2016年连载至今,因内容较多,经历过多个版本的迭代。
为方便查看学习,这里重新做了整理,根据1.x版本和2.x版本做了区分汇总。
可以通过下面的链接,进入具体版本的教程目录:
- [Spring Boot 2.x](./2.x)
- [Spring Boot 1.x](./1.x)
> **关注公众号:“程序猿DD”**,领取我整理的免费学习资料。
## 推荐内容
- [我的博客](http://blog.didispace.com):分享平时学习和实践过的技术内容
- [Spring Boot教程](https://blog.didispace.com/spring-boot-learning-2x/):全网Star最多的免费Spring Boot基础教程
- [Spring Cloud教程](https://blog.didispace.com/spring-cloud-learning/):全网最早最全的免费Spring Cloud基础教程
- [知识星球](https://t.xiaomiquan.com/zfEiY3v):聊聊技术人的斜杠生活
**关注公众号,获得更多技术资讯**
================================================
FILE: pom.xml
================================================
4.0.0
com.didispace
SpringBoot-Learning
1.0-SNAPSHOT
pom
2.x