Springboot +tk.mybatis+generator 自动生成Mapper xml 插件配置及 常见 错误 MapperException 、BaseSelectProvider

1.新建sprintboot项目,先把需要的 选项勾选上

如Mysql,jdbc,web,mybatis 等你需要的,这是第一步,如果你需要配置tk.mybatis,你需要额外的导入 新的jar包 以及 pom.xml 的 build 中plugin generator 插件

1.1 首先你要 配置你的 application.properties 文件, 我的配置如下, username,pwd 改成自己的用户密码
#mybatis 配置
mybatis.type-aliases-package=com.jzj.tkdemo.domain.po
#mapper 文件存放xml
mybatis.mapper-locations=classpath:/mapper/*Mapper.xml
#启用驼峰规则将数据库 user_name 实体转化为userName
mybatis.configuration.map-underscore-to-camel-case=true

#数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=xxx
spring.datasource.password=xxx
1.2 pom 中要引入 tk.mybatis的包,如下 pom.xml
1.3 pom 中要引入 tk.sprint boot start 的包,如下 pom.xml
1.4 pom 中要引入build 的generator 的maven插件 指明 generator的配置文件 generatorConfig.xml 所在位置,如下 pom.xml
1.5 项目resource 下 新建目录 mapper文件夹 存放 *Mapper.xml文件 及 generator 文件夹存放 generatorConfig.xml配置文件

下面是我的pom文件



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.3.RELEASE
         
    
    com.jzj
    tkdemo
    0.0.1-SNAPSHOT
    tkdemo
    Demo project for Spring Boot

    
        1.8
    

    
        
        
        
            tk.mybatis
            mapper-spring-boot-starter
            1.2.4
        
        
        
            com.github.pagehelper
            pagehelper-spring-boot-starter
            1.2.3
        
        

        
            org.springframework.boot
            spring-boot-starter-integration
        
        
            org.springframework.boot
            spring-boot-starter-jdbc
        
        
            org.springframework.boot
            spring-boot-starter-validation
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            2.0.0
        

        
            mysql
            mysql-connector-java
            runtime
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            


            
            
                org.mybatis.generator
                mybatis-generator-maven-plugin
                1.3.7
                
                    
                        mysql
                        mysql-connector-java
                        5.1.21
                    
                    
                        tk.mybatis
                        mapper
                        4.0.4
                    
                    
                        org.mybatis.generator
                        mybatis-generator-core
                        1.3.7
                    
                
                
                
                    src/main/resources/generator/generatorConfig.xml
                    true
                
            
        
    


2.先配置Generator maven 插件

咱们先说 插件,Generator 插件最简单 ,首先你的有数据库 我的数据库 test,然后你的有 数据库的表 user, 这些创建完成后,你可以先配置插件

2.1创建test 库 的数据表 语句
CREATE TABLE `user` (
  `id` int(32) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `user_name` varchar(32) NOT NULL DEFAULT '' COMMENT '"用户姓名"',
  `password` varchar(50) NOT NULL DEFAULT '' COMMENT '用户密码',
  `safe` tinyint(1) NOT NULL COMMENT '是否安全',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
2.2 配置generator的配置文件generatorConfig.xml

这个generatorConfig.xml 是 我们生成插件 所需要的配置信息 如 你的PO实体包,你的Mapper文件路径,你的实体类名称及 你的要创建sqlMapper的数据库表信息

1.你需要新建一个base 文件夹,放你的BaseMapper 后面所有的数据库Mapper都继承这个Base 我的是 com.jzj.tkdemo.domain.base包
2.你需要新建一个 po文件夹,放你的数据库是实体 com.jzj.tkdemo.domain.po
3.你需要resources 文件夹下 有 mapper文件夹, 存放你的数据库XML文件
4.你需要在resources 文件夹下 有 generator文件夹, 存放你的数据库generatorConfig.xml 文件

下面是 我的 generatorConfig.xml 配置文件信息, 这个xml在 resources下面的 generator 文件夹下






    

    
        
        


        
        
        
            
        


        
        

        
        
            
        

        
        
        

        
        
        


        
        
2.3 然后你可以看到看到 你的 工程中的 maven 插件中 有一个 mybatis-generator 插件, 可以直接双击运行,你的 dao,po,mapper 文件夹中就会自动生成

Springboot +tk.mybatis+generator 自动生成Mapper xml 插件配置及 常见 错误 MapperException 、BaseSelectProvider_第1张图片

UserPOMapper.java,UserPO.java,UserPOMapper.xml 文件自动生成到相应文件夹

UserPOMapper.java 自动继承BaseMapperSpringboot +tk.mybatis+generator 自动生成Mapper xml 插件配置及 常见 错误 MapperException 、BaseSelectProvider_第2张图片
UserPO.java 自动生成及注解Springboot +tk.mybatis+generator 自动生成Mapper xml 插件配置及 常见 错误 MapperException 、BaseSelectProvider_第3张图片
UserPOMapper.xml 自动生成Springboot +tk.mybatis+generator 自动生成Mapper xml 插件配置及 常见 错误 MapperException 、BaseSelectProvider_第4张图片

综上,generator 插件配置完成

3.然后开始使用,写自己的Controller,Service及Impl实现

3.1 写一个Controller, 新建com.jzj.tkdemo.controller 文件夹,新建TKUserController类 用于web访问
package com.jzj.tkdemo.controller;

import com.jzj.tkdemo.domain.po.UserPO;
import com.jzj.tkdemo.service.ITkUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 描述:
 *
 * @author jiazijie
 * @since 2019-04-02 下午9:47
 */
@RestController
public class TkUserController {

    @Autowired
    private ITkUserService tkUserService;

    @RequestMapping("selectUser/{id}")
    private String getUser(@PathVariable String id) {
        UserPO user = tkUserService.selectById(Integer.parseInt(id));
        return user.toString();
    }


    @RequestMapping("addUser")
    private int addUser() {
        UserPO user = new UserPO();
        user.setUserName("aaa");
        user.setPassword("pwd");
        user.setSafe(true);
        int count = tkUserService.insertUser(user);
        return count;
    }

    @RequestMapping("updateUser/{name}")
    private void update(@PathVariable String name) {
        UserPO user = new UserPO();
        user.setUserName(name);
        user.setPassword("pwd");
        user.setSafe(true);
        user.setId(1);
        tkUserService.updateUser(user);
    }
}

3.2 写接口ITKUserService 及实现

接口 ITkUserService

package com.jzj.tkdemo.service;

import com.jzj.tkdemo.domain.po.UserPO;

/**
 * 描述:
 *
 * @author jiazijie
 * @since 2019-04-03 下午10:47
 */
public interface ITkUserService {

    UserPO  selectById(Integer id);

    int insertUser(UserPO userPO);

    int updateUser(UserPO userPO);
}

实现 TKUserServiceImpl

package com.jzj.tkdemo.service;

import com.jzj.tkdemo.dao.UserPOMapper;
import com.jzj.tkdemo.domain.po.UserPO;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * 描述:
 *
 * @author jiazijie
 * @since 2019-04-03 下午10:48
 */
@Service
public class TkUserServiceImpl implements ITkUserService {


    @Resource
    private UserPOMapper userPOMapper;

    @Override
    public UserPO selectById(Integer id) {

        UserPO userPO = userPOMapper.selectByPrimaryKey(id);
        return userPO;
    }

    @Override
    public int insertUser(UserPO userPO) {
        int count = userPOMapper.insert(userPO);
        return count;
    }

    @Override
    public int updateUser(UserPO userPO) {
       int count = userPOMapper.updateByPrimaryKey(userPO);
       return count;
    }
}

3.3 然后 看你的Application 入口函数

加上Mapper 包扫描 ,扫描你自己的Mapper 文件,BaseMapper 接口千万别 写进这个包里面 @MapperScan(“com.jzj.tkdemo.dao”)
我的入口函数

package com.jzj.tkdemo;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tk.mybatis.spring.annotation.MapperScan;

@SpringBootApplication
@MapperScan("com.jzj.tkdemo.dao")
public class TkdemoApplication {

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

}

大功告成, 可以 启动了,然后访问Controller 页面

添加用户User http://localhost:8080/addUser 返回 1 添加数量
查询用户User http://localhost:8080/selectUser/1 查询 id=1 的员工信息
更新用户User http://localhost:8080/updateUser/aaabbb 将员工Id为1的 员工 姓名设置为 aaabbb

4. 遇到的错误 ,这才是重点

4.1 第一个错误,最经常犯的 Application启动类上 没有 MapperScan Mapper包扫描

Spring bean 注入失败 Injection of resource dependencies failed NoSuchBeanDefinitionException Dependency annotations 错误:

nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘tkUserServiceImpl’: Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘com.jzj.tkdemo.dao.UserPOMapper’ available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.annotation.Resource(shareable=true, lookup=, name=, description=, authenticationType=CONTAINER, type=class java.lang.Object, mappedName=)}

这是因为 Spring 无法发现你的 mapper文件 ,在Application上加上包扫描 就可以了 @MapperScan(“com.jzj.tkdemo.dao”)

3.2 第二个错误,最经常犯的 Application启动类上 加上 MapperScan Mapper包扫描 结果导错了MapperScan的 包

正确导入的是 import tk.mybatis.spring.annotation.MapperScan;
错误导入的是 import org.mybatis.spring.annotation.MapperScan;

报错 java.lang.NoSuchMethodException: tk.mybatis.mapper.provider.base.BaseInsertProvider.() 等信息

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Error invoking SqlProvider method (tk.mybatis.mapper.provider.base.BaseInsertProvider.dynamicSQL).  Cause: java.lang.InstantiationException: tk.mybatis.mapper.provider.base.BaseInsertProvider] with root cause

java.lang.NoSuchMethodException: tk.mybatis.mapper.provider.base.BaseInsertProvider.()
	at java.lang.Class.getConstructor0(Class.java:3082) ~[na:1.8.0_181]
	at java.lang.Class.newInstance(Class.java:412) ~[na:1.8.0_181]
	at org.apache.ibatis.builder.annotation.ProviderSqlSource.createSqlSource(ProviderSqlSource.java:117) ~[mybatis-3.4.5.jar:3.4.5]
	at org.apache.ibatis.builder.annotation.ProviderSqlSource.getBoundSql(ProviderSqlSource.java:103) ~[mybatis-3.4.5.jar:3.4.5]
	at org.apache.ibatis.mapping.MappedStatement.getBoundSql(MappedStatement.java:292) ~[mybatis-3.4.5.jar:3.4.5]
	at org.apache.ibatis.executor.statement.BaseStatementHandler.(BaseStatementHandler.java:64) ~[mybatis-3.4.5.jar:3.4.5]
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.(PreparedStatementHandler.java:40) ~[mybatis-3.4.5.jar:3.4.5]
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.(RoutingStatementHandler.java:46) ~[mybatis-3.4.5.jar:3.4.5]
	at org.apache.ibatis.session.Configuration.newStatementHandler(Configuration.java:558) ~[mybatis-3.4.5.jar:3.4.5]
	at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:48) ~[mybatis-3.4.5.jar:3.4.5]
	at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117) ~[mybatis-3.4.5.jar:3.4.5]
	at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76) ~[mybatis-3.4.5.jar:3.4.5]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]
	at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63) ~[mybatis-3.4.5.jar:3.4.5]
	at com.sun.proxy.$Proxy83.update(Unknown Source) ~[na:na]
	at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198) ~[mybatis-3.4.5.jar:3.4.5]
	at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:185) ~[mybatis-3.4.5.jar:3.4.5]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433) ~[mybatis-spring-1.3.1.jar:1.3.1]
	at com.sun.proxy.$Proxy71.insert(Unknown Source) ~[na:na]
	at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:278) ~[mybatis-spring-1.3.1.jar:1.3.1]
	at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:57) ~[mybatis-3.4.5.jar:3.4.5]
或者 不用加MapperScan 你可以不导入 MapperScan jar包

直接在你的UserPOMapper 类上加上 @Mapper 注解 也可以,但是这样 每一个Mapper都加,费力不讨好,所以还是用包扫描 比较好
Springboot +tk.mybatis+generator 自动生成Mapper xml 插件配置及 常见 错误 MapperException 、BaseSelectProvider_第5张图片

3.3 BaseMapper 在你的Mapper包 扫描内, 和其他的数据库Mapper 在同一个包扫描内

这个错误比较隐晦,藏的比较深,一般大家为了方便Mapper.java 放在一起,就将BaseMapper 父类放在类Mapper 包内,自动生成的Mapper.java 也在同一个包内,方便 但是这样会导致问题,报的错误时 reflect 反射类型错误,说类转换失败 其实就是 你把BaseMapper放在类 mapper包扫描中

报错:Invocation of init method failed;
nested exception is tk.mybatis.mapper.MapperException: tk.mybatis.mapper.MapperException: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class

tk.mybatis.mapper.MapperException 错误
java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class 错误

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'baseMapper' defined in file [/Users/jiazijie/Documents/offtime/sblearn/tkdemo/target/classes/com/jzj/tkdemo/dao/BaseMapper.class]: Invocation of init method failed; nested exception is tk.mybatis.mapper.MapperException: tk.mybatis.mapper.MapperException: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1762) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:830) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]

项目github 地址:https://github.com/jzjie007/spboot/tree/master/tkdemo

搞定, 欢迎拍砖 这只是一次简单的 sprint boot 和 generator 和 tk.mybatis 的结合

你可能感兴趣的:(SprintBoot,Springboot,tk.mybatis,generator,MapperException)