Idea创建Maven多模块+Spring-boot jdbctemplate的使用

本文详细介绍了如何在Spring Boot项目中整合MySQL,包括项目搭建、数据库连接、实体类定义、DAO层实现、Service层设计及控制器编写,最终实现CRUD操作。

1、在打开Idea后选择Create New Project,如下图所示:

2、选择Maven,然后不要选Create from archetype,直接点击Next,如下图所示:

3、输入GroupId和ArtifactId,然后点击Next,如下图所示:

4、输入工程名称以及路径,然后点击Finish,如下图所示:

5、创建好之后如下图所示的目录结构:

6、右键单击src,然后在弹出的菜单中选择Delete,将其删除,如下图所示:

7、然后在项目名称上右键单击,依次选择New->Module,如下图所示:

8、然后选择Maven,直接单击Next,如下图所示:

9、然后只需要输入ArtifactId即可,如下图所示:

10、输入模块的名称,如下图所示:

11、如果出现Maven projects need to be imported,选择Enable Auto-Import表示自动导入,如下图所示:

12、在根项目中的pom.xml添加parent,然后所有的子模块都可以使用此parent中的jar,如添加:

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
    </parent>

13、在根项目中添加dependencies和dependency,所有子模块都可以使用此依赖,如:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>2.1.0.RELEASE</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

14、在mysql模块中的pom.xml添加连接mysql相应的jar包,如:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.13</version>
        </dependency>
    </dependencies>

15、新建一个demo数据库,如下图所示:

16、创建一个tb_user表,如:

CREATE TABLE `tb_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `username` varchar(50) NOT NULL COMMENT '用户名',
  `age` int(11) NOT NULL COMMENT '年龄',
  `ctm` datetime NOT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

17、插入相应的数据,如:

INSERT INTO `demo`.`tb_user` (`username`, `age`, `ctm`) VALUES('张三', '18', NOW()) ;
INSERT INTO `demo`.`tb_user` (`username`, `age`, `ctm`) VALUES('李四', '20', NOW()) ;
INSERT INTO `demo`.`tb_user` (`username`, `age`, `ctm`) VALUES('王五', '19', NOW()) ;

18、最后结果如下图所示:

19、在mysql模块中创建相应的包,结构如下图所示:

20、在resources创建一个application.yml文件,配置连接mysql的字符串(注意:每一项的冒号后都要有一个空格,否则会出错),如下图所示:

21、在bean中创建一个User类,此类对应数据库表tb_user,并且每个变量对应一个字段,如:

package com.win.mysql.bean;

import java.util.Date;

public class User {
    private int id;
    private String username;
    private int age;
    private Date ctm;
    public User() {
    }
    public User(String username, int age) {
        this.username = username;
        this.age = age;
        this.ctm = new Date();
    }
    public void setUsername(String username){
        this.username=username;
    }
    public void setAge(int age){
        this.age=age;
    }
    public void setCtm(Date ctm){
        this.ctm=ctm;
    }
    public int getId(){
        return this.id;
    }
    public String getUsername(){
        return this.username;
    }
    public int getAge(){
        return this.age;
    }
    public Date getCtm(){
        return this.ctm;
    }
}

22、创建一个UserDao接口,如:

package com.win.mysql.dao;

import com.win.mysql.bean.User;

import java.util.List;

public interface UserDao {
    public User getUserById(Integer id);
    public List<User> getUserList();
    public int add(User user);
    public int update(Integer id, User user);
    public int delete(Integer id);
}

23、在dao包中创建一个impl包,并创建一个UserDaoImpl类用来实现UserDao接口,此类中有JdbcTemplate,Spring-boot会自动读取配置文件中的信息到JdbcTemplate中,然后通过JdbcTemplate就可以进行RCUD了,如:

package com.win.mysql.dao.impl;

import com.win.mysql.bean.User;
import com.win.mysql.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.Date;
import java.util.List;
@Repository
public class UserDaoImpl implements UserDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Override
    public User getUserById(Integer id){
        List<User> list = jdbcTemplate.query("select * from tb_user where id = ?", new Object[]{id}, new BeanPropertyRowMapper(User.class));
        if(list!=null && list.size()>0){
            return list.get(0);
        }else{
            return null;
        }
    }
    @Override
    public List<User> getUserList(){
        List<User> list = jdbcTemplate.query("select * from tb_user", new Object[]{}, new BeanPropertyRowMapper(User.class));
        if(list!=null && list.size()>0){
            return list;
        }else{
            return null;
        }
    }
    @Override
    public int add(User user){
        return jdbcTemplate.update("insert into tb_user(username, age, ctm) values(?, ?, ?)",
                user.getUsername(),user.getAge(), new Date());
    }
    @Override
    public int update(Integer id, User user){
        return jdbcTemplate.update("UPDATE tb_user SET username = ? , age = ? WHERE id=?",
                user.getUsername(),user.getAge(), id);
    }
    @Override
    public int delete(Integer id){
        return jdbcTemplate.update("DELETE from tb_user where id = ? ",id);
    }
}

24、在service包中创建一个UserService接口,如:

package com.win.mysql.service;

import com.win.mysql.bean.User;
import java.util.List;
public interface UserService {
    public User getUserById(Integer id);
    public List<User> getUserList();
    public int add(User user);
    public int update(Integer id, User user);
    public int delete(Integer id);
}

25、在service包中创建一个impl包,并创建一个UserServiceImpl类用来实现UserService接口,如:

package com.win.mysql.service.impl;

import com.win.mysql.bean.User;
import com.win.mysql.dao.UserDao;
import com.win.mysql.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
    @Override
    public User getUserById(Integer id){
        return userDao.getUserById(id);
    }
    @Override
    public List<User> getUserList(){
        return userDao.getUserList();
    }
    @Override
    public int add(User user){
        return userDao.add(user);
    }
    @Override
    public int update(Integer id, User user){
        return userDao.update(id, user);
    }
    @Override
    public int delete(Integer id){
        return userDao.delete(id);
    }
}

26、在bean包中创建一个JsonResult类,如:

package com.win.mysql.bean;

public class JsonResult {
    private String status = null;
    private Object result = null;
    public JsonResult status(String status) {
        this.status = status;
        return this;
    }
    public void setResult(Object user){
        this.result=user;
    }
    public Object getResult(){
        return this.result;
    }
    public void setStatus(String status){
        this.status=status;
    }
    public String getStatus(){
        return this.status;
    }
}

27、在web包中创建一个控制类UserController,通过http请求的都在此类中,如:

package com.win.mysql.web;

import com.win.mysql.bean.JsonResult;
import com.win.mysql.bean.User;
import com.win.mysql.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class UserController {
    @Autowired
    private UserService userService;

    /**
     * 根据ID查询用户
     * @param id
     * @return
     */
    @RequestMapping(value = "user/{id}", method = RequestMethod.GET)
    public ResponseEntity<JsonResult> getUserById (@PathVariable(value = "id") Integer id){
        JsonResult r = new JsonResult();
        try {
            User user = userService.getUserById(id);
            r.setResult(user);
            r.setStatus("ok");
        } catch (Exception e) {
            r.setResult(e.getClass().getName() + ":" + e.getMessage());
            r.setStatus("error");
            e.printStackTrace();
        }
        return ResponseEntity.ok(r);
    }

    /**
     * 查询用户列表
     * @return
     */
    @RequestMapping(value = "users", method = RequestMethod.GET)
    public ResponseEntity<JsonResult> getUserList (){
        JsonResult r = new JsonResult();
        try {
            List<User> users = userService.getUserList();
            r.setResult(users);
            r.setStatus("ok");
        } catch (Exception e) {
            r.setResult(e.getClass().getName() + ":" + e.getMessage());
            r.setStatus("error");
            e.printStackTrace();
        }
        return ResponseEntity.ok(r);
    }

    /**
     * 添加用户
     * @param user
     * @return
     */
    @RequestMapping(value = "user", method = RequestMethod.POST)
    public ResponseEntity<JsonResult> add (@RequestBody User user){
        JsonResult r = new JsonResult();
        try {
            int orderId = userService.add(user);
            if (orderId < 0) {
                r.setResult(orderId);
                r.setStatus("fail");
            } else {
                r.setResult(orderId);
                r.setStatus("ok");
            }
        } catch (Exception e) {
            r.setResult(e.getClass().getName() + ":" + e.getMessage());
            r.setStatus("error");

            e.printStackTrace();
        }
        return ResponseEntity.ok(r);
    }

    /**
     * 根据id删除用户
     * @param id
     * @return
     */
    @RequestMapping(value = "user/{id}", method = RequestMethod.DELETE)
    public ResponseEntity<JsonResult> delete (@PathVariable(value = "id") Integer id){
        JsonResult r = new JsonResult();
        try {
            int ret = userService.delete(id);
            if (ret < 0) {
                r.setResult(ret);
                r.setStatus("fail");
            } else {
                r.setResult(ret);
                r.setStatus("ok");
            }
        } catch (Exception e) {
            r.setResult(e.getClass().getName() + ":" + e.getMessage());
            r.setStatus("error");

            e.printStackTrace();
        }
        return ResponseEntity.ok(r);
    }

    /**
     * 根据id修改用户信息
     * @param user
     * @return
     */
    @RequestMapping(value = "user/{id}", method = RequestMethod.PUT)
    public ResponseEntity<JsonResult> update (@PathVariable("id") Integer id, @RequestBody User user){
        JsonResult r = new JsonResult();
        try {
            int ret = userService.update(id, user);
            if (ret < 0) {
                r.setResult(ret);
                r.setStatus("fail");
            } else {
                r.setResult(ret);
                r.setStatus("ok");
            }
        } catch (Exception e) {
            r.setResult(e.getClass().getName() + ":" + e.getMessage());
            r.setStatus("error");

            e.printStackTrace();
        }
        return ResponseEntity.ok(r);
    }
}

28、在mysql包中创建一个spring-boot的启动类Application,如:

package com.win.mysql;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@EnableAutoConfiguration
@SpringBootApplication
public class Application {
    public static void main( String[] args )
    {
        System.out.println( "start....." );
        SpringApplication.run(Application.class, args);
    }
}

29、在启动后出现错误,如:

java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) ~[mysql-connector-java-8.0.13.jar:8.0.13]
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) ~[mysql-connector-java-8.0.13.jar:8.0.13]
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89) ~[mysql-connector-java-8.0.13.jar:8.0.13]
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63) ~[mysql-connector-java-8.0.13.jar:8.0.13]
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:73) ~[mysql-connector-java-8.0.13.jar:8.0.13]
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:76) ~[mysql-connector-java-8.0.13.jar:8.0.13]
	at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:835) ~[mysql-connector-java-8.0.13.jar:8.0.13]
	at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:455) ~[mysql-connector-java-8.0.13.jar:8.0.13]
	at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:240) ~[mysql-connector-java-8.0.13.jar:8.0.13]
	at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:207) ~[mysql-connector-java-8.0.13.jar:8.0.13]
	at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:136) ~[HikariCP-3.2.0.jar:na]
	at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:369) ~[HikariCP-3.2.0.jar:na]
	at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:198) ~[HikariCP-3.2.0.jar:na]
	at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:467) [HikariCP-3.2.0.jar:na]
	at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:541) [HikariCP-3.2.0.jar:na]
	at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115) [HikariCP-3.2.0.jar:na]
	at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) [HikariCP-3.2.0.jar:na]
	at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:151) [spring-jdbc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:115) [spring-jdbc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:78) [spring-jdbc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:319) [spring-jdbc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:356) [spring-jdbc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.boot.autoconfigure.orm.jpa.DatabaseLookup.getDatabase(DatabaseLookup.java:72) [spring-boot-autoconfigure-2.1.0.RELEASE.jar:2.1.0.RELEASE]
	at org.springframework.boot.autoconfigure.orm.jpa.JpaProperties.determineDatabase(JpaProperties.java:142) [spring-boot-autoconfigure-2.1.0.RELEASE.jar:2.1.0.RELEASE]
	at org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.jpaVendorAdapter(JpaBaseConfiguration.java:112) [spring-boot-autoconfigure-2.1.0.RELEASE.jar:2.1.0.RELEASE]
	at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration$$EnhancerBySpringCGLIB$$94d70ee3.CGLIB$jpaVendorAdapter$4(<generated>) [spring-boot-autoconfigure-2.1.0.RELEASE.jar:2.1.0.RELEASE]
	at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration$$EnhancerBySpringCGLIB$$94d70ee3$$FastClassBySpringCGLIB$$c0920c0.invoke(<generated>) [spring-boot-autoconfigure-2.1.0.RELEASE.jar:2.1.0.RELEASE]
	at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) [spring-core-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363) [spring-context-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration$$EnhancerBySpringCGLIB$$94d70ee3.jpaVendorAdapter(<generated>) [spring-boot-autoconfigure-2.1.0.RELEASE.jar:2.1.0.RELEASE]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:620) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:455) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1288) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:273) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1239) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1166) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:855) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:758) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:508) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1288) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:273) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1239) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1166) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:855) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:758) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:508) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1288) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) [spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1083) ~[spring-context-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:853) ~[spring-context-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546) ~[spring-context-5.1.2.RELEASE.jar:5.1.2.RELEASE]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
	at com.win.mysql.Application.main(Application.java:13) ~[classes/:na]
Caused by: com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_181]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_181]
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_181]
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_181]
	at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) ~[mysql-connector-java-8.0.13.jar:8.0.13]
	at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:85) ~[mysql-connector-java-8.0.13.jar:8.0.13]
	at com.mysql.cj.util.TimeUtil.getCanonicalTimezone(TimeUtil.java:132) ~[mysql-connector-java-8.0.13.jar:8.0.13]
	at com.mysql.cj.protocol.a.NativeProtocol.configureTimezone(NativeProtocol.java:2234) ~[mysql-connector-java-8.0.13.jar:8.0.13]
	at com.mysql.cj.protocol.a.NativeProtocol.initServerSession(NativeProtocol.java:2258) ~[mysql-connector-java-8.0.13.jar:8.0.13]
	at com.mysql.cj.jdbc.ConnectionImpl.initializePropsFromServer(ConnectionImpl.java:1319) ~[mysql-connector-java-8.0.13.jar:8.0.13]
	at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:966) ~[mysql-connector-java-8.0.13.jar:8.0.13]
	at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:825) ~[mysql-connector-java-8.0.13.jar:8.0.13]

30、出现此错误说明在连接mysql时的时区不对,只需要在连接串后加上?serverTimezone=UTC即可,如下图所示:

31、再次启动即可启动成功,如下图所示:

32、在浏览器中输入:http://127.0.0.1:8080/users即可输入结果,如下图所示:

33、在输出结果可以看到其中的id全部是0,这是由于在User类中缺少setId方法,只需要添加即可,如下图所示:

34、在此刷新即可正常输入,如下图所示:

35、在浏览器中输入:http://127.0.0.1:8080/user/1即可查询指定用户,如下图所示:

36、使用火狐浏览器中的RESTClient插件进行测试添加用户,选择post请求,然后输入:http://127.0.0.1:8080/user,然后添加HTTP头,输入正文,点击发送即可添加,并且有返回状态,如下图所示:

37、在此查询所有用户即可显示,如下图所示:

38、修改用户信息,选择put请求,然后输入:http://127.0.0.1:8080/user/1,输入要修改的内容,表示修改指定ID的信息,点击发送即可修改,并且有返回状态,如下图所示:

39、在此刷新可以看到已经更新了,如下图所示:

40、删除用户信息,选择DELETE请求,然后输入:http://127.0.0.1:8080/user/1,不需要输入内容,点击发送即可删除,并且有返回状态,如下图所示:

41、再次刷新显示ID为1的已经被删除,如下图所示:

 

总结:

(1)在程序启动时,在Application.java类中有一个@SpringBootApplication注解,它包含了@Configuration + @EnableAutoConfiguration + @ComponentScan三个注解,说明在启动时会自动获取配置(比如配置的数据库连接参数等)

(2)然后在去运行main,进而运行SpringApplication.run(Application.class, args);然后开始进行初始化Spring相关的信息,比如其他类的注解。

(3)当从浏览器中输入网址时,spring就会去找被@RestController的相应的类,然后进行路径解析,然后@RequestMapping来注释具体调用的是那个路径下的方法,如:@RequestMapping(value = "users", method = RequestMethod.GET),根路径为:http://127.0.0.1:8080,如果加上value,那么就会自动匹配成http://127.0.0.1:8080/users,然后在进一步判断http请求的方法,如果为:RequestMethod.GET,则会调用getUserList ();

(4)在getUserList ()方法中会有一个userService.getUserList(),此处的userService通过@Service已经实例化为了UserServiceImpl类,那么此时调用的userService.getUserList()就会调用UserServiceImpl类中的getUserList()。

(5)在UserServiceImpl类中的getUserList()方法中会调用userDao.getUserList()方法,而userDao通过@Repository已经实例化为了UserDaoImpl类,那么此时调用的userDao.getUserList()就会调用UserDaoImpl类中的getUserList()方法。

(6)在UserDaoImpl类中的getUserList()方法中通过jdbcTemplate.query("select * from tb_user", new Object[]{}, new BeanPropertyRowMapper(User.class)),对数据表进行查询,而jdbcTemplate则是在spring-boot启动时会自动配置数据库的相关连接,直接可以使用。

(7)把查询结果生成一个List,然后返回到UserController中,并构造一个JsonResult对象,然后通过ResponseEntity对象构造成一个json格式对象,然后返回到浏览器中。

 

C:\Users\Administrator\.jdks\ms-17.0.15\bin\java.exe -XX:TieredStopAtLevel=1 -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true "-Dmanagement.endpoints.jmx.exposure.include=*" "-javaagent:C:\Users\Administrator\AppData\Local\Programs\IntelliJ IDEA Ultimate 2025.1.3\lib\idea_rt.jar=64611" -Dfile.encoding=UTF-8 -classpath C:\Users\Administrator\IdeaProjects\demo\target\classes;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot-starter-web\2.6.13\spring-boot-starter-web-2.6.13.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot-starter\2.6.13\spring-boot-starter-2.6.13.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot-starter-logging\2.6.13\spring-boot-starter-logging-2.6.13.jar;D:\apache-maven-3.9.10\maven-repository\ch\qos\logback\logback-classic\1.2.11\logback-classic-1.2.11.jar;D:\apache-maven-3.9.10\maven-repository\ch\qos\logback\logback-core\1.2.11\logback-core-1.2.11.jar;D:\apache-maven-3.9.10\maven-repository\org\apache\logging\log4j\log4j-to-slf4j\2.17.2\log4j-to-slf4j-2.17.2.jar;D:\apache-maven-3.9.10\maven-repository\org\apache\logging\log4j\log4j-api\2.17.2\log4j-api-2.17.2.jar;D:\apache-maven-3.9.10\maven-repository\org\slf4j\jul-to-slf4j\1.7.36\jul-to-slf4j-1.7.36.jar;D:\apache-maven-3.9.10\maven-repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;D:\apache-maven-3.9.10\maven-repository\org\yaml\snakeyaml\1.29\snakeyaml-1.29.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot-starter-json\2.6.13\spring-boot-starter-json-2.6.13.jar;D:\apache-maven-3.9.10\maven-repository\com\fasterxml\jackson\core\jackson-databind\2.13.4.2\jackson-databind-2.13.4.2.jar;D:\apache-maven-3.9.10\maven-repository\com\fasterxml\jackson\core\jackson-annotations\2.13.4\jackson-annotations-2.13.4.jar;D:\apache-maven-3.9.10\maven-repository\com\fasterxml\jackson\core\jackson-core\2.13.4\jackson-core-2.13.4.jar;D:\apache-maven-3.9.10\maven-repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.13.4\jackson-datatype-jdk8-2.13.4.jar;D:\apache-maven-3.9.10\maven-repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.13.4\jackson-datatype-jsr310-2.13.4.jar;D:\apache-maven-3.9.10\maven-repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.13.4\jackson-module-parameter-names-2.13.4.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot-starter-tomcat\2.6.13\spring-boot-starter-tomcat-2.6.13.jar;D:\apache-maven-3.9.10\maven-repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.68\tomcat-embed-core-9.0.68.jar;D:\apache-maven-3.9.10\maven-repository\org\apache\tomcat\embed\tomcat-embed-el\9.0.68\tomcat-embed-el-9.0.68.jar;D:\apache-maven-3.9.10\maven-repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.68\tomcat-embed-websocket-9.0.68.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-web\5.3.23\spring-web-5.3.23.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-beans\5.3.23\spring-beans-5.3.23.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-webmvc\5.3.23\spring-webmvc-5.3.23.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-aop\5.3.23\spring-aop-5.3.23.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-context\5.3.23\spring-context-5.3.23.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-expression\5.3.23\spring-expression-5.3.23.jar;D:\apache-maven-3.9.10\maven-repository\org\slf4j\slf4j-api\1.7.36\slf4j-api-1.7.36.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-core\5.3.23\spring-core-5.3.23.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-jcl\5.3.23\spring-jcl-5.3.23.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot-configuration-processor\2.6.13\spring-boot-configuration-processor-2.6.13.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot-devtools\2.6.13\spring-boot-devtools-2.6.13.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot\2.6.13\spring-boot-2.6.13.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot-autoconfigure\2.6.13\spring-boot-autoconfigure-2.6.13.jar;D:\apache-maven-3.9.10\maven-repository\org\projectlombok\lombok\1.18.24\lombok-1.18.24.jar;D:\apache-maven-3.9.10\maven-repository\org\mybatis\spring\boot\mybatis-spring-boot-starter\2.2.2\mybatis-spring-boot-starter-2.2.2.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot-starter-jdbc\2.6.13\spring-boot-starter-jdbc-2.6.13.jar;D:\apache-maven-3.9.10\maven-repository\com\zaxxer\HikariCP\4.0.3\HikariCP-4.0.3.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-jdbc\5.3.23\spring-jdbc-5.3.23.jar;D:\apache-maven-3.9.10\maven-repository\org\mybatis\spring\boot\mybatis-spring-boot-autoconfigure\2.2.2\mybatis-spring-boot-autoconfigure-2.2.2.jar;D:\apache-maven-3.9.10\maven-repository\org\mybatis\mybatis\3.5.9\mybatis-3.5.9.jar;D:\apache-maven-3.9.10\maven-repository\org\mybatis\mybatis-spring\2.0.7\mybatis-spring-2.0.7.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-tx\5.3.23\spring-tx-5.3.23.jar;D:\apache-maven-3.9.10\maven-repository\com\mysql\mysql-connector-j\8.0.31\mysql-connector-j-8.0.31.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot-starter-actuator\2.6.13\spring-boot-starter-actuator-2.6.13.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot-actuator-autoconfigure\2.6.13\spring-boot-actuator-autoconfigure-2.6.13.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot-actuator\2.6.13\spring-boot-actuator-2.6.13.jar;D:\apache-maven-3.9.10\maven-repository\io\micrometer\micrometer-core\1.8.11\micrometer-core-1.8.11.jar;D:\apache-maven-3.9.10\maven-repository\org\hdrhistogram\HdrHistogram\2.1.12\HdrHistogram-2.1.12.jar;D:\apache-maven-3.9.10\maven-repository\org\latencyutils\LatencyUtils\2.0.3\LatencyUtils-2.0.3.jar com.example.demo.DemoApplication 13:56:27.056 [Thread-0] DEBUG org.springframework.boot.devtools.restart.classloader.RestartClassLoader - Created RestartClassLoader org.springframework.boot.devtools.restart.classloader.RestartClassLoader@1cb8876e . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.6.13) 2025-07-11 13:56:27.326 INFO 23028 --- [ restartedMain] com.example.demo.DemoApplication : Starting DemoApplication using Java 17.0.15 on 闫晓强 with PID 23028 (C:\Users\Administrator\IdeaProjects\demo\target\classes started by Administrator in C:\Users\Administrator\IdeaProjects\demo) 2025-07-11 13:56:27.327 INFO 23028 --- [ restartedMain] com.example.demo.DemoApplication : No active profile set, falling back to 1 default profile: "default" 2025-07-11 13:56:27.362 INFO 23028 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable 2025-07-11 13:56:27.362 INFO 23028 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG' 2025-07-11 13:56:27.957 WARN 23028 --- [ restartedMain] o.m.s.mapper.ClassPathMapperScanner : No MyBatis mapper was found in '[com.example.demo]' package. Please check your configuration. 2025-07-11 13:56:28.272 INFO 23028 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2025-07-11 13:56:28.279 INFO 23028 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2025-07-11 13:56:28.279 INFO 23028 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.68] 2025-07-11 13:56:28.331 INFO 23028 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2025-07-11 13:56:28.331 INFO 23028 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 969 ms 2025-07-11 13:56:28.567 INFO 23028 --- [ restartedMain] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] 2025-07-11 13:56:28.824 INFO 23028 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729 2025-07-11 13:56:28.827 INFO 23028 --- [ restartedMain] o.s.b.a.e.web.EndpointLinksResolver : Exposing 2 endpoint(s) beneath base path '/actuator' 2025-07-11 13:56:28.860 INFO 23028 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2025-07-11 13:56:28.870 INFO 23028 --- [ restartedMain] com.example.demo.DemoApplication : Started DemoApplication in 1.805 seconds (JVM running for 2.254) 2025-07-11 13:56:29.170 INFO 23028 --- [)-192.168.0.102] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2025-07-11 13:56:29.219 INFO 23028 --- [)-192.168.0.102] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' 2025-07-11 13:56:29.219 INFO 23028 --- [)-192.168.0.102] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2025-07-11 13:56:29.220 INFO 23028 --- [)-192.168.0.102] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms 2025-07-11 13:56:30.310 ERROR 23028 --- [)-192.168.0.102] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Exception during pool initialization. java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:828) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:448) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) ~[HikariCP-4.0.3.jar:na] at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364) ~[HikariCP-4.0.3.jar:na] at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206) ~[HikariCP-4.0.3.jar:na] at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476) ~[HikariCP-4.0.3.jar:na] at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) ~[HikariCP-4.0.3.jar:na] at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115) ~[HikariCP-4.0.3.jar:na] at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) ~[HikariCP-4.0.3.jar:na] at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:159) ~[spring-jdbc-5.3.23.jar:5.3.23] at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:117) ~[spring-jdbc-5.3.23.jar:5.3.23] at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80) ~[spring-jdbc-5.3.23.jar:5.3.23] at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:330) ~[spring-jdbc-5.3.23.jar:5.3.23] at org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator.getProduct(DataSourceHealthIndicator.java:122) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator.doDataSourceHealthCheck(DataSourceHealthIndicator.java:105) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator.doHealthCheck(DataSourceHealthIndicator.java:100) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.AbstractHealthIndicator.health(AbstractHealthIndicator.java:82) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthIndicator.getHealth(HealthIndicator.java:37) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpoint.getHealth(HealthEndpoint.java:94) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpoint.getHealth(HealthEndpoint.java:41) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpointSupport.getLoggedHealth(HealthEndpointSupport.java:172) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpointSupport.getContribution(HealthEndpointSupport.java:145) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpointSupport.getAggregateContribution(HealthEndpointSupport.java:156) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpointSupport.getContribution(HealthEndpointSupport.java:141) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpointSupport.getHealth(HealthEndpointSupport.java:110) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpointSupport.getHealth(HealthEndpointSupport.java:81) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpoint.health(HealthEndpoint.java:88) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpoint.health(HealthEndpoint.java:78) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:569) ~[na:na] at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282) ~[spring-core-5.3.23.jar:5.3.23] at org.springframework.boot.actuate.endpoint.invoke.reflect.ReflectiveOperationInvoker.invoke(ReflectiveOperationInvoker.java:74) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredOperation.invoke(AbstractDiscoveredOperation.java:60) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.endpoint.jmx.EndpointMBean.invoke(EndpointMBean.java:122) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.endpoint.jmx.EndpointMBean.invoke(EndpointMBean.java:97) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:814) ~[na:na] at java.management/com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:802) ~[na:na] at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1472) ~[na:na] at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1310) ~[na:na] at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1405) ~[na:na] at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:569) ~[na:na] at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360) ~[na:na] at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200) ~[na:na] at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197) ~[na:na] at java.base/java.security.AccessController.doPrivileged(AccessController.java:712) ~[na:na] at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196) ~[na:na] at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587) ~[na:na] at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828) ~[na:na] at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705) ~[na:na] at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) ~[na:na] at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na] at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na] 2025-07-11 13:56:30.312 WARN 23028 --- [)-192.168.0.102] o.s.b.a.jdbc.DataSourceHealthIndicator : DataSource health check failed org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES) at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:83) ~[spring-jdbc-5.3.23.jar:5.3.23] at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:330) ~[spring-jdbc-5.3.23.jar:5.3.23] at org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator.getProduct(DataSourceHealthIndicator.java:122) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator.doDataSourceHealthCheck(DataSourceHealthIndicator.java:105) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator.doHealthCheck(DataSourceHealthIndicator.java:100) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.AbstractHealthIndicator.health(AbstractHealthIndicator.java:82) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthIndicator.getHealth(HealthIndicator.java:37) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpoint.getHealth(HealthEndpoint.java:94) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpoint.getHealth(HealthEndpoint.java:41) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpointSupport.getLoggedHealth(HealthEndpointSupport.java:172) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpointSupport.getContribution(HealthEndpointSupport.java:145) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpointSupport.getAggregateContribution(HealthEndpointSupport.java:156) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpointSupport.getContribution(HealthEndpointSupport.java:141) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpointSupport.getHealth(HealthEndpointSupport.java:110) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpointSupport.getHealth(HealthEndpointSupport.java:81) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpoint.health(HealthEndpoint.java:88) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.health.HealthEndpoint.health(HealthEndpoint.java:78) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:569) ~[na:na] at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282) ~[spring-core-5.3.23.jar:5.3.23] at org.springframework.boot.actuate.endpoint.invoke.reflect.ReflectiveOperationInvoker.invoke(ReflectiveOperationInvoker.java:74) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredOperation.invoke(AbstractDiscoveredOperation.java:60) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.endpoint.jmx.EndpointMBean.invoke(EndpointMBean.java:122) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at org.springframework.boot.actuate.endpoint.jmx.EndpointMBean.invoke(EndpointMBean.java:97) ~[spring-boot-actuator-2.6.13.jar:2.6.13] at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:814) ~[na:na] at java.management/com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:802) ~[na:na] at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1472) ~[na:na] at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1310) ~[na:na] at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1405) ~[na:na] at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:569) ~[na:na] at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360) ~[na:na] at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200) ~[na:na] at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197) ~[na:na] at java.base/java.security.AccessController.doPrivileged(AccessController.java:712) ~[na:na] at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196) ~[na:na] at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587) ~[na:na] at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828) ~[na:na] at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705) ~[na:na] at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) ~[na:na] at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na] at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na] Caused by: java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:828) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:448) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) ~[HikariCP-4.0.3.jar:na] at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364) ~[HikariCP-4.0.3.jar:na] at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206) ~[HikariCP-4.0.3.jar:na] at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476) ~[HikariCP-4.0.3.jar:na] at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) ~[HikariCP-4.0.3.jar:na] at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115) ~[HikariCP-4.0.3.jar:na] at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) ~[HikariCP-4.0.3.jar:na] at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:159) ~[spring-jdbc-5.3.23.jar:5.3.23] at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:117) ~[spring-jdbc-5.3.23.jar:5.3.23] at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80) ~[spring-jdbc-5.3.23.jar:5.3.23] ... 48 common frames omitted 使用navict可以访问数据库,但是idea启动服务报错,数据库密码没问题也请给出建议
最新发布
07-12
<think>我们正在解决Spring Boot应用连接MySQL时出现的"Access denied for user root@localhost (using password: YES)"错误。尽管密码正确且Navicat可以访问数据库,但应用仍然无法连接。 分析原因: 1. 密码问题:虽然密码正确,但可能应用配置的密码与数据库实际密码不一致(例如,有空格、特殊字符转义问题等)。 2. 权限问题:root用户可能没有从localhost(或应用使用的具体主机)访问的权限,或者权限需要刷新。 3. 认证插件问题:MySQL 8.0默认使用`caching_sha2_password`认证插件,而一些较旧的MySQL驱动可能不支持,导致认证失败。 4. 连接参数问题:Spring Boot配置的URL可能缺少必要的参数,如时区设置、SSL设置、公钥获取设置等。 5. 数据库名称问题:配置的数据库名不存在,或者用户没有访问该数据库的权限。 6. 连接池问题:连接池配置可能导致连接使用过时的凭据。 解决方案: 步骤1:检查Spring Boot配置 确保application.properties(或application.yml)中的数据库配置正确: - spring.datasource.url: 检查数据库URL,包括端口、数据库名、参数(如useSSL, serverTimezone, allowPublicKeyRetrieval等) - spring.datasource.username: 用户名 - spring.datasource.password: 密码(注意特殊字符转义,如'@'需要写成'%40',但通常在properties文件中直接写即可,除非有特殊字符如$需要转义) 推荐配置(MySQL 8.x): ```properties spring.datasource.url=jdbc:mysql://localhost:3306/your_database?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true spring.datasource.username=root spring.datasource.password=your_password ``` 注意:`allowPublicKeyRetrieval=true`参数对于解决MySQL 8.x的认证问题非常重要。 步骤2:检查MySQL用户权限 使用Navicat或命令行登录MySQL,执行以下SQL语句: ```sql SELECT user, host, plugin, authentication_string FROM mysql.user WHERE user='root'; ``` 确保root用户有从'localhost'(或'%',如果从远程连接)访问的权限,并且密码正确。 如果发现root用户的插件是`caching_sha2_password`,而你的驱动较旧(如MySQL Connector/J 5.x),则可能需要更改插件: ```sql ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password'; FLUSH PRIVILEGES; ``` 步骤3:检查数据库是否存在 确保配置的数据库(在URL中)已经存在: ```sql SHOW DATABASES; ``` 如果不存在,创建数据库: ```sql CREATE DATABASE your_database; ``` 步骤4:检查防火墙和MySQL服务 确保MySQL服务正在运行,并且端口3306没有被防火墙阻止。 步骤5:检查连接池配置 如果使用了连接池(如HikariCP),检查连接池配置是否正确,特别是连接测试查询(对于较新的驱动,推荐使用`connection-test-query`,但HikariCP有自动检测机制)。 步骤6:启用详细日志 在Spring Boot的application.properties中添加以下配置以查看详细的数据库连接日志: ```properties logging.level.org.springframework.jdbc=DEBUG logging.level.com.zaxxer.hikari=DEBUG ``` 重启应用,查看日志中具体的错误信息。 步骤7:测试连接 编写一个简单的测试来检查数据库连接: ```java @SpringBootTest class DatabaseConnectionTest { @Autowired private DataSource dataSource; @Test void testConnection() throws SQLException { try (Connection connection = dataSource.getConnection()) { assertTrue(connection.isValid(10)); } } } ``` 如果测试失败,根据错误信息进一步排查。 常见错误及解决: - `Public Key Retrieval is not allowed`:在URL中添加`allowPublicKeyRetrieval=true`。 - `The server time zone value 'xxx' is unrecognized`:添加`serverTimezone=UTC`(或你所在的时区,如Asia/Shanghai)。 - `SSL connection error`:如果不需要SSL,设置`useSSL=false`。 如果以上步骤都不能解决问题,考虑重置root密码(参考之前的密码重置步骤)。 相关问题: 1. 如何在Spring Boot中配置多个数据源? 2. 如何为Spring Boot应用创建专用的MySQL用户? 3. 如何升级MySQL驱动以支持caching_sha2_password插件? 4. 如何在生产环境中安全地管理数据库密码? 5. 如何配置Spring Boot使用环境变量中的数据库密码?</think>### 🔍 Spring Boot 连接 MySQL 访问拒绝问题深度解析 当 Spring Boot 应用出现 `Access denied for user root@localhost (using password: YES)` 错误时,尽管 Navicat 可正常访问且密码正确,通常由以下原因导致: #### 🚫 核心问题原因 1. **认证插件不匹配** MySQL 8.x 默认使用 `caching_sha2_password` 认证插件,但旧版 JDBC 驱动(如 mysql-connector-java < 8.0)无法兼容[^1] ```sql SELECT user, host, plugin FROM mysql.user; /* root 用户应显示 caching_sha2_password */ ``` 2. **SSL/TLS 配置冲突** Spring Boot 默认尝试 SSL 连接,而本地 MySQL 可能未配置证书 3. **连接参数缺失** JDBC URL 缺少关键参数如 `allowPublicKeyRetrieval` 和 `serverTimezone` 4. **连接池缓存旧凭据** HikariCP 等连接池可能缓存了过期的认证信息 --- ### ✅ 分步解决方案 #### 步骤 1:修改 Spring Boot 配置 在 `application.properties` 中添加关键参数: ```properties # 强制使用 MySQL 原生密码认证 spring.datasource.url=jdbc:mysql://localhost:3306/your_db? useSSL=false& allowPublicKeyRetrieval=true& serverTimezone=UTC& useUnicode=true& characterEncoding=UTF-8 # 显式指定驱动类(MySQL 8.x+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # 验证凭据 spring.datasource.username=root spring.datasource.password=your_actual_password ``` > 📌 关键参数说明: > - `allowPublicKeyRetrieval=true`:解决公钥检索问题[^1] > - `useSSL=false`:禁用本地环境 SSL > - `serverTimezone=UTC`:避免时区导致的握手失败 #### 步骤 2:验证驱动兼容性 检查 `pom.xml` 确保使用 MySQL 8.x+ 驱动: ```xml <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>8.0.33</version> <!-- 必须 ≥ 8.0 --> </dependency> ``` #### 步骤 3:重置 MySQL 用户认证方式 通过 Navicat 执行: ```sql -- 切换到 mysql 系统库 USE mysql; -- 修改 root 认证插件 ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password'; -- 刷新权限 FLUSH PRIVILEGES; ``` #### 步骤 4:清除连接池缓存 在应用启动类添加: ```java @SpringBootApplication public class Application implements CommandLineRunner { @Autowired private DataSource dataSource; public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Override public void run(String... args) throws SQLException { // 强制重置连接池 if(dataSource instanceof HikariDataSource) { ((HikariDataSource) dataSource).close(); } } } ``` #### 步骤 5:验证连接(测试类) ```java @SpringBootTest public class DatabaseTest { @Autowired DataSource dataSource; @Test void testConnection() throws SQLException { try(Connection conn = dataSource.getConnection()) { DatabaseMetaData meta = conn.getMetaData(); System.out.println("成功连接: " + meta.getDatabaseProductVersion()); } } } ``` --- ### 🔧 高级故障排除 | 现象 | 解决方案 | |------|----------| | 仍报 `Public Key Retrieval` | 在 URL 后添加 `&allowPublicKeyRetrieval=true` | | 时区错误 | 确保 `serverTimezone` 与 MySQL 时区一致 | | 密码特殊字符 | 用 URL 编码:`@` → `%40`,`!` → `%21` | | Docker 环境问题 | 添加 `&useAffectedRows=true` | --- ### 💡 预防措施 1. **创建专用应用用户**(避免使用 root) ```sql CREATE USER 'app_user'@'%' IDENTIFIED WITH mysql_native_password BY 'SecurePass123!'; GRANT SELECT, INSERT, UPDATE ON your_db.* TO 'app_user'@'%'; ``` 2. **配置环境变量管理密码** ```properties # application-prod.properties spring.datasource.password=${DB_PASSWORD} # 从环境变量读取 ``` 3. **启用连接测试** ```properties spring.datasource.hikari.connection-test-query=SELECT 1 spring.datasource.hikari.initialization-fail-timeout=30000 ``` > **重要提示**:生产环境务必启用 SSL 连接,本地开发可暂时禁用[^1] --- ### ❓ 相关问题 1. 如何在 Spring Boot 中配置多数据源并避免认证冲突? 2. MySQL 8.x 的 `caching_sha2_password` 相比 `mysql_native_password` 有哪些安全优势?[^1] 3. Spring Boot 3.x 对 MySQL 驱动有哪些新要求? 4. 如何通过 Docker 部署 MySQL 8.x 并解决认证问题? 5. 生产环境中如何自动化轮换数据库凭据? 通过以上方案,95% 的认证失败问题可解决。若问题持续,请检查 MySQL 错误日志: ```bash # Windows D:\MySQL\mysql-8.0.42-winx64\data\mysql.err # Linux sudo tail -f /var/log/mysql/error.log ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值