通用 Mapper4 是一个可以实现任意 MyBatis 通用方法的框架,项目提供了常规的增删改查操作以及Example 相关的单表操作。通用 Mapper 是为了解决 MyBatis 使用中 90% 的基本操作,使用它可以很方便的进行开发,可以节省开发人员大量的时间。
https://github.com/abel533/Mapper/wiki
http://mvnrepository.com/artifact/tk.mybatis/mapper-spring-boot-starter
<dependency>
<groupId>tk.mybatisgroupId>
<artifactId>mapper-spring-boot-starterartifactId>
<version>2.1.5version>
dependency>
https://github.com/qidasheng2012/springboot2.x_ssm/tree/branch-mapper4
1. 引入TkMybatis的Maven依赖
2. 实体类的相关配置,@Id,@Table
3. Mapper继承tkMabatis的Mapper接口
4. 启动类Application或自定义Mybatis配置类上使用@MapperScan注解扫描Mapper接口
5. 在application.properties配置文件中,配置mapper.xml文件指定的位置[可选]
6. 使用TkMybatis提供的sql执行方法
PS :
1. TkMybatis默认使用继承Mapper接口中传入的实体类对象去数据库寻找对应的表,因此如果表名与实体类名不满足对应规则时,会报错,这时使用@Table为实体类指定表。(这种对应规则为驼峰命名规则)
2. 使用TkMybatis可以无xml文件实现数据库操作,只需要继承tkMybatis的Mapper接口即可。
3. 如果有自定义特殊的需求,可以添加mapper.xml进行自定义sql书写,但路径必须与步骤4对应。
6. 如有需要,实现mapper.xml自定义sql语句
引入mapper-spring-boot-starter
的Maven依赖
因为mapper-spring-boot-starter
中包含MyBatis的相关包,所以不需要再引入MyBatis的相关包
<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">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.2.0.RELEASEversion>
<relativePath/>
parent>
<groupId>com.springbootgroupId>
<artifactId>springboot2.x_ssmartifactId>
<version>1.0.0version>
<description>Spring Boot2.x 搭建 SSM 项目description>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>tk.mybatisgroupId>
<artifactId>mapper-spring-boot-starterartifactId>
<version>2.1.5version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
实体类的相关配置,@Id,@Table
package com.springboot.ssm.domain;
import lombok.Data;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Data
// @Table指定该实体类对应的表名,如表名为base_customer,类名为BaseCustomer可以不需要此注解
@Table(name = "user")
public class User {
// @Id表示该字段对应数据库表的主键id
// @GeneratedValue中strategy表示使用数据库自带的主键生成策略.
// @GeneratedValue中generator配置为"JDBC",在数据插入完毕之后,会自动将主键id填充到实体类中.类似普通mapper.xml中配置的selectKey标签
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "JDBC")
private Integer id;
private String name;
private Integer age;
}
package com.springboot.ssm.common.mapper;
import tk.mybatis.mapper.common.IdsMapper;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;
public interface MysqlBaseMapper<T> extends Mapper<T>, MySqlMapper<T>, IdsMapper<T> {
}
实际开发中我们会自定义一个基础的BaseMapper,继承Mapper, MySqlMapper, IdsMapper,可以根据实际情况进行扩展继承
为何要继承MySqlMapper, IdsMapper接口?各位道友点进去看下源码就一目了然
注意:这个MysqlBaseMapper和业务的Mapper不要在同一个包下
,否则会报下面的错
UserMapper 继承自定义的MysqlBaseMapper接口
package com.springboot.ssm.mapper;
import com.springboot.ssm.common.mapper.MysqlBaseMapper;
import com.springboot.ssm.domain.User;
public interface UserMapper extends MysqlBaseMapper<User> {
}
启动类Application或自定义Mybatis配置类上使用@MapperScan注解扫描Mapper接口
注意包名:tk.mybatis.spring.annotation.MapperScan
package com.springboot.ssm;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tk.mybatis.spring.annotation.MapperScan;
@SpringBootApplication
@MapperScan(basePackages = "com.springboot.ssm.mapper")
public class SsmApplication {
public static void main(String[] args) {
SpringApplication.run(SsmApplication.class, args);
}
}
在application.yml配置文件中,配置mapper.xml文件指定的位置[可选]
spring:
#数据源
datasource:
url: jdbc:mysql://localhost:3306/ssm?serverTimezone=Asia/Shanghai&characterEncoding=utf8
username: root
password: 123456
mybatis:
# 定义mapper.xml的路径
mapper-locations: classpath*:mapper/*.xml
#起别名。可省略写mybatis的xml中的resultType的全路径
type-aliases-package: com.springboot.ssm.domain
mapper:
# 配置后会自动处理关键字,可以配的值和数据库有关。
wrap-keyword: '`{0}`'
# insertSelective 和 updateByPrimaryKeySelective 中,是否判断字符串类型 !=''。
notEmpty: true
# 日志
logging:
level:
com.springboot.ssm.mapper: debug # 显示执行sql
使用TkMybatis提供的sql执行方法
package com.springboot.ssm.controller;
import com.springboot.ssm.domain.User;
import com.springboot.ssm.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/selectAll")
public List<User> selectAll() {
return userService.selectAll();
}
@GetMapping("/selectByIds/{ids}")
public List<User> selectByIds(@PathVariable String ids) {
return userService.selectByIds(ids);
}
@PostMapping("/addOne")
public int addOne(@RequestBody User user) {
return userService.addOne(user);
}
}
package com.springboot.ssm.service;
import com.springboot.ssm.domain.User;
import java.util.List;
public interface UserService {
// 查询所有用户信息
List<User> selectAll();
// 根据ids查询用户信息
List<User> selectByIds(String ids);
// 新增一个用户
int addOne(User user);
}
package com.springboot.ssm.service.impl;
import com.springboot.ssm.domain.User;
import com.springboot.ssm.mapper.UserMapper;
import com.springboot.ssm.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public List<User> selectAll() {
return userMapper.selectAll();
}
@Override
public List<User> selectByIds(String ids) {
return userMapper.selectByIds(ids);
}
@Override
public int addOne(User user) {
return userMapper.insertUseGeneratedKeys(user);
}
}
访问:http://127.0.0.1:8080/user/selectAll
访问:http://localhost:8080/user/selectByIds/1,2,3
访问:http://localhost:8080/user/addOne
【Select】
方法:List select(T record);
说明:根据实体中的属性值进行查询,查询条件使用等号
方法:T selectByPrimaryKey(Object key);
说明:根据主键字段进行查询,方法参数必须包含完整的主键属性,查询条件使用等号
方法:List selectAll();
说明:查询全部结果,select(null)方法能达到同样的效果
方法:T selectOne(T record);
说明:根据实体中的属性进行查询,只能有一个返回值,有多个结果是抛出异常,查询条件使用等号
方法:int selectCount(T record);
说明:根据实体中的属性查询总数,查询条件使用等号
【Insert】
方法:int insert(T record);
说明:保存一个实体,null的属性也会保存,不会使用数据库默认值
方法:int insertSelective(T record);
说明:保存一个实体,null的属性不会保存,会使用数据库默认值
【Update】
方法:int updateByPrimaryKey(T record);
说明:根据主键更新实体全部字段,null值会被更新
方法:int updateByPrimaryKeySelective(T record);
说明:根据主键更新属性不为null的值
【Delete】
方法:int delete(T record);
说明:根据实体属性作为条件进行删除,查询条件使用等号
方法:int deleteByPrimaryKey(Object key);
说明:根据主键字段进行删除,方法参数必须包含完整的主键属性
【Example方法】
方法:List selectByExample(Object example);
说明:根据Example条件进行查询
重点:这个查询支持通过Example类指定查询列,通过selectProperties方法指定查询列
方法:int selectCountByExample(Object example);
说明:根据Example条件进行查询总数
方法:int updateByExample(@Param(“record”) T record, @Param(“example”) Object example);
说明:根据Example条件更新实体record包含的全部属性,null值会被更新
方法:int updateByExampleSelective(@Param(“record”) T record, @Param(“example”) Object example);
说明:根据Example条件更新实体record包含的不是null的属性值
方法:int deleteByExample(Object example);
说明:根据Example条件删除数据
上面我们已经看到了Mapper4的强大了,实际开发中我们不用再写基本的CRUD了,直接调用提供方法即可。如果提供的方法不满足业务需求,再按照MyBatis方式添加即可。
下面介绍使用代码生成器生成代码,进一步简化开发量
https://github.com/abel533/Mapper/wiki/4.1.mappergenerator
这里只展示添加的插件部分,整个pom.xml请自行clone项目查看
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
<plugin>
<groupId>org.mybatis.generatorgroupId>
<artifactId>mybatis-generator-maven-pluginartifactId>
<version>1.3.7version>
<configuration>
<configurationFile>
${basedir}/src/main/resources/generatorConfig.xml
configurationFile>
<overwrite>trueoverwrite>
<verbose>trueverbose>
configuration>
<dependencies>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.29version>
dependency>
<dependency>
<groupId>tk.mybatisgroupId>
<artifactId>mapperartifactId>
<version>4.1.5version>
dependency>
dependencies>
plugin>
plugins>
build>
在/src/main/resources
下添加generatorConfig.xml
文件,文件内容如下(道友可根据注释提示,配置自己的项目)
<generatorConfiguration>
<context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat">
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<plugin type="tk.mybatis.mapper.generator.MapperPlugin">
<property name="mappers" value="com.springboot.ssm.common.mapper.MysqlBaseMapper"/>
<property name="caseSensitive" value="true"/>
<property name="forceAnnotation" value="true"/>
<property name="lombok" value="Data,Accessors"/>
plugin>
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/ssm?serverTimezone=Asia/Shanghai"
userId="root"
password="123456">
jdbcConnection>
<javaModelGenerator targetPackage="com.springboot.ssm.domain"
targetProject="src/main/java"/>
<sqlMapGenerator targetPackage="mapper"
targetProject="src/main/resources"/>
<javaClientGenerator targetPackage="com.springboot.ssm.mapper"
targetProject="src/main/java"
type="XMLMAPPER"/>
<table tableName="teacher">
<generatedKey column="id" sqlStatement="JDBC"/>
table>
context>
generatorConfiguration>
package com.springboot.ssm.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Data
@Accessors(chain = true)
@Table(name = "teacher")
public class Teacher {
/**
* 主键
*/
@Id
@Column(name = "id")
@GeneratedValue(generator = "JDBC")
private Integer id;
/**
* 姓名
*/
@Column(name = "name")
private String name;
}
package com.springboot.ssm.mapper;
import com.springboot.ssm.common.mapper.MysqlBaseMapper;
import com.springboot.ssm.domain.Teacher;
public interface TeacherMapper extends MysqlBaseMapper<Teacher> {
}
<mapper namespace="com.springboot.ssm.mapper.TeacherMapper">
<resultMap id="BaseResultMap" type="com.springboot.ssm.domain.Teacher">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
resultMap>
mapper>
大功告成!