Mybatis:整合SpringBoot+配置文件位置问题

引入mysql和MyBatis 的依赖信息

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.2.2</version>
    </dependency>

    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

在yml 文件中配置数据库连接信息

spring:
  datasource:
    username: root
    password: 1234
    url: jdbc:mysql://192.168.124.188:3306/temp?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false
    driver-class-name: com.mysql.cj.jdbc.Driver

驱动类driver-class-name

  • spring boot 2.0(内置jdbc5驱动),驱动类使用:driver-class-name: com.mysql.jdbc.Driver
  • spring boot 2.1及以上(内置jdbc8驱动),驱动类使用:driver-class-name: com.mysql.cj.jdbc.Driver
  • 否则运行测试用例的时候会有 WARN 信息

连接地址url

  • MySQL5.7版本的url:jdbc:mysql://192.168.124.188:3306/temp?characterEncoding=utf-8&useSSL=false
  • MySQL8.0版本的url:jdbc:mysql://192.168.124.188:3306/temp?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false
  • 否则运行测试用例报告如下错误:java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more

使用注解操作数据库

使用@Mapper

@Mapper
public interface StuMapper {
    @Select("select * from stu")
    List<Stu> findAllStu();
}

@Mapper的作用:

  • 简化XML配置:使用@Mapper注解可以避免编写复杂的XML映射文件。使用@Mapper注解可以让开发者直接在接口方法上使用注解(如@Select@Update@Insert@Delete等)来声明SQL语句,从而简化配置过程。
  • 自动注册Bean:使用@mapper后,不需要在spring配置中设置扫描地址,通过mapper.xml里面的namespace属性对应相关的mapper类,spring将动态的生成Bean后注入到ServiceImpl

使用@MapperScan

@MapperScan("com.example.springbootdemo.dao")
@SpringBootApplication
public class SpringBootDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootDemoApplication.class, args);
    }

}

它的主要作用是自动扫描指定的包路径,将其中的接口与MyBatis的映射器关联起来。这样,你就无需为每个Mapper接口手动添加@Mapper注解或在配置文件中做额外的配置。

所以,有了@MapperScan之后,就不需要每个Mapper接口都写@Mapper

//@Mapper
public interface StuMapper {
    @Select("select * from stu")
    List<Stu> findAllStu();
}

使用Mapper.xml操作数据库

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.springbootdemo.dao.StuMapper">
    <select id="findAllStu" resultType="com.example.springbootdemo.bean.Stu">
        select id,name,age from stu
    </select>
</mapper>

这个时候接口也不需要写SQL了

//@Mapper
public interface StuMapper {
//    @Select("select * from stu")
    List<Stu> findAllStu();
}

Mapper.xml和Mapper接口的位置问题

放在Java目录下

  1. 需要放在同一目录下:

  2. 还需要再pom文件里面做如下配置

    <build>
        <resources>
            <!--maven项目默认去resources目录下找配置文件
            maven项目不会去src/main/java目录底下加载配置文件,
             所有<directory>src/main/java</directory>是为了告诉maven去java目录下加载配置文件-->
            <resource >
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
            </resource>
            <!--上面我们配置了让maven去java目录下找配置文件,我们还有配置去resources目录下找配置文件
            否则maven就不会去resources下面去加载配置文件里,如果我们只配置一个的话-->
            <resource >
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                    <include>**/*.yml</include>
                </includes>
            </resource>
        </resources>
    </build>
    

放在Resource目录下

包路径相同

把mapper配置文件放在resources目录下,然后让两个包的名字相同,注意配置文件的名字要和接口的名字相同。

如果文件名不一样,如下图:

回报如下错误:无效绑定

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.example.springbootdemo.dao.StuMapper.findAllStu

注意,由于文件路径相同,所以加载的时候,会生成在同一个target目录下:

包路径不同

如图,上面Mapper接口和Mapper配置文件不是在同一个路径,所以生成的Target也不会在同一个包下:

如果这个时候去访问,也会报无效绑定

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.example.springbootdemo.dao.StuMapper.findAllStu

这个时候,需要在application配置文件里面配置

mybatis:
  mapper-locations: classpath:/mapper/*.xml # 指定xml映射文件路径

classpath:/mapper/*.xml:这个配置项指定了MyBatis的映射文件的位置。这里使用了通配符*,表示src/main/resources/mapper/目录下所有的.xml文件都是MyBatis的映射文件。这些映射文件定义了SQL语句和映射规则,将数据库中的表映射到Java对象上

但是如果目前这个配置不包含其子包,如下图:

Mybatis只拿找到mapper包下的none.xml,但是找不到mapper.mp下的StuMapper.xml

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.example.springbootdemo.dao.StuMapper.findAllStu

这个时候可以配置多个路径

mybatis:
  mapper-locations: classpath:/mapper/*.xml,/mapper/mp/*.xml # 指定xml映射文件路径

或者配置通配符:通配符 ** 表示任意级的目录

mybatis:
  mapper-locations: classpath:/mapper/**/*.xml # 指定xml映射文件路径

其他mybatis的配置

mybatis:
  config-location: classpath:/mybatis/mybatis-config.xml #指定主配置文件
  type-aliases-package: com/example/springbootdemo/bean # 指定实体类的别名-->但不建议

指定配置文件位置

如果没有配置文件,会报下面的错误:

Caused by: java.io.FileNotFoundException: class path resource [mybatis/mybatis-config.xml] cannot be opened because it does not exist

指定包别名

用过mybatis的客官应该都知道,无论是使用resultType映射查询到的结果集到一个实体类,还是使用parameterType基于Java Bean为SQL脚本传参,都需要使用完全限定名(包名+类名)来指定引用了哪个Java Bean,否则启动时会抛异常,提示找不到类。

但是有些包名很长的,每次配置完全限定名就会显得很长很麻烦,如下:

<select id="findAllStu" resultType="com.example.springbootdemo.bean.Stu">
    select id,name,age from stu
</select>

但是如果我们做了这么一个配置:type-aliases-package: com/example/springbootdemo/bean

项目启动的时候,mybatis会自动扫描指定包及其子包下的所有实体类并将别名装配到上下文中,默认别名是类名和类名首字母小写

加上配置之后,只要resultType引用了这个包下的实体类,就可以直接用别名来代替全限定名

<select id="findAllStu" resultType="stu">
    select id,name,age from stu
</select>

在上述配置的基础上,还可以通过在实体类上加入@Alias注解来进一步设置别名:

@Alias("xxxx")
public class Stu {
    private Integer id;
    private String name;
    private Integer age;
}
<select id="findAllStu" resultType="xxxx">
    select id,name,age from stu
</select>

但是不建议使用别名,因为用全类命名可以可以直接找到对应的JavaBean:按住ctrl然后点名字

classpath*classpath

在mybatis-plus的官方文档中有这么一句提示:对于 Maven 多模块项目,扫描路径应以 classpath*: 开头,以加载多个 JAR 包中的 XML 文件。

classpath:只会到你的class路径中查找找文件;

classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1909773034@qq.com

×

喜欢就点赞,疼爱就打赏