spring整合mybatis,junit纯注解开发(包括连接druid报错的所有解决方法)

目录

Spring整合mybatis开发步骤

第一步:创建我们的数据表

第二步:编写对应的实体类

第三步:在pom.xml中导入我们所需要的坐标

spring所依赖的坐标

mybatis所依赖的坐标

druid数据源坐标

数据库驱动依赖

第四步:编写SpringConfig配置类

第五步:编写数据源配置类(目的:返回一个数据源bean对象)

第六步:编写MybatisConfig配置类

第七步:编写dao层的接口文件

第八步:编写测试类

这里也许就会有人疑惑:明明没有把StudentMapper类交给spring管理,为什么可以直接ctx.getBean(StudentMapper.class);获取bean对象?

错误分析

第一个错误

解决方法:

[1. jdbc.propetties配置文件中所有属性名加上前缀,如](#1. jdbc.propetties配置文件中所有属性名加上前缀,如)

2.注意看你写的配置文件里有没有多余的空格

3.数据库驱动和数据库版本不一致

4.数据库驱动

还有第二个错误

解决方法:

Spring整合junit


项目大致结构:

Spring整合mybatis开发步骤

第一步:创建我们的数据表

第二步:编写对应的实体类

java 复制代码
public class Student {
  private Integer id;
  private String name;
  private Integer age;

  public Student() {
  }

  public Student(Integer id, String name, Integer age) {
    this.id = id;
    this.name = name;
    this.age = age;
  }

  public Integer getId() {
    return id;
  }

  public void setId(Integer id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public Integer getAge() {
    return age;
  }

  public void setAge(Integer age) {
    this.age = age;
  }

  @Override
  public String toString() {
    return "Student{" +
            "id=" + id +
            ", name='" + name + '\'' +
            ", age=" + age +
            '}';
  }
}

第三步:在pom.xml中导入我们所需要的坐标

spring所依赖的坐标

html 复制代码
 <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>
<!--        spring数据层依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>

mybatis所依赖的坐标

html 复制代码
<!--导入mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.1</version>
        </dependency>
<!--        整合mybatis和spring数据库-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.0</version>
        </dependency>

druid数据源坐标

html 复制代码
<!--        导入druid数据源-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>

数据库驱动依赖

html 复制代码
<!--        导入连接-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.13</version>
        </dependency>

第四步:编写SpringConfig配置类

java 复制代码
@Configuration
@ComponentScan("com.hhh")
@PropertySource("classpath:jdbc.properties")
@Import({MybatisConfig.class,JdbcConfig.class})
public class SpringConfig {
}
  • @Configuration说明这是一个配置类
  • @ComponentScan("com.hhh")说明spring要扫描(管理)的范围
  • @@PropertySource("classpath:jdbc.properties")全局引入外部文件
  • @Import({MybatisConfig.class,JdbcConfig.class})导入外部配置类

第五步:编写数据源配置类(目的:返回一个数据源bean对象)

java 复制代码
public class JdbcConfig {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String name;
    @Value("${jdbc.password}")
    private String password;
    //让返回的druid数据源对象成为bean
    @Bean
    public DataSource getDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(driver);
        druidDataSource.setUsername(name);
        druidDataSource.setUrl(url);
        druidDataSource.setPassword(password);
        return druidDataSource;
    }
}

我在这个配置类中写了一个getDataSource()方法,并加上@Bean注解目的是让这个方法的返回值成为一个Bean对象

  • druidDataSource.setDriverClassName(driver);
  • druidDataSource.setUsername(name);
  • druidDataSource.setUrl(url);
  • druidDataSource.setPassword(password);
    这四行分别配置了连接数据库的四大参数,这四大参数通过@Value的方式进行注入

第六步:编写MybatisConfig配置类

java 复制代码
public class MybatisConfig {
    //使用了mybatis整合bean的工厂类,不然会报错
    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
        //直接在参数上写需要的数据源类型,spring会根据bean的类型自动依赖注入
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        //设置别名,让com.hhh.pojo这个包下的类只需要写类名即可
        sqlSessionFactoryBean.setTypeAliasesPackage("com.hhh.pojo");
        sqlSessionFactoryBean.setDataSource(dataSource);
        return sqlSessionFactoryBean;
    }

    /**
     * 创建 MapperScannerConfigurer Mapper类对象,用来加载dao层接口
     * @return
     */
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        //扫描mapper
        mapperScannerConfigurer.setBasePackage("com.hhh.dao");
        return mapperScannerConfigurer;
    }
}

这个配置类有两个目的:

1.返回一个SqlSessionFactory工厂类Bean对象

2.扫描dao层的接口文件

所以我写了两个方法

第一个方法:返回值类型要写成SqlSessionFactoryBean,这是mybatis整合bean的工厂类

不能只写SqlSessionFactory

在这个方法里配置了所有实体类的别名 和配置了所需要的数据源

第二个方法:扫描了dao层的所有mapper接口文件,并返回MapperScannerConfigurer类型的bean对象

第七步:编写dao层的接口文件

java 复制代码
public interface StudentMapper {
    //根据id查询
     @Select("select id,name,age from student where id =#{id};")
     Student findById(@Param("id")Integer id);
}

第八步:编写测试类

java 复制代码
public class App {
    public static void main(String[] args) {
        //加载配置类
        ApplicationContext ctx= new AnnotationConfigApplicationContext(SpringConfig.class);
        StudentMapper studentMapper = ctx.getBean(StudentMapper.class);
      
        Student student = studentMapper.findById(1);
        System.out.println(student);

    }
}

结果:

这里也许就会有人疑惑:明明没有把StudentMapper类交给spring管理,为什么可以直接ctx.getBean(StudentMapper.class);获取bean对象?

我们先来打印一个这个studentMapper对象看看

MapperProxy接口代理对象,可见spring帮我们创建了一个 MapperProxy类型的bean,这是哪里创建的?

这就是MybatisConfig配置类中mapperScannerConfigurer()方法通过扫描dao层的所有接口文件时创建的。

错误分析

第一个错误

com.alibaba.druid.support.logging.JakartaCommonsLoggingImpl info

信息: {dataSource-1} inited

7月 20, 2024 12:05:46 下午 com.alibaba.druid.support.logging.JakartaCommonsLoggingImpl error

严重: create connection SQLException, url: jdbc:mysql://localhost:3306/mysql_day2?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false, errorCode 1045, state 28000

java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)

无限循环报以上的错误

解决方法:

1. jdbc.propetties配置文件中所有属性名加上前缀,如

2.注意看你写的配置文件里有没有多余的空格

3.数据库驱动和数据库版本不一致

复制代码
select VERSION();查询数据库版本
html 复制代码
<!--        导入连接-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.13</version>
        </dependency>

这里我因为之前下载的数据库为8.30,没有这个高版本的数据库驱动,所以我还重新安装了数据库,哭

4.数据库驱动

mysql5 使用的驱动为 com.mysql.jdbc.Driver

mysql8 使用的驱动为 com.mysql.cj.jdbc.Driver

我在使用了上述四种方法后还是报错,

继续试了不使用外部文件,直接注入,依旧不行,把密码改成root,也不行,当时真的快崩溃了

,但是我没有放弃,继续查看报错

errorCode 1045, state 28000

我通过查询大量文章的得知1045时用户名和密码错误,但是我的配置文件里的用户名和密码都是正确的,所以我注意到了上面红字的部分,我看到别人的报错在@前面都会有他们自己的数据库用户名,但是我的没有显示用户名,我就在想是不是数据源的用户名没有传进去。我查看

通过对比发现setName()并不是配置用户名的,我马上修改成

最后运行正确,历时一个下午,一个晚上(甚至做梦梦到),最后在早晨醒来时豁然开朗,发现错误。

还有第二个错误

create connection SQLException, url: jdbc:mysql://localhost:3306/mysql_day2, errorCode 0, state 01S00

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.

解决方法:

在url后面加上 ?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false

完整的jdbc.properties配置文件

html 复制代码
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mysql_day2?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false
jdbc.username=root
jdbc.password=123456

Spring整合junit

导入所需要的依赖

html 复制代码
<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

测试

java 复制代码
//添加spring整合junit专用的类加载器
@RunWith(SpringJUnit4ClassRunner.class)
//加载spring配置类
@ContextConfiguration(classes= SpringConfig.class)
public class Test {
    @Autowired
    private StudentMapper studentMapper;//这里会一直报错No beans of 'StudentMapper' type found.
    //但是我们通过MybatisConfig配置类扫描了dao层的所有接口,会创建出一个代理类bean,所以不用管
    @org.junit.Test
    public void testFindById(){
        Student student = studentMapper.findById(1);
        System.out.println(student);
    }


}

结果:

相关推荐
面试鸭几秒前
离谱!买个人信息买到网安公司头上???
java·开发语言·职场和发展
小白冲鸭31 分钟前
【报错解决】使用@SpringJunitConfig时报空指针异常
spring·java后端开发
沈询-阿里42 分钟前
java-智能识别车牌号_基于spring ai和开源国产大模型_qwen vl
java·开发语言
AaVictory.1 小时前
Android 开发 Java中 list实现 按照时间格式 yyyy-MM-dd HH:mm 顺序
android·java·list
Yaml41 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
LuckyLay1 小时前
Spring学习笔记_27——@EnableLoadTimeWeaving
java·spring boot·spring
Stringzhua1 小时前
【SpringCloud】Kafka消息中间件
spring·spring cloud·kafka
向阳12181 小时前
Dubbo负载均衡
java·运维·负载均衡·dubbo
Gu Gu Study2 小时前
【用Java学习数据结构系列】泛型上界与通配符上界
java·开发语言