【Springboot+mybatisPlus+mysql+thymeleaf实现crud】

Springboot+mybatisPlus+mysql+thymeleaf实现crud


代码链接-spring-boot-mybatis-plus
Springboot学习

Mybatis Plus

简介

MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

愿景

我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。

img

#特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

#支持数据库

任何能使用 MyBatis 进行 CRUD, 并且支持标准 SQL 的数据库,具体支持情况如下,如果不在下列表查看分页部分教程 PR 您的支持。

  • MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,ClickHouse,Sybase,OceanBase,Firebird,Cubrid,Goldilocks,csiidb,informix,TDengine,redshift
  • 达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库,优炫数据库

#框架结构

framework

Springboot+mybatisPlus+mysql+thymeleaf

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fK1TuygR-1679234128051)(image/image-20230319214436002.png)]

pom.xml

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.4</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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-extension</artifactId>
            <version>3.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.21</version>
        </dependency>

        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.30</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.5.4</version>
            </plugin>
        </plugins>

application.yml

server:
  port: 8080
# DataSource Config
spring:
  application:
    name: user
  thymeleaf:
    cache: false
  datasource:
    url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=false&serverTimezone=UTC
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis-plus:
  # mapper配置文件。可能有多个,所以Mapper.xml结尾的都添加进来
  mapper-locations: classpath:mapper/*Mapper.xml
  configuration:
    # 类属性与表字段的驼峰映射,mybatis plus默认true开启,mybatis需要手动配置,且config-location和configuration不能同时出现
    map-underscore-to-camel-case: true
    # 配置日志输出
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl


# Logger Config
logging:
  level:
    com.neo: debug

MybatisPlusConfig.java

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
@MapperScan("com.neo.mapper")
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);
        return mybatisPlusInterceptor;
    }

}

User.java

package com.neo.model;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

@TableName(value = "t_user")
public class User {

    /**
     * 用户表主键Id
     */
    @TableId
    private String userId;

    /**
     * 用户姓名
     */
    private String userName;

    /**
     * 用户年龄
     */
    private String userAge;

    /**
     * 用户住址
     */
    private String userAddr;

    /**
     * 用户性别
     */
    private String userSex;

    /**
     * 用户电话号码
     */
    private String userPhone;


    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserAge() {
        return userAge;
    }

    public void setUserAge(String userAge) {
        this.userAge = userAge;
    }

    public String getUserAddr() {
        return userAddr;
    }

    public void setUserAddr(String userAddr) {
        this.userAddr = userAddr;
    }

    public String getUserSex() {
        return userSex;
    }

    public void setUserSex(String userSex) {
        this.userSex = userSex;
    }

    public String getUserPhone() {
        return userPhone;
    }

    public void setUserPhone(String userPhone) {
        this.userPhone = userPhone;
    }
}

UserService.java

package com.neo.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.neo.model.User;

import java.util.List;

public interface UserService extends IService<User> {

    List<User> getUserByUserAge(String userAge);
}

UserServiceImpl.java

package com.neo.service.impl;


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

import java.util.List;

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


    @Override
    public List<User> getUserByUserAge(String userAge) {
        return this.baseMapper.getUserByUserAge(userAge);
    }
}

MyBatisPlusApplication.java

package com.neo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


/**
 * http://localhost:8080/api/v1/user/list
 */
@SpringBootApplication
public class MyBatisPlusApplication {

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

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.neo.mapper.UserMapper">

    <select id="getUserByUserAge" parameterType="java.lang.String" resultType="com.neo.model.User">
        select
            user_Id, user_name, user_age, user_addr, user_sex, user_phone
        from t_user t
        where t.user_age &gt; #{userAge}
    </select>

</mapper>

add.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>添加用户</title>
    <!--<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">-->
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
</head>

<body>

<div style="width:400px;height:100%;margin-left:450px;margin-top:100px;">
    <form action="/api/v1/user/add" method="post">
        姓 名:<input class="form-control"  type="text" th:value="${userName}" name="userName"><br>
        年 龄:<input class="form-control" type="text" th:value="${userAge}" name="userAge"><br>
        住 址:<input class="form-control" type="text" th:value="${userAddr}" name="userAddr"><br>
        性 别:<input class="form-control" type="text" th:value="${userSex}" name="userSex"><br>
        电话号码:<input class="form-control" type="text" th:value="${userPhone}" name="userPhone"><br>
        <button class="btn btn-primary btn-lg btn-block">保存</button>
    </form>
</div>

</body>
</html>



login.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>用户列表</title>
    <!-- 引入 Bootstrap -->
    <!--
        <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
    -->
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">

</head>

<style>
    a {
        color: #ffffff;
    }

    h1 {
        /*文字对齐*/
        text-align: center;
    }
</style>

<body>

<div class="container">
    <button class="btn btn-success pull-right"><a th:href="@{'/api/v1/user/insert'}">添加用户</a></button>
    <h1>用户管理系统</h1>
    <!--table-striped:斑马线格式,table-bordered:带边框的表格,table-hover:鼠标悬停高亮的表格-->
    <table class="table table-striped table-bordered table-hover text-center">
        <thead>
        <tr style="text-align:center">
            <!--        th标签定义html表格中的表头单元格-->
            <th style="text-align:center">姓名</th>
            <th style="text-align:center">年龄</th>
            <th style="text-align:center">住址</th>
            <th style="text-align:center">性别</th>
            <th style="text-align:center">电话号码</th>
        </tr>
        </thead>
        <!--tr标签定义html表格中的所有行-->
        <!--    遍历集合,如果被遍历的变量users为null或者不存在,则不会进行遍历,也不会报错-->
        <tr th:each="user:${page.records}">
            <!--        td标签定义html表格中的标准单元格-->
            <td style="vertical-align: middle!important;" th:text="${user.userName}"></td>
            <td style="vertical-align: middle!important;" th:text="${user.userAge}"></td>
            <td style="vertical-align: middle!important;" th:text="${user.userAddr}"></td>
            <td style="vertical-align: middle!important;" th:text="${user.userSex}"></td>
            <td style="vertical-align: middle!important;" th:text="${user.userPhone}"></td>
            <td>
                <!--         a标签用来定义超链接 href表示超链接-->
                <a class="btn btn-primary" th:href="@{'/api/v1/user/updatePage/'+${user.userId}}">更改</a>
                <a class="btn btn-danger" th:href="@{'/api/v1/user/delete/'+${user.userId}}">删除</a>
            </td>
        </tr>
    </table>

    <!-- 显示分页信息 -->
    <div class="row">
        <!--分页文字信息  -->
        <div class="col-md-6">当前 [[${page.current}]]页,总[[${page.pages }]]
            页,总[[ ${page.total }]] 条记录
        </div>
        <!-- 分页条信息 -->
        <div class="col-md-6">
            <nav aria-label="Page navigation">
                <ul class="pagination">
                    <!--点击首页会跳转到第一页,并且首页禁用-->
                    <th:block th:if="${page.current==1}">
                        <li class="active,disabled">
                            <a>首页</a></li>
                    </th:block>

                    <th:block th:if="${page.current>1}">
                        <li><a th:href="@{/list(pn=1)}">首页</a></li>
                    </th:block>

                    <li th:if="${page.hasPrevious()}">
                        <a th:href="@{/list(pn=${page.getCurrent()-1})}">
                            <span aria-hidden="true">&laquo;</span>

                        </a>
                    </li>

                    <!--遍历页码,只显示五页,点击下一页之后,每次多遍历两个页码-->
                    <th:block th:if="${page.getCurrent()<=3}" th:each="i:${#numbers.sequence(1,5)}">
                        <!--加判断是不是当前页,如果是 高亮显示,并且取消超链接,这样避免了点击当前页重复发送请求查询数据-->
                        <th:block th:if="${page.getCurrent()==i}">

                            <li class="active">
                                <a th:text="${i}"></a>
                            </li>
                        </th:block>

                        <th:block th:if="${page.getCurrent()!=i}">
                            <li>
                                <a th:text="${i}" th:href="@{/api/v1/user/list(pn=${i})}"></a>
                            </li>
                        </th:block>


                    </th:block>


                    <th:block th:if="${page.getCurrent()>3 && page.getCurrent()+2<=page.getPages()}"
                              th:each="i:${#numbers.sequence(page.getCurrent()-2,page.getCurrent()+2)}">
                        <!--同理上-->
                        <th:block th:if="${page.getCurrent()==i}">

                            <li class="active">
                                <a th:text="${i}"></a>
                            </li>
                        </th:block>

                        <th:block th:if="${page.getCurrent()!=i}">
                            <li>
                                <a th:text="${i}" th:href="@{/api/v1/user/list(pn=${i})}"></a>
                            </li>
                        </th:block>


                    </th:block>


                    <th:block th:if="${page.getCurrent()+2>page.getPages()}"
                              th:each="i:${#numbers.sequence(page.getPages()-4,page.getPages())}">
                        <!--同理上-->
                        <th:block th:if="${page.getCurrent()==i}">

                            <li class="active,disabled">
                                <a th:text="${i}"></a>
                            </li>
                        </th:block>

                        <th:block th:if="${page.getCurrent()!=i}">
                            <li>
                                <a th:text="${i}" th:href="@{/api/v1/user/list(pn=${i})}"></a>
                            </li>
                        </th:block>


                    </th:block>


                    <!--下一页-->
                    <li th:if="${page.hasNext()}">
                        <a th:href="@{/api/v1/user/list(pn=${page.current+1})}">
                            <span aria-hidden="true">&raquo;</span>
                        </a></li>


                    <!--点击末页会跳转到最后一页,并且最后一页禁用-->
                    <th:block th:if="${page.current<page.pages}">
                        <li><a th:href="@{/api/v1/user/list(pn=${page.pages})}">末页</a></li>

                    </th:block>

                    <th:block th:if="${page.current==page.pages}">
                        <li class="active,disabled"><a>末页</a></li>

                    </th:block>


                </ul>
            </nav>
        </div>
    </div>
</div>
</body>

</html>

modifie.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>修改用户</title>
    <!--<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">-->
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>

<div style="width:400px;height:100%;margin-left:450px;margin-top:100px;">
    <form action="/api/v1/user/update" method="post">
        <!-- rest风格中的更新是put请求,
        所以这块先使用post请求,然后隐藏起来改为put请求-->
        <input name="_method" type="hidden" value="put">
        <input type="hidden" th:value="${users.userId}" name="userId">
        姓 名:<input class="form-control"  type="text" th:value="${users.userName}" name="userName"><br>
        年 龄:<input class="form-control" type="text" th:value="${users.userAge}" name="userAge"><br>
        住 址:<input class="form-control" type="text" th:value="${users.userAddr}" name="userAddr"><br>
        性 别:<input class="form-control" type="text" th:value="${users.userSex}" name="userSex"><br>
        电话号码:<input class="form-control" type="text" th:value="${users.userPhone}" name="userPhone"><br>
        <button class="btn btn-primary btn-lg btn-block" type="submit">保存</button>
    </form>
</div>

</body>
</html>

在这里插入图片描述
启动效果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值