SpringBoot整合mybatis通用Mapper+自定义通用Mapper方法解析

目录
  • 首先引入pom
  • 通用Mapper是tk.mybais中的
  • 也可以用代码进行配置
  • 数据库创建一张表member以及相关字段
  • 新建一个通用Mapper继承Mapper、MySqlMapper
  • 比较详细的一个入门示例
  • 举例我要写一个通用的单表分页
  • 在自己的BaseMapper写一个方法,改造后的BaseMapper
  • 新建的BaseMapperProvider
  • 对上诉实现代码的描述
  • 返回后通用Mapper是怎么处理的

最近公司在用的通用mapper,自己感兴趣,然后就来搭建了一个springboot项目试验通用mapper

这个项目是国内的大神写的一个mybatis插件,里面有很多的增删改查方法

官方解释的是通用mapper支持3.2.4以及以上的版本

首先引入pom

<!--Mybatis -->
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.1.1</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis.generator</groupId>
			<artifactId>mybatis-generator</artifactId>
			<version>1.3.5</version>
			<type>pom</type>
		</dependency>
		<!--分页插件 -->
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper</artifactId>
			<version>4.2.1</version>
		</dependency>
		<!--tkmybatis -->
		<dependency>
			<groupId>tk.mybatis</groupId>
			<artifactId>mapper-spring-boot-starter</artifactId>
			<version>1.1.4</version>
		</dependency>

通用Mapper是tk.mybais中的

配置文件application.yml:

server:
  port: 8081
  # 下面是配置undertow作为服务器的参数
  undertow:
    # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程
    io-threads: 4
    # 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载
    worker-threads: 20
    # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
    # 每块buffer的空间大小,越小的空间被利用越充分
    buffer-size: 1024
    # 是否分配的直接内存
    direct-buffers: true

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.jdbc.Driver
    driver-class-name: com.mysql.jdbc.Driver
    platform: mysql
    url: jdbc:mysql://xxx.xxx.xxx.xxx:5306/miniprogram?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false
    username: xxxxx
    password: xxxxx
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT1FROMDUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    filters: stat,wall
    logSlowSql: true
  redis:
    database: 1
    host: xxxxx
    port: xxxx
    password: xxxx
    timeout: 10000
  activemq:
    queueName: mvp.queue
    topicName: mvp.topic
    #账号密码
    user: user
    password: user
    #URL of the ActiveMQ broker.
    broker-url: tcp://localhost:61616
    in-memory: false
    #必须使用连接池
    pool:
      #启用连接池
      enabled: true
      #连接池最大连接数
      max-connections: 5
      #空闲的连接过期时间,默认为30秒
      idle-timeout: 30s
#    jedis:    有默认值,源码:RedisProperties
#      pool:
#        max-active:
#        max-idle:
#        max-wait:
#        min-idle: 

mybatis:
  typeAliasesPackage: com.pinyu.miniprogram.mysql.entity
  mapper-locations: classpath:mapper/**/*Mapper.xml
mapper:
  mappers: com.pinyu.miniprogram.mysql.mappers.BaseMapper
  identity: mysql

#logging.config:
#  classpath: test/log4j2_test.xml

xxxx请配置自己的数据库相关信息

mapper:
  mappers: com.pinyu.miniprogram.mysql.mappers.BaseMapper
  identity: mysql

ctrl+鼠标点击com.pinyu.miniprogram.mysql.mappers.BaseMapper 进入源码可以看到 MapperProperties类

是一个集合,意思这里可以mappers配置多个通用Mapper,可以是直接继承它已有的通用Mapper,也可以是定义自己需要的通用Mapper,自定义通用Mapper(代替它的Mapper)继承实现的方式不一样,下面会讲到

也可以用代码进行配置

/**
 * 通用mapper与分页插件的一些配置
 */
@Configuration
public class MyBatisMapperScannerConfig {

   /**
   * 使用通用Mapper之前需要初始化的一些信息
   * 使用通用Mapper插件时请勿使用热加载,否则报错,插件作者后续应该会修复
   */
   @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
        mapperScannerConfigurer.setBasePackage("com.xx.xx.xx.mapper");//普通mapper的位置

        Properties properties = new Properties();
        properties.setProperty("mappers", BaseMapper.class.getName());//通用mapper的全名
        properties.setProperty("notEmpty", "false");
        properties.setProperty("IDENTITY", "MYSQL");//配置数据库方言

        mapperScannerConfigurer.setProperties(properties);
        return mapperScannerConfigurer;
    }

   /**
    * 配置mybatis的分页插件pageHelper
    */
   @Bean
   public PageHelper pageHelper(){
       PageHelper pageHelper = new PageHelper();
       Properties properties = new Properties();
       //设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用
       properties.setProperty("offsetAsPageNum","true");
       //置为true时,使用RowBounds分页会进行count查询
       properties.setProperty("rowBoundsWithCount","true");
       //合理化查询,启用合理化时,
       //如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页
       //未开启时如果pageNum<1或pageNum>pages会返回空数据
       properties.setProperty("reasonable","true");
       //配置mysql数据库的方言
       properties.setProperty("dialect","mysql");
       pageHelper.setProperties(properties);
       return pageHelper;
   }
}

mappers对应的通用mapper类,不要和自己其他业务的mapper放在一起,不要被@MapperScan扫描到,不然会报错,因为继承了通用mapper,会有很多相应的方法,被扫描到以后,mybatis发现没有一个xml配置文件或者相应方法没有进行实现,这时候就会报错。但是继承自己的BaseMapper相关mapper肯定是要被扫描到的

数据库创建一张表member以及相关字段

/*
Navicat MySQL Data Transfer
Source Server         : 120.79.81.103-5306-master
Source Server Version : 50719
Source Host           : 120.79.81.103:5306
Source Database       : miniprogram
Target Server Type    : MYSQL
Target Server Version : 50719
File Encoding         : 65001
Date: 2019-04-03 23:09:51
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for member
-- ----------------------------
DROP TABLE IF EXISTS `member`;
CREATE TABLE `member` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `member_name` varchar(255) NOT NULL COMMENT '会员用户名',
  `tel` varchar(255) DEFAULT NULL COMMENT '电话',
  `nick_name` varchar(255) NOT NULL COMMENT '昵称',
  `head_img` varchar(255) DEFAULT NULL COMMENT '头像地址',
  `status` int(1) NOT NULL COMMENT '状态 1启用 2禁用',
  `create_date` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_date` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
  `pwd` varchar(255) NOT NULL COMMENT '密码',
  `signature` varchar(255) DEFAULT NULL COMMENT '个性签名',
  `creat_id` bigint(20) DEFAULT NULL,
  `delete_state` int(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of member
-- ----------------------------
INSERT INTO `member` VALUES ('1', 'dsada', '15928878433', 'dasdas', null, '1', '2019-03-11 18:47:53', '2019-03-11 18:47:53', '123456', null, null, '1');
INSERT INTO `member` VALUES ('2', 'ypp', '15928878888', '6666', null, '1', '2019-03-11 19:35:39', null, 'EDGM@MAMABDACFDLLG', null, null, '1');

创建实体MemberEntity,一般创建实体我都会抽一些相同的字段出来

MemberEntity:

package com.pinyu.miniprogram.mysql.entity.member;
import javax.persistence.Table;
import com.pinyu.miniprogram.mysql.entity.BaseEntity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

@Data // getter、setter
@AllArgsConstructor // 全参构造方法
@NoArgsConstructor // 无参构造方法
@Accessors(chain = true) // 链式编程写法
@Table(name="member")
public class MemberEntity extends BaseEntity {

	/**
	 *
	 */
	private static final long serialVersionUID = -2601234073734313278L;
	private String memberName;// 会员登录用户名
	private String nickName;// 昵称
	private String tel;// 电话
	private String pwd;// 密码
	private String headImg;// 头像图片
	private String signature;// 个性签名
	private Integer status;//状态 1禁用 2启用
}

BaseEntity:

package com.pinyu.miniprogram.mysql.entity;
import java.util.Date;
import javax.persistence.Column;
import com.pinyu.miniprogram.mysql.entity.member.MemberEntity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

/**
 * @author ypp
 * @Description: TODO(用一句话描述该文件做什么)
 */
@Data // getter、setter
@AllArgsConstructor // 全参构造方法
@NoArgsConstructor // 无参构造方法
@Accessors(chain = true) // 链式编程写法
public class BaseEntity extends IdEntity {

	/**
	 *
	 */
	private static final long serialVersionUID = 8575696766261326260L;

	@Column(name="creat_id")
	private Integer creatId;

	@Column(name="create_date")
	private Date createDate;

	@Column(name="delete_state")
	private Integer deleteState;// 删除状态 1正常 2已删除
}

IdEntity:

package com.pinyu.miniprogram.mysql.entity;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import com.pinyu.miniprogram.mysql.entity.member.MemberEntity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

/**
 * @author ypp
 * @Description: TODO(用一句话描述该文件做什么)
 */
@Data // getter、setter
@AllArgsConstructor // 全参构造方法
@NoArgsConstructor // 无参构造方法
@Accessors(chain = true) // 链式编程写法
public class IdEntity implements Serializable {

	/**
	 *
	 */
	private static final long serialVersionUID = -9089706482760436909L;

	@Id
	@Column(name = "id")
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
}
  • @Table:对应数据库的表,如果不写默认是类名首字母小写作为表名,比Member,不写数据库表默认指向member
  • @Column:的属性name对应数据库表的字段,如果不写默认是驼峰下划线匹配,比如private Long myId,如果不写得话,就是对应数据库表字段my_id
  • @Id:把当前字段作为数据库主键使用,匹配数据库主键。如果不贴此注解,在某些查询语句的时候会把表字段一起作为联合主键查询
  • @GeneratedValue:让通用mapper在执行insert操作之后将自动生成的主键值回写到当前实体对象对应的属性当中

新建一个通用Mapper继承Mapper、MySqlMapper

点击进去看

package com.pinyu.miniprogram.mysql.mappers;
import com.pinyu.miniprogram.mysql.entity.BaseEntity;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;

/**
* @author ypp
* 创建时间:2018年12月27日 下午1:29:03
* @Description: TODO(用一句话描述该文件做什么)
*/
public interface BaseMapper<T extends BaseEntity> extends Mapper<T>,MySqlMapper<T>{
}

BaseMapper是我自己定义的通用Mapper,注意在被继承Mapper上面也有BaseMapper,注意区分,我这里名字取一样了而已。

被Mapper继承的BaseMapper里面有还有很多增删改查的方法

这是源码

看了下,里面有大概20个左右方法,都是比较基础的增删改查

测试:

MemberMapper并没有selectAll方法,沿用的继承的selectAll方法

比较详细的一个入门示例

希望能帮助到用到的小伙伴

自定义通用Mapper,也有可能在实际工作中通用Mapper并不能满足工作,需要额外的一些通用方法,但是这种的情况很少,通用Mapper提供的方法基本都能满足单表操作需求了

举例我要写一个通用的单表分页

1、自己定义的通用Mapper必须包含泛型,例如MysqlMapper<T>。这一点在这里可以忽略,这里并没有自定义自己的通用Mapper,而是使用了它自带的通用Mapper,我们继承的它

2、自定义的通用Mapper接口中的方法需要有合适的注解。具体可以参考Mapper

3、需要继承MapperTemplate来实现具体的操作方法。必须要新建一个类继承MapperTemplate,必须继承MapperTemplate,必须继承MapperTemplate

4、通用Mapper中的Provider一类的注解只能使用相同的type类型(这个类型就是第三个要实现的类。)。实际上method也都写的一样。

在自己的BaseMapper写一个方法,改造后的BaseMapper

package com.pinyu.miniprogram.mysql.mappers;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.SelectProvider;
import com.pinyu.miniprogram.mysql.entity.BaseEntity;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;

/**
 * @author ypp 创建时间:2018年12月27日 下午1:29:03
 * @Description: TODO(用一句话描述该文件做什么)
 */
public interface BaseMapper<T extends BaseEntity> extends Mapper<T>, MySqlMapper<T> {

	/**
	 * * 单表分页查询 * * @param object * @param offset * @param limit * @return
	 */
	@SelectProvider(type = BaseMapperProvider.class, method = "dynamicSQL")
	List selectPage(@Param("entity") T object, @Param("offset") int offset, @Param("limit") int limit);
}

返回结果为List,入参分别为查询条件和分页参数。在Mapper的接口方法中,当有多个入参的时候建议增加@Param注解,否则就得用param1,param2...来引用参数。

同时必须在方法上添加注解。查询使用SelectProvider,插入使用@InsertProvider,更新使用UpdateProvider,删除使用DeleteProvider。不同的Provider就相当于xml中不同的节点,如<select>,<insert>,<update>,<delete>。

因为这里是查询,所以要设置为SelectProvider,这4个Provider中的参数都一样,只有type和method。

type必须设置为实际执行方法的BaseMapperProvider.class(此类在下面),method必须设置为"dynamicSQL"。

通用Mapper处理的时候会根据type反射BaseMapperProvider查找方法,而Mybatis的处理机制要求method必须是type类中只有一个入参,且返回值为String的方法。"dynamicSQL"方法定义在MapperTemplate中,该方法如下:

public String dynamicSQL(Object record) {
    return "dynamicSQL";
}

新建的BaseMapperProvider

上面第三点说到了需要一个类继承MapperTemplate,这是必须的。继承了它然后再进行相应的实现,方法名请和Mapper接口中的方法名一致

package com.pinyu.miniprogram.mysql.mappers;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.scripting.xmltags.IfSqlNode;
import org.apache.ibatis.scripting.xmltags.MixedSqlNode;
import org.apache.ibatis.scripting.xmltags.SqlNode;
import org.apache.ibatis.scripting.xmltags.StaticTextSqlNode;
import org.apache.ibatis.scripting.xmltags.WhereSqlNode;

import tk.mybatis.mapper.entity.EntityColumn;
import tk.mybatis.mapper.mapperhelper.EntityHelper;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import tk.mybatis.mapper.mapperhelper.MapperTemplate;

public class BaseMapperProvider extends MapperTemplate {
	public BaseMapperProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
		super(mapperClass, mapperHelper);
	}

	public SqlNode selectPage(MappedStatement ms) {
		Class<?> entityClass = getEntityClass(ms);
		// 修改返回值类型为实体类型
		setResultType(ms, entityClass);

		List<SqlNode> sqlNodes = new ArrayList<SqlNode>();
		// 静态的sql部分:select column ... from table
		sqlNodes.add(new StaticTextSqlNode(
				"SELECT " + EntityHelper.getSelectColumns(entityClass) + " FROM " + tableName(entityClass)));
		// 获取全部列
		Set<EntityColumn> columns = EntityHelper.getColumns(entityClass);

		List<SqlNode> ifNodes = new ArrayList<SqlNode>();
		boolean first = true;
		// 对所有列循环,生成<if test="property!=null">[AND] column = #{property}</if>
		for (EntityColumn column : columns) {
			StaticTextSqlNode columnNode = new StaticTextSqlNode(
					(first ? "" : " AND ") + column.getColumn() + " = #{entity." + column.getProperty() + "} ");
			if (column.getJavaType().equals(String.class)) {
				ifNodes.add(new IfSqlNode(columnNode, "entity." + column.getProperty() + " != null and " + "entity."
						+ column.getProperty() + " != '' "));
			} else {
				ifNodes.add(new IfSqlNode(columnNode, "entity." + column.getProperty() + " != null "));
			}
			first = false;
		}
		// 将if添加到<where>
		sqlNodes.add(new WhereSqlNode(ms.getConfiguration(), new MixedSqlNode(ifNodes)));
		// 处理分页
		sqlNodes.add(new IfSqlNode(new StaticTextSqlNode(" LIMIT #{limit}"), "offset==0"));
		sqlNodes.add(new IfSqlNode(new StaticTextSqlNode(" LIMIT #{limit} OFFSET #{offset} "), "offset>0"));
		return new MixedSqlNode(sqlNodes);
	}
}

在这里有一点要求,那就是BaseMapperProvider处理BaseMapper<T>中的方法时,方法名必须一样,因为这里需要通过反射来获取对应的方法,方法名一致一方面是为了减少开发人员的配置,另一方面和接口对应看起来更清晰。

除了方法名必须一样外,入参必须是MappedStatement ms,除此之外返回值可以是void或者SqlNode之一。

这里先讲一下通用Mapper的实现原理。通用Mapper目前是通过拦截器在通用方法第一次执行的时候去修改MappedStatement对象的SqlSource属性。而且只会执行一次,以后就和正常的方法没有任何区别。

使用Provider注解的这个Mapper方法,Mybatis本身会处理成ProviderSqlSource(一个SqlSource的实现类),由于之前的配置,这个ProviderSqlSource种的SQL是上面代码中返回的"dynamicSQL"。这个SQL没有任何作用,如果不做任何修改,执行这个代码肯定会出错。所以在拦截器中拦截符合要求的接口方法,遇到ProviderSqlSource就通过反射调用如BaseMapperProvider中的具体代码去修改原有的SqlSource。

最简单的处理Mybatis SQL的方法是什么?就是创建SqlNode,使用DynamicSqlSource,这种情况下我们不需要处理入参,不需要处理代码中的各种类型的参数映射。比执行SQL的方式容易很多。

有关这部分的内容建议查看通用Mapper的源码和Mybatis源码了解,如果不了解在这儿说多了反而会乱。

对上诉实现代码的描述

首先获取了实体类型,然后通过setResultType将返回值类型改为entityClass,就相当于resultType=entityClass。

这里为什么要修改呢?因为默认返回值是T,Java并不会自动处理成我们的实体类,默认情况下是Object,对于所有的查询来说,我们都需要手动设置返回值类型。

对于insert,update,delete来说,这些操作的返回值都是int,所以不需要修改返回结果类型。

之后从List<SqlNode> sqlNodes = new ArrayList<SqlNode>();代码开始拼写SQL,首先是SELECT查询头,在EntityHelper.getSelectColumns(entityClass)中还处理了别名的情况。

然后获取所有的列,对列循环创建<if entity.property!=null>column = #{entity.property}</if>节点。最后把这些if节点组成的List放到一个<where>节点中。

这一段使用属性时用的是 entity. + 属性名,entity来自哪儿?来自我们前面接口定义处的Param("entity")注解,后面的两个分页参数也是。如果你用过Mybatis,相信你能明白。

之后在<where>节点后添加分页参数,当offset==0时和offset>0时的分页代码不同。

最后封装成一个MixedSqlNode返回。

返回后通用Mapper是怎么处理的

这里贴下源码:

SqlNode sqlNode = (SqlNode) method.invoke(this, ms);
DynamicSqlSource dynamicSqlSource = new DynamicSqlSource(ms.getConfiguration(), sqlNode);
setSqlSource(ms, dynamicSqlSource);

返回SqlNode后创建了DynamicSqlSource,然后修改了ms原来的SqlSource。

测试:

这里分页参数就随便用了RESTFUL风格随便写了下

数据库只有2条数据。测试成功

其实有了Mybatis自动生成插件,通用Mapper优势并不是太突出。

非SpringBoot项目的话,原理都是一样的,只是某些类需要.xml配置文件进行配置和注入

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • SpringBoot整合MyBatis逆向工程及 MyBatis通用Mapper实例详解

    一.添加所需依赖,当前完整的pom文件如下: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&q

  • SpringBoot+Mybatis使用Mapper接口注册的几种方式

    目录 I. 环境准备 1. 数据库准备 2. 项目环境 II. 实例演示 1. 实体类,Mapper类 2. 注册方式 2.1 @MapperScan注册方式 2.2 @Mapper 注册方式 2.3 MapperScannerConfigurer注册方式 3. 小结 III. 不能错过的源码和相关知识点 SpringBoot项目中借助Mybatis来操作数据库,对大部分java技术栈的小伙伴来说,并不会陌生:我们知道,使用mybatis,一般会有下面几个 Entity: 数据库实体类 Mapp

  • springboot多模块化整合mybatis,mapper自动注入失败问题及解决

    目录 springboot多模块化整合mybatis,mapper自动注入失败 问题 解决 springboot mapper注入失败的一种原因 具体情况是 解决办法 springboot多模块化整合mybatis,mapper自动注入失败 问题 启动类添加@MapperScan或@ComponentScan,mapper类添加@Mapper或@Repository ==> Consider defining a bean of type 'com.ten.mapper.UserMapper'

  • SpringBoot+Mybatis实现Mapper接口与Sql绑定几种姿势

    目录 I. 环境准备 1. 数据库准备 2. 项目环境 II. 实例演示 1. 实体类,Mapper接口 2. sql文件 3. Mapper与Sql绑定 3.1 默认方式 3.2 SpringBoot配置 3.3 Mapper标签 3.4 SqlSessionFactory 4. 小结 III. 不能错过的源码和相关知识点 通常我们在使用Mybatis进行开发时,会选择xml文件来写对应的sql,然后将Mapper接口与sql的xml文件建立绑定关系,然后在项目中调用mapper接口就可以执行

  • 解决SpringBoot整合Mybatis扫描不到Mapper的问题

    闲来无事,想学学springboot,开始搭建一个项目,但是一直显示mapper扫描不到的错误: "Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController': Unsa

  • springboot 2.0 mybatis mapper-locations扫描多个路径的实现

    springboot 2.0 mybatis mapper-locations扫描多个路径 mapper-locations扫描多个路径,中间以,分开, 如果mapper.xml在源码包下,配置成classpath*开头比较好使 mybatis: mapper-locations: classpath*:mapper/*.xml,classpath*:com/urthink/upfs/**/*Mapper.xml type-aliases-package: com.urthink.upfs.sp

  • Springboot通用mapper和mybatis-generator代码示例

    实现功能:根据数据库中的表,自动生成model.dao和对应的xml文件.xml中实现通用mapper中CURD功能 1.引入依赖 <properties> <mybatis.generator.version>1.3.7</mybatis.generator.version> <tk.mybatis.version>4.1.5</tk.mybatis.version> </properties> <dependencies&g

  • SpringBoot整合Mybatis使用Druid数据库连接池

    本文实例为大家分享了SpringBoot整合Mybatis使用Druid数据库连接池的方法,具体内容如下 在SpringBoot项目中,增加如下依赖 <!-- spring mybatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version

  • SpringBoot整合Mybatis自定义拦截器不起作用的处理方案

    目录 SpringBoot整合Mybatis自定义拦截器不起作用 1. 原始的读取mybatis-config.xml文件 2. 与SpringBoot容器整合 2.1 mybatis的自动装载 3. 在mybatis-config.xml配置又放入Spring容器 SpringBoot 自定义Mybatis拦截器 第一种 第二种 第三种 SpringBoot整合Mybatis自定义拦截器不起作用 Mybatis插件生效的方式: 1. 原始的读取mybatis-config.xml文件 该方式和

  • SpringBoot整合Mybatis的知识点汇总

    springboots使用的版本是2.0.1,注意不同版本可能有差异,并不一定通用 添加Mybatis的起步依赖: <!--mybatis起步依赖--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version&

  • springboot整合mybatis流程详解

    目录 1.mybatis是什么 2.整合 2.1 导入依赖 2.2 创建包和类 2.3 在application.yaml配置mybatis 3.使用注解版mybaits 4.实战过程 1.mybatis是什么 MyBatis 是一款优秀的持久层框架,它支持自定义 SQL.存储过程以及高级映射.MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作.MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型.接口和 Java POJO(Plain Old Java

  • springboot整合mybatis中的问题及出现的一些问题小结

    1.springboot整合mybatis mapper注入时显示could not autowire,如果强行写(value  = false ),可能会报NullPointException异常 解决方案: dao层加注解@Component(value = "首字母小写的接口名如UserMapper->userMapper") dao层还可以加注解@Mapper 2.The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecogni

  • SpringBoot整合Mybatis实现CRUD

    准备工具:IDEA jdk1.8 Navicat for MySQL Postman 一.新建Project 选择依赖:mybatis Web Mysql JDBC 项目结构 pom依赖: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.o

  • SpringBoot整合mybatis简单案例过程解析

    这篇文章主要介绍了SpringBoot整合mybatis简单案例过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.在springboot项目中的pom.xml中添加mybatis的依赖 <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifac

  • springboot整合Mybatis、JPA、Redis的示例代码

    引言 在springboot 项目中,我们是用ORM 框架来操作数据库变的非常方便.下面我们分别整合mysql ,spring data jpa 以及redis .让我们感受下快车道. 我们首先创建一个springboot 项目,创建好之后,我们来一步步的实践. 使用mybatis 引入依赖: <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-

随机推荐