在springBoot中使用Mapper类问题_@Mapper_@MapperScan_xml文件跟mapper分开_xml文件跟mapper在同一个目录下


背景

在springBoot中使用mapper类,因为有其xml文件的存在,所以其xml文件的存放位置不同,会导致出现运行是否能够调用xml文件的问题存在;这个问题我遇到N多次了,不好好的解决一番,实在是不好继续写项目下去了;

xml文件跟mapper分开

当xml文件跟mapper文件分开的时候,也就是将xml文件放在springBoot下的src/main/resources文件下,如下所示:
在这里插入图片描述

application.properties

当分开的时候,我们需要在application.properties主配置文件中配置如下:

mybatis.mapper-locations=classpath:mapper/*.xml
  • mybatis.mapper-locations
    指明是xml文件的路径

方式一: 主程序中@MapperScan

为了让mybatis扫描到我们的包,还需要在主程序中声明Mapper包的扫描,如下:
在这里插入图片描述
也可以不配置上边的扫描,在每个Mapper文件上加上@Mapper注解,每个文件都需要写上,没有上边的方便。

按照上边的配置,不需要在Mapper类中添加注解的,当我们在Service类中直接调用就是了,因为配置文件指明了;
但是这样idea会报红!
当我们在Service中调用的时候,还是会报无法注入,如下展示:
在PermissionMapper类中:
在这里插入图片描述

之后在Service类中使用Autowired注入,如下:
在这里插入图片描述
注意了:
这样虽然报错,但是项目运行没有一点影响!

如图运行成功:
在这里插入图片描述

也就是说是无伤大雅的;

但是要想消除这个idea的报错也可以滴;无法注入,是说没有这样的Bean存在,那么我们就添加一个注解,注入Bean嘛,所以在Mapper包下的所有mapper接口添加一个
@Repository注解
或者是
@Component注解

其效果是一样的,都是告知spring管理这个类为Bean;

这样就不会有报错了,如下:
在这里插入图片描述
在这里插入图片描述

方式二: 每个接口添加@Mapper

在方式一中,我们需要在主程序类中告诉Mybatis扫描mapper包;添加@MapperScan注解
如下:
在这里插入图片描述
我们也可以在每一个mapper接口中添加@Mapper注解,这样就不需要在主程序类中添加扫描了;如下:
在这里插入图片描述

注意点

在上面的两种方式中,有一个绕不开的点,就是在resources目录下创建的目录的时候,跟在java目录下创建目录是不一样的;

在java文件中我们创建的目录可以使用

这样表示子级目录,但是在resources文件下创建使用.

idea创建的时候就会误认为是一个名字,如下这样创建:
在这里插入图片描述
在盘符系统中,是这样的:
在这里插入图片描述
点开之后就只是一个文件,如下:
在这里插入图片描述

实际上我们需要使用的是子级目录形式,也就是在application.properties中写的:
mybatis.mapper-locations=classpath:mapper/*.xml

是一个目录路径;

所以,在resources目录下创建文件,需要以/创建,如下这样的形式:

这个锅就是idea来背!!!!!当我们打开其目录结构,就可以发现,如下:
在这里插入图片描述

点开之后如下:
在这里插入图片描述
但是idea本身也可查看其到底是否是一个目录,如下:
在这里插入图片描述
这样就可以显示是否是一个目录结构了,如下:
在这里插入图片描述

xml文件跟mapper在同一个目录下

application.properties中不需要配置这个。

mybatis.mapper-locations=classpath:mapper/*.xml

在mapper包下

将原来在resources的mapper目录下的xml文件全部剪切到mapper包下,如下:
在这里插入图片描述

主程序类

主程序类还是指明了Mybatis扫描的包,不加@MapperScan扫描,可以在mapper文件中单独加上@Mapper注解。
在这里插入图片描述
然后运行主程序类,再访问,如下:
在这里插入图片描述

报错:找不到mapper.xml

注意了

xml文件是没有问题的,其它的也没有问题的;因为按照前面分开mapper类和xml文件,运行及其功能都是没有问题的!!!

并且在Ecplise中运行,按照上面的方式去配置,运行也没问题。。。。
但是在idea中就是不行。。。。。。。

百度了好大一会儿,才解决;

在idea中,默认情况下是不会去编译src/main/java下的xml文件的!!!
在idea中,默认情况下是不会去编译src/main/java下的xml文件的!!!

所以需要我们自己配置src/main/java也可以编译资源文件,在pom.xml文件中,如下:

     <!--资源路径-->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>

注意这个资源是配置到build标签下的
然后当我们再运行的时候,就成功了~~~~
如下:
在这里插入图片描述
并且在编译文件中也有,如下:
在这里插入图片描述

SpringBoot中关于@Mapper 和 @Repository 的一些疑问

@Mapper 是 Mybatis 的注解,和 Spring 没有关系,@Repository 是 Spring 的注解,用于声明一个 Bean。

1. @Mapper

Mybatis 需要找到对应的 mapper,在编译的时候动态生成代理类,才能实现对数据库的一系列操作,所以我们需要在接口上添加 @Mapper 注解。

例如(这里只是为了演示并且sql不复杂,所以这里使用注解的方式来编写sql语句):

@Mapper
public interface UserMapper {

    @Select("select * from user where id = #{id}")
    User getById(Integer id);

    @Select("select * from user")
    List<User> getAll();
}

编写测试方法,可以发现加了自动装配注解的userMapper会出现报错(并不影响代码正常运行),这是因为@Mapper是Mybatis中的注解,我们没有显示的标明UserMapper是spring中的一个Bean,idea此时会认为在运行时找不到实例注入,所以会提示错误
在这里插入图片描述

虽然这个报错并不影响代码的正常运行,但是看着很不舒服,我们可以@Repository注解(也可以使用@Componet,只要注明这是一个bean就可以)来显示的说明UserMapper是一个bean

2. @Repository

@Repository 是spring提供的一个注解,用于声明 dao 层的 bean,如果我们要真正地使用 @Repository 来进行开发,那么我们需要手动实现UserMapperImpl,也就是说手写 JDBC代码!!!

@Repository
public class UserMapperImpl implements UserMapper{
	
	@Override
	public User getById(Integer id){
		// 装载Mysql驱动
		// 获取连接
		// 创建Statement
		// 构建SQL语句
		// 执行SQL返回结果
	}
}

3. @MapperScan(“com.xxx.xxx”)

如果我们不使用@Mapper注解,还有另一种方式让Mybatis找到mapper接口,那就是 @MapperScan 注解,可以在启动类上添加该注解,自动扫描包路径下的所有mapper接口。

@SpringBootApplication
@MapperScan("com.example.springboot_mybatis.mapper")
public class SpringbootMybatisApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootMybatisApplication.class, args);
    }
}

使用@MapperScan注解之后,就不需要在mapper接口上添加任何注解了!!

4. 总结

  • 总的来说,@Mapper 和 @MapperScan 这两个必须有一个,否则就会出错!
  • @Repository 可有可无,对程序正常运行没什么影响,但是可以消除idea报错的问题
好的,这是一个关于MyBatis的问题。以下是实现对表t_article的查改方法的代码示例。 首先,我们需要创建Article实体和ArticleMapper接口。Article实体包含id、title、content和createTime等属性。 ```java public class Article { private Long id; private String title; private String content; private Date createTime; // getter and setter methods } ``` 接下来,创建ArticleMapper接口,并使用@Mapper注解声明这是一个Mapper接口。在ArticleMapper接口,我们通过@Select和@Update注解实现对t_article表的查询和更新操作。 ```java @Mapper public interface ArticleMapper { @Select("SELECT * FROM t_article WHERE id = #{id}") Article findById(@Param("id") Long id); @Update("UPDATE t_article SET title = #{title}, content = #{content}, create_time = #{createTime} WHERE id = #{id}") void update(Article article); } ``` 接下来,我们创建ArticleMapper.xml文件,并实现对应的查询和更新操作。在ArticleMapper.xml文件,我们使用<select>和<update>标签实现对t_article表的查询和更新操作。 ```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.demo.mapper.ArticleMapper"> <select id="findById" parameterType="java.lang.Long" resultType="com.example.demo.entity.Article"> SELECT * FROM t_article WHERE id = #{id} </select> <update id="update" parameterType="com.example.demo.entity.Article"> UPDATE t_article SET title = #{title}, content = #{content}, create_time = #{createTime} WHERE id = #{id} </update> </mapper> ``` 在以上代码,<select>和<update>标签的id属性对应ArticleMapper接口方法的名称。parameterType和resultType属性分别表示参数型和返回值型。 最后,我们可以编写测试用例来测试这些方法的正确性,例如: ```java @RunWith(SpringRunner.class) @SpringBootTest public class ArticleMapperTest { @Autowired private ArticleMapper articleMapper; @Test public void testFindById() { Article article = articleMapper.findById(1L); assertNotNull(article); assertEquals("test title", article.getTitle()); } @Test public void testUpdate() { Article article = articleMapper.findById(1L); article.setTitle("updated title"); article.setContent("updated content"); article.setCreateTime(new Date()); articleMapper.update(article); article = articleMapper.findById(1L); assertEquals("updated title", article.getTitle()); assertEquals("updated content", article.getContent()); } } ``` 以上测试用例使用JUnit和Spring Boot框架编写,分别测试了查询和更新操作的正确性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Archie_java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值