SpringBoot + MyBatis-plus + Druid 实现简单增删查改、动态条件查询和分页功能

2023-11-19

本文主要讲解:SpringBoot集成Mybatis-plus,数据库连接池使用alibaba的druid,实现简单增删查改、动态条件查询和分页功能。

项目整体结构

项目添加相关框架依赖(pom.xml)

<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.0</modelVersion>
	<groupId>com.zzg</groupId>
	<artifactId>crm_sys</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.2.RELEASE</version>
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<!--starter -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		<!-- test -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<!--web -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!--validation -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-validation</artifactId>
		</dependency>
		<!--lombok -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>
		<!-- mybatis-plus 集成 -->
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>3.4.1</version>
		</dependency>
		<!-- 数据库连接池druid -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid-spring-boot-starter</artifactId>
			<version>1.1.10</version>
		</dependency>
		<!--mysql 驱动程序 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
	</dependencies>

	<!--集成mybatis-generator 自动生成组件 -->
	<build>
		<plugins>
			<plugin>
				<groupId>org.mybatis.generator</groupId>
				<artifactId>mybatis-generator-maven-plugin</artifactId>
				<version>1.3.7</version>
				<dependencies>
					<dependency>
						<groupId>mysql</groupId>
						<artifactId>mysql-connector-java</artifactId>
						<version>8.0.12</version>
					</dependency>
					<dependency>
						<groupId>org.mybatis.generator</groupId>
						<artifactId>mybatis-generator-core</artifactId>
						<version>1.3.7</version>
					</dependency>
				</dependencies>
				<executions>
					<execution>
						<id>Generate MyBatis Artifacts</id>
						<phase>package</phase>
						<goals>
							<goal>generate</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<!--允许移动生成的文件 -->
					<verbose>true</verbose>
					<!-- 是否覆盖 -->
					<overwrite>true</overwrite>
					<!-- 自动生成的配置 -->
					<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
				</configuration>
			</plugin>
		</plugins>
	</build>




</project>

项目资源文件配置(application.yml)

server:
  port: 8098
mybatis-plus:
  mapper-locations:classpath:/mapper/*Mapper.xml
  typeAliasesPackage:com.zzg.entity
spring:
  ##数据库连接信息
  datasource:
    url: jdbc:mysql://192.168.1.73:3306/boot-table?serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true&allowMultiQueries=true
    username: root
    password: digipower
    driver-class-name: com.mysql.cj.jdbc.Driver
    ###################以下为druid增加的配置###########################
    type: com.alibaba.druid.pool.DruidDataSource
    # 下面为连接池的补充设置,应用到上面所有数据源中
    # 初始化大小,最小,最大
    initialSize: 5
    minIdle: 5
    maxActive: 20
    # 配置获取连接等待超时的时间
    maxWait: 60000
    # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    timeBetweenEvictionRunsMillis: 60000
    # 配置一个连接在池中最小生存的时间,单位是毫秒
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    # 打开PSCache,并且指定每个连接上PSCache的大小
    poolPreparedStatements: true
    maxPoolPreparedStatementPerConnectionSize: 20
    # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall,log4j
    # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    # 合并多个DruidDataSource的监控数据
    useGlobalDataSourceStat: true
    ###############以上为配置druid添加的配置########################################

项目涉及(entity、mapper、service、serviceImpl 和Controller)

Controller 层定义

package com.zzg.controller;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zzg.common.controller.AbstractController;
import com.zzg.entity.User;
import com.zzg.service.UserService;

@Controller
@RequestMapping("/api/user")
public class UserController extends AbstractController<User> {

	@Autowired
	private UserService userService;

	// 增
	@RequestMapping(value = "/insert", method = { RequestMethod.POST }, produces = "application/json;charset=UTF-8")
	@ResponseBody
	public Object insert(@RequestBody User user) {
		return userService.save(user);
	}

	// 改
	@RequestMapping(value = "/update", method = { RequestMethod.POST }, produces = "application/json;charset=UTF-8")
	@ResponseBody
	public Object update(@RequestBody User user) {
		return userService.updateById(user);
	}

	// 删
	@RequestMapping(value = "/delete/{id}", method = { RequestMethod.DELETE })
	@ResponseBody
	public Object delete(@PathVariable("id") Integer id) {
		return userService.removeById(id);
	}

	// 查
	@RequestMapping(value = "/getUserByName", method = { RequestMethod.GET })
	@ResponseBody
	public Object getUserByName(@RequestParam String userName) {
		QueryWrapper<User> query = new QueryWrapper<User>();
		query.like("username", userName);
		return userService.getOne(query);
	}

	// 查
	@RequestMapping(value = "/getId", method = { RequestMethod.GET })
	@ResponseBody
	public Object getId(@RequestParam Integer id) {
		return userService.getById(id);
	}
	
	// 查
	@RequestMapping(value = "/getPage", method = { RequestMethod.POST })
	@ResponseBody
	public Object getPage(@RequestBody Map<String, Object> parame) {
		Page<User> page = this.initPageBounds(parame);
		return userService.page(page);
	}
	

}

entity 定义

package com.zzg.entity;

import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@SuppressWarnings("serial")
@Data
@TableName("user")
public class User implements Serializable {
	@TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    private String username;

    private String password;

    private String email;

    private String phone;

    private String question;

    private String answer;

    private Integer role;
    
    private Date createTime;
    
    private Date updateTime;

   
}

mapper 定义:

package com.zzg.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zzg.entity.User;

public interface UserMapper extends BaseMapper<User> {
}

service 和serviceImpl 定义:

package com.zzg.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.zzg.entity.User;

public interface UserService extends IService<User> {
}
package com.zzg.service.impl;

import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzg.entity.User;
import com.zzg.mapper.UserMapper;
import com.zzg.service.UserService;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
	
}

项目涉及(common、util之转换、程序入口、全局配置对象)

common 之公共抽象Controller

package com.zzg.common.controller;

import java.util.Map;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zzg.util.converter.SimpleTypeConverterUtil;



public abstract class AbstractController<T> {
	public static final String PAGE = "page";
	
	public static final String LIMIT = "limit";
	
	/**
	 * 参数分页参数转换校验
	 * 
	 * @param param
	 * @return
	 */
	protected Page<T> initPageBounds(Map<String, Object> param) {
		int page = SimpleTypeConverterUtil.convertIfNecessary(param.get(PAGE), int.class);
		int limit = SimpleTypeConverterUtil.convertIfNecessary(param.get(LIMIT), int.class);
		// 页码和页数取消最大限制
		page = (page <= 0) ? 1 : page;
		limit = (limit <= 0) ? 10 : limit;
		return new Page<T>(page, limit);
	}
}

Util之数据类型转换:

package com.zzg.util.converter;

import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.SimpleTypeConverter;


public class SimpleTypeConverterUtil {
public static final Logger log = LoggerFactory.getLogger(SimpleTypeConverterUtil.class);
	
	private static final SimpleTypeConverter typeConverterDelegate = new SimpleTypeConverter();
	static{
		typeConverterDelegate.registerCustomEditor(Date.class, new DateEditor());
	}
	
	/**
	 * @param <T>
	 * @param value  待转换值,一般字符串
	 * @param requiredType 转后类型类对象
	 * @return
	 */
	public static <T> T convertIfNecessary(Object value, Class<T> requiredType) {
		T rs = null;
		try {
			rs = typeConverterDelegate.convertIfNecessary(value, requiredType);
		} catch (Exception e) {
			log.info(e.getMessage());
			if(requiredType == int.class || requiredType == Integer.class){
				rs = (T)Integer.valueOf(0);
			}
		}
		return rs;
	}
}
package com.zzg.util.converter;

import java.lang.management.ManagementFactory;
import java.text.DateFormat;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class DateUtils {
public static final Logger log = LoggerFactory.getLogger(DateUtils.class);
	
	public static final String YYYY = "yyyy" ;

    public static final String YYYY_MM = "yyyy-MM" ;

    public static final String YYYY_MM_DD = "yyyy-MM-dd" ;

    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss" ;

    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss" ;

    private static String[] parsePatterns = {
            YYYY_MM_DD , YYYY_MM_DD_HH_MM_SS , "yyyy-MM-dd HH:mm" , YYYY_MM ,
            "yyyy/MM/dd" , "yyyy/MM/dd HH:mm:ss" , "yyyy/MM/dd HH:mm" , "yyyy/MM" ,
            "yyyy.MM.dd" , "yyyy.MM.dd HH:mm:ss" , "yyyy.MM.dd HH:mm" , "yyyy.MM"};

    /**
     * 获取当前Date型日期
     *
     * @return Date() 当前日期
     */
    public static Date getNowDate() {
        return new Date();
    }

    /**
     * 获取当前日期, 默认格式为yyyy-MM-dd
     *
     * @return String
     */
    public static String getDate() {
        return dateTimeNow(YYYY_MM_DD);
    }

    public static final String getTime() {
        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
    }

    public static final String dateTimeNow() {
        return dateTimeNow(YYYYMMDDHHMMSS);
    }

    public static final String dateTimeNow(final String format) {
        return parseDateToStr(format, new Date());
    }

    public static final String dateTime(final Date date) {
        return parseDateToStr(YYYY_MM_DD, date);
    }

    public static final String parseDateToStr(final String format, final Date date) {
    	if (date == null) {
            return null;
        }

        Format formatter = new SimpleDateFormat(format);
        return formatter.format(date);
    }

    /**
     * 获取服务器启动时间
     */
    public static Date getServerStartDate() {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }
    
    private static final List<DateFormat> formarts = new ArrayList<>(5);
	static {
		formarts.add(new SimpleDateFormat("yyyy-MM"));
		formarts.add(new SimpleDateFormat("yyyy-MM-dd"));
		formarts.add(new SimpleDateFormat("yyyy-MM-dd hh:mm"));
		formarts.add(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"));
		formarts.add(new SimpleDateFormat("yyyy.MM.dd"));
	}

	public static Date formatDateStr(String source) {
		String value = source.trim();
		if ("".equals(value)) {
			return null;
		}
		try {
			if (source.matches("^\\d{4}-\\d{1,2}$")) {
				return formarts.get(0).parse(source);
			} else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")) {
				return formarts.get(1).parse(source);
			} else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}$")) {
				return formarts.get(2).parse(source);
			} else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")) {
				return formarts.get(3).parse(source);
			} else if (source.matches("^\\d{4}.\\d{1,2}.\\d{1,2}$")) {
				return formarts.get(4).parse(source);
			} else {
				throw new IllegalArgumentException("Invalid boolean value '" + source + "'");
			}
		} catch (Exception e) {
			log.warn("DateUtils.formatDateStr error", e);
			return null;
		}
	}

    /**
     * 计算两个时间差
     */
    public static String getDatePoor(Date endDate, Date nowDate) {
        long nd = (long)1000 * 24 * 60 * 60;
        long nh = (long)1000 * 60 * 60;
        long nm = (long)1000 * 60;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        return day + "天" + hour + "小时" + min + "分钟" ;
    }
}
package com.zzg.util.converter;

import java.beans.PropertyEditorSupport;


public class DateEditor extends PropertyEditorSupport {
	@Override
	public void setAsText(String text) throws IllegalArgumentException {
		setValue(DateUtils.formatDateStr(text));
	}
}

程序入口:

package com.zzg;

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


@SpringBootApplication
@MapperScan("com.zzg.mapper")
public class CRMApplication {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		SpringApplication.run(CRMApplication.class, args);
		System.out.println("============= SpringBoot CRM Project Start Success =============");
	}

}

全局配置对象

package com.zzg.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;

@Configuration
public class MybatisPlusConfig {
	/**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor page = new PaginationInterceptor();
        //设置方言类型
        page.setDialectType("mysql");
        return page;
    }
}

项目初始化SQL

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户表id',
  `username` varchar(50) NOT NULL COMMENT '用户名',
  `password` varchar(50) NOT NULL COMMENT '用户密码,MD5加密',
  `email` varchar(50) DEFAULT NULL,
  `phone` varchar(20) DEFAULT NULL,
  `question` varchar(100) DEFAULT NULL COMMENT '找回密码问题',
  `answer` varchar(100) DEFAULT NULL COMMENT '找回密码答案',
  `role` int(4) NOT NULL COMMENT '角色0-管理员,1-普通用户',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `update_time` datetime NOT NULL COMMENT '最后一次更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `user_name_unique` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8;
SET FOREIGN_KEY_CHECKS = 1;

INSERT INTO `user`(`id`, `username`, `password`, `email`, `phone`, `question`, `answer`, `role`, `create_time`, `update_time`) VALUES (1, 'admin', '432D38237BD939443EC5D48E24FD3B1A', 'admin@admin.com', '13800138000', '问题', '答案', 1, '2016-11-06 16:56:45', '2017-04-04 19:27:36');

技术文档:

MyBatis-plus 官网

github 代码地址:https://github.com/zhouzhiwengang/crm_sys.git

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringBoot + MyBatis-plus + Druid 实现简单增删查改、动态条件查询和分页功能 的相关文章

随机推荐

  • 宝塔 Error: BT-Task service startup failed. 问题原因以及解决方法

    因为我个人电脑用的是py3 所以自带py2的宝塔就自以为是升级了 还替换掉了宝塔的py2 因为py2和py3包和语法有部分不一样 所以不能用 导致重启服务器后失效 解决方法就是替换回来 先看看现在的Python版本 python v 如果是
  • Excel脱拽或者下拉公式时, 保持公式里单元格数字不变

    绝对引用 可以选中B1 用F4快捷键自己就给加绝对引用符号了 然后回车 复制或者拖拽 转载于 https www cnblogs com baxianhua p 9995530 html
  • SSL与TLS工作原理

    链接 https zhuanlan zhihu com p 36981565 为了保证网络通信的安全性 需要对网络上传递的数据进行加密 现在主流的加密方法就是SSL Secure Socket Layer TLS Transport Lay
  • 第5讲:VUE3工程中实现页面加载中效果和页面切换动画效果。

    VUE3工程发布后的运行过程为先加载html面 再通过html页中的js加载单页面js来渲染页面并显示 根据这个加载过程 实现页面加载中的原理是预先在html中显示加载中 再单页面数据加载完成在mounted时隐藏加载中 即实现想要的效果
  • 轻量级分割网络总结

    目录 ddrnet STDC Seg 重新思考BiSeNet ExtremeC3Net DFANet NfS SegNet 好像未开源 人像分割
  • 操作系统常见面试题及答案

    操作系统 从系统观点看 是计算机系统的一个系统软件 管理和控制计算机系统中的资源 从用户观点看 操作系统是用户与计算机之间的接口 从软件观点看 操作系统是程序和数据结构的集合 1 什么是进程 process 和线程 thread 有何区别
  • linux中esc无法正常退出insert

    ctrl c
  • 在android 输出log 信息 用于调试

    要想在 jni native 代码中看打印信息 printf 是不行的 需使用 android log print 如下所示 android log print ANDROID LOG INFO ProjectName I am d n n
  • python的文件操作

    一 文件的基本操作 1 读文件read f open filename r encoding utf 8 data f read 读文件 f close 关闭文件 1 绝对路径的易错点 文件路径中 前要加转义字符 或者 使用r使转义字符失效
  • Android declare-styleable:自定义控件的属性(attr.xml,TypedArray)的使用

    android 自定义属性类型的使用 转自 http www cnblogs com ufocdy archive 2011 05 27 2060221 html 做Android布局是件很享受的事 这得益于他良好的xml方式 使用xml可
  • 关于define与defined的区别

    1 define用来定义一个常量 常量也是全局范围的 不用管作用域就可以在脚本的任何地方访问 常量 一个常量一旦被定义 就不能再改变或者取消定义 如 define path root www web define 为常量的值root www
  • 什么是计算机域名和域名定义?

    domain is a very popular term used in computer and information technology Users generally do not know or misinterpret th
  • BAT面试题 - 找一个无序实数数组中的最大差值

    题目描述 一个无序的实数数组a i 要求求里面大小相邻的实数的差的最大值 比如 double a 1 5 4 0 2 100 这个无序的数组 相邻的数的最大差值为100 5 95 题目分析 这题有个简单的做法 首先就是对数组进行一个排序 然
  • 免费送书啦!细数Github大神们的开源书籍!

    作者 弗拉德 来源 弗拉德 公众号 fulade me Go 系列 Mastering GO 推荐语 本书适用于Golang程序员 您之前应该阅读有关Go的介绍性书籍 本书的内容包括但不限于并发 网络编程 垃圾回收 组合 GO UNIX系统
  • STM32F10X_系统定时器(systick)

    目录 1 参考文献 2 systick简介 3 systick寄存器 3 1 控制及状态寄存器 3 2 重装载数值寄存器 3 3 当前数值寄存器 3 4 校准数值寄存器 4 systick中断时间计算 5 systick配置库函数 1 参考
  • YOLOv5 提升模型训练结果小技巧

    一 数据集 1 每类图片数 建议 gt 1500张 2 每类实例数 推荐每类标签实例数 gt 10000 3 图片多样性 必须代表部署环境 对于现实世界我们推荐图片来自一天中不同时间 不同季节 不同天气 不同光照 不同角度和不同相机等 4
  • 线程封闭概念

    线程封闭概念 为什么要有线程封闭这个概念呢 多线程中访问共享可变数据时 涉及到线程间数据同步的问题 并不是所有时候都需要共享数据 所以线程封闭概念就出来了 在Java中线程封闭该怎么做呢 可以通过两个方法来做 ThreadLocal 1 T
  • 34 openEuler使用LVM管理硬盘-创建并挂载文件系统

    文章目录 34 openEuler使用LVM管理硬盘 创建并挂载文件系统 34 1 创建文件系统 34 2 手动挂载文件系统 34 3 自动挂载文件系统 34 openEuler使用LVM管理硬盘 创建并挂载文件系统 在创建完逻辑卷之后 需
  • android代码获取当前package的de目录

    获取de目录首先要获取DE CONTEXT Context deContext getApplicationContext createDeviceProtectedStorageContext 然后通过DE CONTEXT获取de目录 S
  • SpringBoot + MyBatis-plus + Druid 实现简单增删查改、动态条件查询和分页功能

    本文主要讲解 SpringBoot集成Mybatis plus 数据库连接池使用alibaba的druid 实现简单增删查改 动态条件查询和分页功能 项目整体结构 项目添加相关框架依赖 pom xml