Springboot 整合tk-mybatis , 妈妈,我再也不想敲CRUD的代码了!

简介: Springboot 整合tk-mybatis , 妈妈,我再也不想敲CRUD的代码了!

前言


 

码农这一生,做的最多的四件事,不是吃喝玩乐,而是  增加(Create)、检索(Retrieve)、更新(Update)和删除(Delete)  。

 

泪目。

 

为何我要写这篇文章,是有感而发,请看图:


image.png


哈哈,虽然看着图一乐,但是大部分码农的工作生活确实现状如此。


也许会有人说了,其实很多crud的代码也只是复制粘贴而已,稍微改改就好。


这确实没错,但是人天性嗜懒,日复一日,不免对复制粘贴也产生了些许倦意。


那么为了我们每天都能元气满满,我们尽可能减少大部分我们‘重复’ 的代码。



曾写过一篇 Springboot 整合Mybatis 使用Mybatis-plus 敏捷开发 ,也是可以省掉非常多的crud代码

那么今天,我需要介绍给大家的是 TK-Mybatis。

 

正文


 

惯例,今天的实战实例目录结构:


image.png


目前不管是mybatis-plus ,还是tk-mybatis。 帮我们省掉的代码,其实都是对于单表操作而言。


(所以一些复杂的sql语句,我们还是可以自己额外编写,所以额外编写的,我们如往常一样写在mapper.xml里面即可)


也就是说,对于单独一个表的crud操作,一些常规的crud相关代码,都是可以帮我们省掉的,我们不用再写了,包括不仅限于:


1.查询该表所有数据
2.根据条件该表查询该表所有数据
3.根据主键该表查询该表单个数据
4.根据条件查询该表单个数据
5.检测数据是否存在
6.统计该表数据条数
7.根据主键删除数据
8.根据条件删除数据
9.根据主键修改数据
10.根据条件修改数据
11.新增数据
12.分页查询
13.当然还有挺多,不一一列举了


创建一个springboot项目,在pom.xml里导入用到的依赖:


        <!--jdbc驱动-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!--mybatis操作数据库有关-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!--连接mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--使用阿里巴巴的druid数据源,有利于监控sql的执行情况-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!--通用mapper-->
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>2.1.2</version>
        </dependency>
        <!--添加lombok支持,可以省掉写get和set方法-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
            <optional>true</optional>
        </dependency>
        <!--使用fastjson来操作json数据-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.58</version>
        </dependency>
        <!--spring boot web方面的支持-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.1.4.RELEASE</version>
        </dependency>


数据库表,简单一张表:


image.png


对于的User.java实体类:


import lombok.Data;
import javax.persistence.*;
/**
 * @Author : JCccc
 * @CreateTime : 2020/8/13
 * @Description :
 **/
@Data
@Table(name="user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY,generator = "JDBC")
    private Integer id;
    @Column(name = "name")
    private String name;
    @Column(name = "age")
    private Integer age;
}


然后是UserMapper.java(注意看细节,继承了Mapper<User>  来自于tk-mybatis),只要继承了这个Mapper,那么文章前头提到的那些代码和sql,我们都不用再去写了,我们只需要写一些多表的,业务复杂的需要额外扩展的就行。:


import tk.mybatis.mapper.common.Mapper;
import java.util.List;
import java.util.Map;
/**
 * @Author : JCccc
 * @CreateTime : 2020/8/13
 * @Description :
 **/
public interface UserMapper extends Mapper<User> {
    //额外扩展的方法,如一些复杂的查询语句等
    List<Map> getMyCustom(int age);
}


细心的人发现了,我们这次的mapper上面没有写@Mapper。


是的,我们现在进行一个关键的操作,在启动类上,使用tk-mybatis的扫描mapper注解:


image.png


pojo和mapper 两层已经完毕了,那么对接持久层需要做的我们已经完毕了。


service层,我们在这层为了方面项目的扩展,后期能省掉更多的接口复写代码(是不是很多人很烦service层里面的代码跟mapper层对于一些普通的crud操作,基本代码没什么区别),


我们需要做一个base层,也就是后续其他业务的表扩展,都同一继承和实现base层即可。


BaseService.java :


import org.apache.ibatis.session.RowBounds;
import tk.mybatis.mapper.common.Mapper;
import java.util.List;
/**
 * @Author : JCccc
 * @CreateTime : 2020/8/13
 * @Description :
 **/
public interface BaseService<T> extends Mapper<T> {
    @Override
    int deleteByPrimaryKey(Object o);
    @Override
    int delete(T o);
    @Override
    int insert(T o);
    @Override
    int insertSelective(T o);
    @Override
    List<T> selectAll();
    @Override
    T selectByPrimaryKey(Object o);
    @Override
    public int selectCount(T o);
    @Override
    public List<T> select(T o);
    @Override
    public T selectOne(T o);
    @Override
    public int updateByPrimaryKey(T o);
    @Override
    public int updateByPrimaryKeySelective(T o);
    @Override
    public int deleteByExample(Object o);
    @Override
    public List<T> selectByExample(Object o);
    @Override
    public int selectCountByExample(Object o);
    @Override
    public T selectOneByExample(Object o);
    @Override
    public int updateByExample(T o, Object o2);
    @Override
    public int updateByExampleSelective(T o, Object o2);
    @Override
    public List<T> selectByExampleAndRowBounds(Object o, RowBounds rowBounds);
    @Override
    public List<T> selectByRowBounds(T o, RowBounds rowBounds);
}


BaseServiceImpl.java:


import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.common.Mapper;
import java.util.List;
/**
 * @Author : JCccc
 * @CreateTime : 2020/8/13
 * @Description :
 **/
public abstract class BaseServiceImpl<T> implements BaseService<T> {
    @Autowired
    private Mapper<T> mapper;
    @Override
    public int deleteByPrimaryKey(Object o) {
        return mapper.deleteByPrimaryKey(o);
    }
    @Override
    public int delete(T t) {
        return mapper.delete(t);
    }
    @Override
    public int insert(T t) {
        return mapper.insert(t);
    }
    @Override
    public int insertSelective(T t) {
        return mapper.insertSelective(t);
    }
    @Override
    public List<T> selectAll() {
        return mapper.selectAll();
    }
    @Override
    public int selectCount(T t) {
        return mapper.selectCount(t);
    }
    @Override
    public List<T> select(T t) {
        return mapper.select(t);
    }
    @Override
    public T selectOne(T t) {
        return mapper.selectOne(t);
    }
    @Override
    public int updateByPrimaryKey(T t) {
        return mapper.updateByPrimaryKey(t);
    }
    @Override
    public int updateByPrimaryKeySelective(T t) {
        return mapper.updateByPrimaryKeySelective(t);
    }
    @Override
    public int deleteByExample(Object t) {
        return mapper.deleteByExample(t);
    }
    @Override
    public List<T> selectByExample(Object t) {
        return mapper.selectByExample(t);
    }
    @Override
    public int selectCountByExample(Object t) {
        return mapper.selectCountByExample(t);
    }
    @Override
    public T selectOneByExample(Object o) {
        return mapper.selectOneByExample(o);
    }
    @Override
    public int updateByExample(T t, Object o) {
        return mapper.updateByExample(t, o);
    }
    @Override
    public int updateByExampleSelective(T t, Object o) {
        return mapper.updateByExampleSelective(t, o);
    }
    @Override
    public List<T> selectByExampleAndRowBounds(Object o, RowBounds rowBounds) {
        return mapper.selectByExampleAndRowBounds(o, rowBounds);
    }
    @Override
    public List<T> selectByRowBounds(T t, RowBounds rowBounds) {
        return mapper.selectByRowBounds(t, rowBounds);
    }
    @Override
    public boolean existsWithPrimaryKey(Object o) {
        return mapper.existsWithPrimaryKey(o);
    }
    @Override
    public T selectByPrimaryKey(Object o) {
        return mapper.selectByPrimaryKey(o);
    }
}


ok,业务层的base层已经完成,回归业务,

 

UserService.java:


import com.jc.tkmybatis.base.BaseService;
import com.jc.tkmybatis.pojo.User;
import java.util.List;
import java.util.Map;
/**
 * @Author : JCccc
 * @CreateTime : 2020/8/13
 * @Description :
 **/
public interface UserService extends BaseService<User> {
    //仅仅需要编写额外扩展的业务方法
    List<Map>  getMyCustom(int age);
}


UserServiceImpl.java:


import com.jc.tkmybatis.base.BaseServiceImpl;
import com.jc.tkmybatis.mapper.UserMapper;
import com.jc.tkmybatis.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
 * @Author : JCccc
 * @CreateTime : 2020/8/13
 * @Description :
 **/
@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements UserService {
    //UserMapper需要继承tk-myabtis的Mapper,这样才能顺利使用到tk-mybatis帮我们写好的N多mapper层方法和sql语句
    @Autowired
     UserMapper userMapper;
    //仅仅需要编写额外扩展的业务方法
    @Override
    public List<Map> getMyCustom(int age) {
        return userMapper.getMyCustom(age);
    }
}


到这里,我们其实整合tk-mybatis已经完毕了!(后面有controller层来演示怎么使用)


因为我们为了确保可以额外扩展,我们还是建了mapper.xml的,所以我们在yml加上对于的mapper.xml文件扫描配置:


mybatis:
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml


对于userMapper.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.jc.tkmybatis.mapper.UserMapper">
    <select id="getMyCustom" resultType="java.util.HashMap">
      SELECT *
      FROM  user
      WHERE age>=#{age}
    </select>
</mapper>


mybatis-config.xml:


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="useGeneratedKeys" value="true"/>
        <setting name="useColumnLabel" value="true"/>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
</configuration>


controller层,我们写一些curd的接口来进行使用测试:


UserController.java


PS: 我们在controller层注入 UserService后,我们就可以使用tk-mybatis帮我们实现的那一堆方法了。


image.png

import com.jc.tkmybatis.pojo.User;
import com.jc.tkmybatis.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
/**
 * @Author : JCccc
 * @CreateTime : 2020/8/13
 * @Description :
 **/
@RestController
public class UserController {
    @Autowired
    UserService userService;
    /**
     * 新增
     * @return
     */
    @PostMapping("addOne")
    public int addOne() {
        User user=new User();
        user.setName("jc");
        user.setAge(10);
        return userService.insert(user);
    }
    /**
     * 获取所有 分页
     * @return
     */
    @GetMapping("getAllByPage")
    public List<User> getAllByPage() {
        RowBounds rowBounds=new RowBounds(0,3);
        return userService.selectByRowBounds(new User(),rowBounds);
    }
    /**
     * 获取某个
     * @return
     */
    @GetMapping("getOne")
    public User getOne() {
        User user=new User();
        user.setId(1);
        return userService.selectOne(user);
    }
    /**
     * 获取所有
     * @return
     */
    @GetMapping("getAll")
    public List<User> getAll() {
        return userService.selectAll();
    }
    /**
     * 修改
     * @return
     */
    @GetMapping("updateOne")
    public int updateOne() {
        User user=new User();
        user.setId(1);
        user.setName("TG");
        return userService.updateByPrimaryKeySelective(user);
    }
    /**
     * 额外扩展的
     * @return
     */
    @GetMapping("getMyCustom")
    public List<Map> getMyCustom() {
        return userService.getMyCustom(1);
    }
}


接口的测试,大家自行使用postman或者api post等测试就ok,我就不一一列举了。


ps: 上面代码里面的分页查询,是用到了tk-mybatis里的方法 selectByRowBounds 。


习惯用pagehelper的依然可以使用,添加分页插件依赖:


        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.5</version>
        </dependency>


使用示例:


    /**
     * 获取所有 分页 PageHelper
     * @return
     */
    @GetMapping("getAllByPage")
    public PageInfo getAll() {
        PageHelper.startPage(1, 2);
        PageInfo pageInfo = new PageInfo(userService.selectAll());
        return pageInfo;
    }


到此,大家应该是学会整合使用了,我建议,我们不仅要求自己处于单纯的使用,稍微深入一点点了解也是需要的(这样说不定突然感兴趣了,自己就去深挖了)。


抛砖引玉


为什么能省掉这么多代码?  


说白了,就是tk-mybatis帮我们写了呗。


我们知道mapper是对接持久层的,那么我们看看我们mapper做了什么?  没错,就是继承了tk-mybatis的Mapper<T>:


image.png


我们需要的就是了解这些Mapper里面有哪些方法,例如


BaseMapper<T> :


        /**
   * 保存一个实体,null属性也会保存
   * 
   * @param record
   * @return
   */
  int insert(T record);
  /**
   * 保存一个实体,null属性不会保存
   * 
   * @param record
   * @return
   */
  int insertSelective(T record);
  /**
   * 根据实体属性作为条件进行删除,查询条件使用等号
   */
  int delete(T record);
  /**
   * 根据主键更新属性不为null的值
   */
  int updateByPrimaryKeySelective(T record);
  /**
   * 根据实体中的属性值进行查询,查询条件使用等号
   */
  List<T> select(T record);
  /**
   * 查询全部结果,select(null)方法能达到同样的效果
   */
  List<T> selectAll();
  /**
   * 根据实体中的属性进行查询,只能有一个返回值,有多个结果是抛出异常,查询条件使用等号
   */
  T selectOne(T record);
  /**
   * 根据实体中的属性查询总数,查询条件使用等号
   */
  int selectCount(T record);


ExampleMapper ,RowBoundsMapper 这些也是需要了解的(小声说下,认真操作的在文章前面有些方法用到了RowBounds,其实是用来分页的~ )。


这篇文章算是一个tk-mybatis的整合引玉篇吧,把BaseService里面的方法都使用调试下,那么使用层面应该没有问题了。

相关文章
|
3天前
|
Java 数据安全/隐私保护 Spring
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效
|
1天前
|
前端开发 IDE Java
"揭秘前端转Java的秘径:SpringBoot Web极速入门,掌握分层解耦艺术,让你的后端代码飞起来,你敢来挑战吗?"
【8月更文挑战第19天】面向前端开发者介绍Spring Boot后端开发,通过简化Spring应用搭建,快速实现Web应用。本文以创建“Hello World”应用为例,展示项目基本结构与运行方式。进而深入探讨三层架构(Controller、Service、DAO)下的分层解耦概念,通过员工信息管理示例,演示各层如何协作及依赖注入的使用,以此提升代码灵活性与可维护性。
|
4天前
|
Java 关系型数据库 MySQL
1、Mybatis-Plus 创建SpringBoot项目
这篇文章是关于如何创建一个SpringBoot项目,包括在`pom.xml`文件中引入依赖、在`application.yml`文件中配置数据库连接,以及加入日志功能的详细步骤和示例代码。
|
6天前
|
前端开发 Java 数据库连接
一天十道Java面试题----第五天(spring的事务传播机制------>mybatis的优缺点)
这篇文章总结了Java面试中的十个问题,包括Spring事务传播机制、Spring事务失效条件、Bean自动装配方式、Spring、Spring MVC和Spring Boot的区别、Spring MVC的工作流程和主要组件、Spring Boot的自动配置原理和Starter概念、嵌入式服务器的使用原因,以及MyBatis的优缺点。
|
5天前
|
Java 数据库连接 mybatis
基于SpringBoot+MyBatis的餐饮点餐系统
本文介绍了一个基于SpringBoot和MyBatis开发的餐饮点餐系统,包括系统的主控制器`IndexController`的代码实现,该控制器负责处理首页、点餐、登录、注册、订单管理等功能,适用于毕业设计项目。
9 0
基于SpringBoot+MyBatis的餐饮点餐系统
|
5天前
|
XML SQL JavaScript
在vue页面引入echarts,图表的数据来自数据库 springboot+mybatis+vue+elementui+echarts实现图表的制作
这篇文章介绍了如何在Vue页面中结合SpringBoot、MyBatis、ElementUI和ECharts,实现从数据库获取数据并展示为图表的过程,包括前端和后端的代码实现以及遇到的问题和解决方法。
在vue页面引入echarts,图表的数据来自数据库 springboot+mybatis+vue+elementui+echarts实现图表的制作
|
6天前
|
SQL Java 数据库连接
springboot+mybatis+shiro项目中使用shiro实现登录用户的权限验证。权限表、角色表、用户表。从不同的表中收集用户的权限、
这篇文章介绍了在Spring Boot + MyBatis + Shiro项目中,如何使用Shiro框架实现登录用户的权限验证,包括用户、角色和权限表的设计,以及通过多个表查询来收集和验证用户权限的方法和代码实现。
springboot+mybatis+shiro项目中使用shiro实现登录用户的权限验证。权限表、角色表、用户表。从不同的表中收集用户的权限、
|
9天前
|
安全 Java Shell
"SpringBoot防窥秘籍大公开!ProGuard混淆+xjar加密,让你的代码穿上隐形斗篷,黑客也无奈!"
【8月更文挑战第11天】开发SpringBoot应用时,保护代码免遭反编译至关重要。本文介绍如何运用ProGuard和xjar强化安全性。ProGuard能混淆代码,去除未使用的部分,压缩字节码,使反编译困难。需配置ProGuard规则文件并处理jar包。xjar则进一步加密jar包内容,即使被解压也无法直接读取。结合使用这两种工具可显著提高代码安全性,有效保护商业机密及知识产权。
37 3
|
15天前
|
Java API 数据格式
Spring Boot API参数读取秘籍大公开!6大神器助你秒变参数处理大师,让你的代码飞起来!
【8月更文挑战第4天】Spring Boot凭借其便捷的开发和配置特性,成为构建微服务的热门选择。高效处理HTTP请求参数至关重要。本文介绍六种核心方法:查询参数利用`@RequestParam`;路径变量采用`@PathVariable`;请求体通过`@RequestBody`自动绑定;表单数据借助`@ModelAttribute`或`@RequestParam`;请求头使用`@RequestHeader`;Cookie则依靠`@CookieValue`。每种方法针对不同场景,灵活运用可提升应用性能与用户体验。
39 9
|
19天前
|
XML Java 数据库连接
Spring Boot集成MyBatis
主要系统的讲解了 Spring Boot 集成 MyBatis 的过程,分为基于 xml 形式和基于注解的形式来讲解,通过实际配置手把手讲解了 Spring Boot 中 MyBatis 的使用方式,并针对注解方式,讲解了常见的问题已经解决方式,有很强的实战意义。在实际项目中,建议根据实际情况来确定使用哪种方式,一般 xml 和注解都在用。