abel533 通用Mapper 问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了abel533 通用Mapper 问题相关的知识,希望对你有一定的参考价值。

首先 我自定义的Mapper继承了通用Mapper
public interface UserMapper extends Mapper<User>



然后我写了个BaseService接口
public interface BaseService<T>
/**
* 根据主键ID查询一条数据
* @param id
* @return
*/
public T queryById(Object id);

//、、、、很多方法


然后我自己实现了BaseService接口
public class BaseServiceImpl<T> implements BaseService<T>

@Autowired
private Mapper<T> mapper;

// 指定的T的泛型
private Class clazz;

public BaseServiceImpl()
// 指定父类的类型type
Type type = this.getClass().getGenericSuperclass();
// 根据这个父类的type类型转成泛型
ParameterizedType pType = (ParameterizedType) type;
// 获取T的泛型
clazz = (Class<T>) pType.getActualTypeArguments()[0];


@Override
public T queryById(Object id)
T t = mapper.selectByPrimaryKey(id);
return t;


然后 我自己的UserService接口继承BaseService接口

public interface UserService extends BaseService<User>


然后 UserService的实现如下:
@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements UserService


其他配置文件都配置好了,该做的都做了
但是最后本机tomcat启动报错:
No qualifying bean of type [com.github.abel533.mapper.Mapper] is defined: expected single matching bean but found 2: accountMapper,userMapper
说通用Mapper有两个类型,但是我继承Mapper的时候泛型不一样啊 baseService中也是按泛型注入的啊。按网上各种方法都试了 没用 ,还是报错
但是我用maven自带的tomcat插件启动就不报错,求高人解答 万分感谢

参考技术A 使用通用Mapper,不需要再写mapper.xml配置文件,多数时候,连接口方法都不需要了,大大提高了开发效率。创建一个mapper继承com.github.abel533.mapper.Mapper,必须指定泛型实体一旦继承了Mapper,继承的mapper就拥有了通用的方法。 参考技术B 看看你的Mapper中的泛型是不是写错了

MyBatis 为什么需要通用 Mapper ?

在早期项目文档中有过类似主题的内容,但是最近我自己看文档的时候发现一个问题,文档虽然很详细,但是并不适合初次接触的人。为了方便第一次听说,第一次尝试的开发人员了解通用 Mapper,补充此文档。

一、通用 Mapper 的用途 ?

我个人最早用 MyBatis 时,先是完全手写,然后用上了 MyBatis 代码生成器(简称为 MBG),在使用 MBG 过程中,发现一个很麻烦的问题,如果数据库字段变化很频繁,就需要反复重新生成代码,并且由于 MBG 覆盖生成代码和追加方式生成 XML,导致每次重新生成都需要大量的比对修改。除了这个问题外,还有一个问题,仅仅基础的增删改查等方法,就已经产生了大量的 XML 内容,还没有添加一个自己手写的方法,代码可能就已经几百行了,内容多,看着比较碍事。

因为很多人都在使用 MBG,MBG 中定义了很多常用的单表方法,为了解决前面提到的问题,也为了兼容 MBG 的方法避免项目重构太多,在 MBG 的基础上结合了部分 JPA 注解产生了通用 Mapper。通用 Mapper 可以很简单的让你获取基础的单表方法,也很方便扩展通用方法。使用通用 Mapper 可以极大的提高你的工作效率。

通过下面的快速入门,会让你尽快的了解基本的用法。

通用 Mapper 诞生于 2014 年 11 月:

https://blog.csdn.net/isea533/article/details/41457529 上面文章的设计思路和现在完全不同。 如果想要了解当前的实现原理,可以看下面这篇。 MyBatis 通用 Mapper 实现原理 :

https://blog.csdn.net/isea533/article/details/78493852

二、快速入门

为了让你更快速的了解通用 Mapper 的优势,这里会更简洁的让你了解整个过程。

首先在 Maven 项目的 pom.xml 中添加通用 Mapper 依赖:

 
   
   
 
  1. <dependency>

  2.    <groupId>tk.mybatis</groupId>

  3.    <artifactId>mapper</artifactId>

  4.    <version>最新版本</version>

  5. </dependency>

最新版本可以看这里: 

https://mvnrepository.com/artifact/tk.mybatis/mapper

接下来,开始具体的使用。

1. 配置实体类

通过 MBG 配合 专用代码生成器 可以直接生成实体类等基础代码,为了避免信息量过大,这里当作手工编写和配置。

有如下类:

 
   
   
 
  1. public class Country implements Serializable {

  2.    private static final long serialVersionUID = 1L;

  3.    @Id

  4.    @KeySql(useGeneratedKeys = true)

  5.    private Long id;

  6.    private String countryname;

  7.    private String countrycode;

  8.    //setter 和 getter 方法

  9. }

在上面类中,我们给主键添加了 @Id,标记该字段为数据库主键。还有一个通用 Mapper 的特殊注解 @KeySql,配置的 useGeneratedKeys=true 和 MyBatis 中的 useGeneratedKeys 含义相同,意思是说使用 JDBC 的方式获取数据库自增的主键值。

该类对应数据表为 country,因为类名和数据库名对应(当前数据库忽略大小写),因此不需要在类上添加 @Table(name="country")

经过上面简单的配置后,相当于就有了 MyBatis 中的 <resultMap> 关系映射了,特别注意,这个映射关系只对通用 Mapper 有效,自己手写方法时,需要自己处理映射关系。

这部分的详细内容参考文档:对象关系映射

2. 创建 Mapper 接口

根据上述实体类,创建对应的 CountryMapper 接口如下:

 
   
   
 
  1. import tk.mybatis.mapper.common.Mapper;

  2. public interface CountryMapper extends Mapper<Country> {

  3. }

这里继承了 tk.mybatis.mapper.common.Mapper 接口,在接口上指定了泛型类型 Country。当你继承了 Mapper 接口后,此时就已经有了针对 Country 的大量方法,方法如下:

这些方法中和 MBG 生成的大部分方法都一致,还有一部分 MBG 之外的常用方法。

3. 配置通用 Mapper

为了让上述方法可以直接使用,还需要配置通用 Mapper,让项目在启动的时候,把上述方法都自动生成好,这样在运行时就可以使用上面所有的方法。

根据不同的开发环境,需要不同的配置方式,完整的内容可以 集成通用 Mapper,我们这里以最常见的 Spring 和 MyBatis 集成为例。

在集成 Spring 的环境中使用 MyBatis 接口方式时,需要配置 MapperScannerConfigurer,在这种情况下使用通用 Mapper,只需要修改配置如下:

 
   
   
 
  1. <bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">

  2.    <property name="basePackage" value="扫描包名"/>

  3.    <!-- 其他配置 -->

  4. </bean>

注意官方的包名和这里 tk 包名的区别:

  • tk.mybatis.spring.mapper.MapperScannerConfigurer

  • org.mybatis.spring.mapper.MapperScannerConfigurer

只有第一部分从 org 换成了 tk。

此时通用 Mapper 最简单的配置就完成了,完整的配置可以看这里 和 Spring 集成。

4. 简单使用

下面是一个简单的测试用例,实际使用中,可以直接注入 CountryMapper

 
   
   
 
  1. public class SpringXmlTest {

  2.    private ClassPathXmlApplicationContext context;

  3.    @Test

  4.    public void testCountryMapper() {

  5.        context = new ClassPathXmlApplicationContext("tk/mybatis/mapper/xml/spring.xml");

  6.        CountryMapper countryMapper = context.getBean(CountryMapper.class);

  7.        //获取全部信息

  8.        List<Country> countries = countryMapper.selectAll();

  9.        Assert.assertNotNull(countries);

  10.        Assert.assertEquals(183, countries.size());

  11.    }

  12. }

通用 Mapper 只是提供了基础的大量方法,遇到没有的方法时,你可以正常按照 MyBatis 的用法手写,和正常用法没有任何区别。

5. 了解更多

上面的简单的介绍已经可以应用到真正的项目中了,但是有很多细节这里都没有涉及,如果你准备加入通用 Mapper,你可以先按上述内容引入项目,然后通过更详细的文档去了解更多的细节,有很多你可能想要但是 MBG 不存在的方法,在这里都有,而且如果你想实现自己的通用方法,可以很轻松的进行扩展。

完整文档:
https://github.com/abel533/Mapper/wiki

遇到问题提 issues:
https://github.com/abel533/Mapper/issues

更多完整项目示例:
https://mybatis.tk/samples.html

果子篮开发架构: http://guozilan.tk

MyBatis 交流:点击加入 MyBatis QQ 群

三、最后问一句

你觉得 MyBatis 需要通用 Mapper 吗?

由于每个人对技术的掌握程度不同,对新事物的接受能力不同,因此我们都习惯于自己已经掌握的内容,抵制未知的能力,如果你不去试试,你能回答这个问题吗?

由于微信限制,想要查看所有链接,请点击【阅读原文】进行查看。


以上是关于abel533 通用Mapper 问题的主要内容,如果未能解决你的问题,请参考以下文章

集成通用Mapper

通用mapper的使用

Error invoking SqlProvider method (com.github.abel533.mapper.MapperProvider.dynamicSQL). Cause: jav

收藏一个链接

Mybatis通用Mapper(转)

通用mapper和分类实现