作为一名长期奋战在一线的Java开发者,我深知SpringBoot与MySQL的组合在企业级应用开发中的重要性。这篇文章将带你深入理解SpringBoot连接MySQL的完整流程,从基础配置到事务机制,再到常见问题排查。不同于简单的配置教程,我会着重分享那些官方文档不会告诉你,但在实际项目中一定会遇到的"坑"。
在开始之前,确保你的开发环境满足以下要求:
注意:MySQL 8.x与5.x在驱动类、连接参数等方面有较大变化,这也是很多开发者升级后遇到问题的原因。
在pom.xml中添加以下依赖:
xml复制<dependencies>
<!-- Spring JDBC Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
<scope>runtime</scope>
</dependency>
</dependencies>
关键点解析:
spring-boot-starter-jdbc会自动引入Spring JDBC核心组件和HikariCP连接池mysql-connector-j而非老版本的mysql-connector-java推荐使用YAML格式的配置文件,结构更清晰:
yaml复制spring:
datasource:
url: jdbc:mysql://localhost:3306/your_database?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8
username: your_username
password: your_password
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
maximum-pool-size: 10
minimum-idle: 5
connection-timeout: 30000
配置参数解析:
useSSL=false:开发环境禁用SSL连接serverTimezone=Asia/Shanghai:解决MySQL 8时区问题characterEncoding=utf8:确保中文支持driver-class-name:MySQL 8必须使用cj.jdbc.DriverSpringBoot启动时会自动完成以下操作:
如果需要自定义DataSource,可以这样配置:
java复制@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
java复制@Repository
public class UserRepository {
@Autowired
private JdbcTemplate jdbcTemplate;
public List<User> findAll() {
String sql = "SELECT * FROM users";
return jdbcTemplate.query(sql, (rs, rowNum) -> {
User user = new User();
user.setId(rs.getLong("id"));
user.setName(rs.getString("name"));
user.setEmail(rs.getString("email"));
return user;
});
}
public int insert(User user) {
String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
return jdbcTemplate.update(sql, user.getName(), user.getEmail());
}
}
java复制public int[] batchInsert(List<User> users) {
String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
return jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
User user = users.get(i);
ps.setString(1, user.getName());
ps.setString(2, user.getEmail());
}
@Override
public int getBatchSize() {
return users.size();
}
});
}
java复制@Service
@Transactional
public class UserService {
@Autowired
private UserRepository userRepository;
public void createUser(User user) {
userRepository.insert(user);
// 其他业务逻辑...
}
}
java复制@Transactional(propagation = Propagation.REQUIRED)
public void transactionalMethod() {
// 业务逻辑...
}
常用传播行为:
yaml复制spring:
datasource:
hikari:
maximum-pool-size: 20
minimum-idle: 10
idle-timeout: 30000
max-lifetime: 1800000
connection-timeout: 30000
connection-test-query: SELECT 1
建议在开发环境开启SQL日志:
yaml复制logging:
level:
org.springframework.jdbc.core.JdbcTemplate: DEBUG
org.springframework.jdbc.core.StatementCreatorUtils: TRACE
java复制@Repository
public class UserRepository {
@Autowired
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
public List<User> findByName(String name) {
String sql = "SELECT * FROM users WHERE name = :name";
Map<String, Object> params = new HashMap<>();
params.put("name", name);
return namedParameterJdbcTemplate.query(sql, params, new UserRowMapper());
}
}
java复制@Configuration
public class MultiDataSourceConfig {
@Bean
@Primary
@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 dataSource) {
return new JdbcTemplate(dataSource);
}
@Bean
public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondaryDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
xml复制<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
java复制public interface UserRepository extends CrudRepository<User, Long> {
List<User> findByName(String name);
}
Communications link failure
Access denied for user
yaml复制url: jdbc:mysql://localhost:3306/db?serverTimezone=Asia/Shanghai
yaml复制url: jdbc:mysql://localhost:3306/db?characterEncoding=utf8
在实际项目开发中,我总结了以下几点经验:
最后,建议在项目初期就建立完善的数据库访问规范,包括命名约定、事务使用原则等,这将大大减少后期维护成本。