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);
    }


}

结果:

相关推荐
yacolex16 分钟前
Mac安装使用Gradle
spring·macos·gradle
豐儀麟阁贵19 分钟前
2.6 代码注释与编码规
java·开发语言
程序员三明治20 分钟前
【Mybatis从入门到入土】ResultMap映射、多表查询与缓存机制全解析
java·sql·缓存·mybatis·resultmap·缓存机制·多表查询
间彧25 分钟前
Java transient关键字详解与项目实战
后端
华仔啊26 分钟前
Java 重试机制没写对,线上很容易出问题!这份生产级方案请收好
java·后端
你不是我我28 分钟前
【Java 开发日记】什么是线程池?它的工作原理?
java·开发语言
Seven9730 分钟前
剑指offer-35、数组中的逆序对
java·leetcode
中电金信30 分钟前
中电金信:从AI赋能到AI原生——企业级工具链平台重塑与建设实践
大数据
梵得儿SHI44 分钟前
Java 反射机制深度解析:从运行时 “解剖” 类的底层逻辑
java·开发语言·反射·反射机制·private·类成员·反射的三大核心功能
CodeSheep1 小时前
大家有没有发现一个奇特现象:你能在一个公司工作 12 年以上,无论你多忠诚多卖力,一旦公司赚的少了,那你就成了“眼中钉肉中刺”
前端·后端·程序员