一. Spring Boot数据库配置
单数据源的配置:DAO --> jdbcTemplete --> DataSource
1.application.yml 增加DataSource的配置。
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/demo?charset=utf8
username: admin
password: admin
2.写了一个DAO,并且在这个DAO里@autowired了一个jdbcTemplete .
3.使用 jdbcTemplete 来进行操作。
@Repository
public class AccountDAOImpl implements AccountDAO {
private final JdbcTemplate jdbcTemplate;
private final NamedParameterJdbcTemplate namedJdbcTemplate;
@Autowired
public AccountDAOImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
this.namedJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
}
@Override
public void insert(Account account) {
String sql = "INSERT INTO account(username, password, nickname) VALUES(?, ?, ?)";
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
PreparedStatement stmt = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
stmt.setString(1, account.getUsername());
stmt.setString(2, account.getPassword());
stmt.setString(3, account.getNickname());
return stmt;
}
}, keyHolder);
long id = keyHolder.getKey().longValue();
account.setId(id);
}
}
二. 多数据源的步骤:
1.application.yml 增加配置,注意区分。spring.datasource.db1 spring.datasource.db2 (url --> jdbc-url)
datasource:
db1:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/demo?charset=utf8
username: admin
password: admin
db2:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/demo2?charset=utf8
username: admin
password: admin
2.@Configuration 的类,里边声明两个 DataSource 和 两个 jdbcTemplete。(@Primary,默认数据源)
package com.example.demo.springboot.config;
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 DataSourceConfig {
@Bean(name = "db1")
@ConfigurationProperties("spring.datasource.db1")
@Primary
public DataSource dataSource1() {
return DataSourceBuilder.create().build();
}
@Bean(name = "db2")
@ConfigurationProperties("spring.datasource.db2")
public DataSource dataSource2() {
return DataSourceBuilder.create().build();
}
@Bean(name = "jdbcTemplete1")
@Primary
public JdbcTemplate jdbcTemplate1(@Qualifier("db1") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Bean(name = "jdbcTemplete2")
public JdbcTemplate jdbcTemplate2(@Qualifier("db2") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
3.使用 @Qualifier("db2") 来指定我们使用哪个,如果不指定的话,用的就是 @Primary。
三. Spring Boot 数据库支持(增删改查)
1.pom.xml里增加 数据库访问的相关依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
2.application.yml 或 application.properties 增加数据源的配置。
3.代码实现,见上面AccountDAOImpl的源码
四. 事务的支持
一种基于AOP的技术。
事务相关逻辑源码见 TransactionAspectSupport.java
事务的操作有三种:
开事务。 -- 每个操作(方法)都开事务。
正常:事务提交。-- 正常返回,没有exception。
异常:事务回滚。-- 有exception,认为是有问题。需要回滚。
@Transactional 注解。Spring 帮我们完成 上面描述的这些操作。
@Override
@Transactional(rollbackFor = NullPointerException.class, noRollbackFor = RuntimeException.class)
public void insert2(Account account) {
SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(jdbcTemplate);
simpleJdbcInsert.withTableName("account").usingGeneratedKeyColumns("id");
BeanPropertySqlParameterSource parameterSource = new BeanPropertySqlParameterSource(account);
Number key = simpleJdbcInsert.executeAndReturnKey(parameterSource);
account.setId(key.longValue());
if ("张三".equals(account.getNickname())) {
//throw new RuntimeException("张三");
throw new NullPointerException("张三");
}
}
问题1:哪些异常需要回滚,哪些异常不需要回滚。
rollbackFor()
noRollbackFor()
问题2: 事务的影响范围。如果几个方法都有@Transactional ,那么他们是在一个事务里吗?
propagation 默认是REQUIRED 在枚举类Propagation中
问题3:会话级别 的 事务隔离级别。
isolation 默认是default。