【Spring Boot】用 MyBatis 实现数据的 CRUD

用 MyBatis 实现数据的 CRUD

  • 1.创建项目 & 引入依赖
  • 2.实现数据表的自动初始化
  • 3.实现实体对象建模
  • 4.实现实体和数据表的映射关系
  • 5.实现增加、删除、修改和查询功能
  • 6.配置分页功能
    • 6.1 增加分页支持
    • 6.2 创建分页配置类
  • 7.实现分页控制器
  • 8.创建分页视图

本篇博客将通过 MyBatis 来实现常用的数据增加、删除、修改、查询和分页功能。

在这里插入图片描述

1.创建项目 & 引入依赖

创建一个 Spring Boot 项目,并引入 MyBatis 和 MySQL 依赖。

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

		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.0.0</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
		</dependency>
		
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</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>
	</dependencies>

2.实现数据表的自动初始化

在项目的 resources 目录下新建 db 目录,并添加 schema.sql 文件,然后在此文件中写入创建 user 表的 SQL 语句,以便进行初始化数据表。具体代码如下:

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

application.properties 配置文件中配置数据库连接,并加上数据表初始化的配置。具体代码如下:

spring.datasource.initialize=true
spring.datasource.initialization-mode=always
spring.datasource.schema=classpath:db/schema.sql

完整的 application.properties 文件如下:

spring.datasource.url=jdbc:mysql://127.0.0.1/book?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
spring.datasource.username=xxxx
spring.datasource.password=xxxxxx

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql=true

spring.datasource.initialization-mode=always
spring.datasource.schema=classpath:db/schema.sql

spring.thymeleaf.cache=false
server.port=8080

这样,Spring Boot 在启动时就会自动创建 user 表。

3.实现实体对象建模

用 MyBatis 来创建实体,见以下代码:

package com.example.demo.entity;

import lombok.Data;

@Data
public class User {
    private int id;
    private String name;
    private int age;
}

从上述代码可以看出,用 MyBatis 创建实体是不需要添加注解 @Entity 的,因为 @Entity 属于 JPA 的专属注解。

4.实现实体和数据表的映射关系

实现实体和数据表的映射关系可以在 Mapper 类上添加注解 @Mapper,见以下代码。建议以后直接在入口类加 @MapperScan("com.example.demo.mapper"),如果对每个 Mapper 都加注解则很麻烦。

package com.example.demo.mapper;

import com.example.demo.entity.User;
import com.github.pagehelper.Page;
import org.apache.ibatis.annotations.*;

import java.util.List;

@Mapper
public interface UserMapper {

    @Select("SELECT * FROM user WHERE id = #{id}")
    User queryById(@Param("id") int id);

    @Select("SELECT * FROM user")
    List<User> queryAll();

    @Insert({"INSERT INTO user(name,age) VALUES(#{name},#{age})"})
    int add(User user);

    @Delete("DELETE FROM user WHERE id = #{id}")
    int delById(int id);

    @Update("UPDATE user SET name=#{name},age=#{age} WHERE id = #{id}")
    int updateById(User user);

    @Select("SELECT * FROM user")
    Page<User> getUserList();
}

5.实现增加、删除、修改和查询功能

创建控制器实现操作数据的 API,见以下代码:

package com.example.demo.controller;

import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    UserMapper userMapper;

    @RequestMapping("/querybyid")
    User queryById(int id) {
        return userMapper.queryById(id);
    }

    @RequestMapping("/")
    List<User> queryAll() {
        return userMapper.queryAll();
    }


    @RequestMapping("/add")
    String add(User user) {
        return userMapper.add(user) == 1 ? "success" : "failed";
    }

    @RequestMapping("/updatebyid")
    String updateById(User user) {
        return userMapper.updateById(user) == 1 ? "success" : "failed";
    }

    @RequestMapping("/delbyid")
    String delById(int id) {
        return userMapper.delById(id) == 1 ? "success" : "failed";
    }
}
  • 启动项目,访问 http://localhost:8080/user/add?name=pp&age=20,会自动添加一个 name=ppage=20 的数据。

在这里插入图片描述
在这里插入图片描述

  • 访问 http://localhost:8080/user/updatebyid?name=pipi&age=26&id=1,会实现对 id=1 的数据的更新,更新为 name=pipiage=26

在这里插入图片描述

  • 访问 http://localhost:8080/user/querybyid?id=1,可以查找到 id=1 的数据,此时的数据是 name=pipiage=26

在这里插入图片描述

  • 访问 http://localhost:8080/user/,可以查询出所有的数据。

在这里插入图片描述

  • 访问 http://localhost:8080/user/delbyid?id=1,可以删除 id1 的数据。

在这里插入图片描述

6.配置分页功能

6.1 增加分页支持

分页功能可以通过 PageHelper 来实现。要使用 PageHelper,则需要添加如下依赖,并增加 Thymeleaf 支持。

<!-- 增加对PageHelper的支持 -->
<dependency>
	<groupId>com.github.pagehelper</groupId>
	<artifactId>pagehelper</artifactId>
	<version>4.1.6</version>
</dependency>

<!--增加thymeleaf支持-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

6.2 创建分页配置类

创建分页配置类来实现分页的配置,见以下代码:

package com.example.demo.config;

import com.github.pagehelper.PageHelper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Properties;

@Configuration
public class PageHelperConfig {
    @Bean
    public PageHelper pageHelper(){
        PageHelper pageHelper = new PageHelper();
        Properties p = new Properties();
        p.setProperty("offsetAsPageNum", "true");
        p.setProperty("rowBoundsWithCount", "true");
        p.setProperty("reasonable", "true");
        pageHelper.setProperties(p);
        return pageHelper;
    }
}

代码解释如下。

  • @Configuration:表示 PageHelperConfig 这个类是用来做配置的。
  • @Bean:表示启动 PageHelper 拦截器。
  • offsetAsPageNum:设置为 true 时,会将 RowBounds 第一个参数 offset 当成 pageNum 页码使用。
  • rowBoundsWithCount:设置为 true 时,使用 RowBounds 分页会进行 count 查询。
  • reasonable:启用合理化时,如果 pageNum<1 会查询第一页,如果 pageNum>pages 会查询最后一页。

7.实现分页控制器

创建分页列表控制器,用以显示分页页面,见以下代码:

package com.example.demo.controller;

import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

@Controller
public class UserListController {
    @Autowired
    UserMapper userMapper;
    @RequestMapping("/listall")
    public String listCategory(Model m, @RequestParam(value="start", defaultValue="0")int start, @RequestParam(value="size", defaultValue="5") int size) throws Exception {
        PageHelper.startPage(start,size,"id desc");
        List<User> cs = userMapper.queryAll();
        PageInfo<User> page = new PageInfo<>(cs);
        m.addAttribute("page", page);
        return "list";
    }
}
  • start:在参数里接收当前是第几页。默认值是 0
  • size:每页显示多少条数据。默认值是 5
  • PageHelper.startPage(start,size,"id desc") : 根据 startsize 进行分页,并且设置 id 倒排序。
  • List<User>:返回当前分页的集合。
  • PageInfo<User>:根据返回的集合创建 Pagelnfo 对象。
  • model.addAttribute("page", page):把 page (PageInfo 对象)传递给视图,以供后续显示。

8.创建分页视图

接下来,创建用于视图显示的 list.html,其路径为 resources/template/list.html

在视图中,通过 page.pageNum 获取当前页码,通过 page.pages 获取总页码数,见以下代码:

<div class="with:80%">
    <div th:each="u : ${page.list}">
        <span scope="row" th:text="${u.id}">id</span>
        <span th:text="${u.name}">name</span>
    </div>
</div>

<div>
    <a th:href="@{listall?start=1}">[首页]</a>
    <a th:href="@{/listall(start=${page.pageNum-1})}">[上页]</a>
    <a th:href="@{/listall(start=${page.pageNum+1})}">[下页]</a>
    <a th:href="@{/listall(start=${page.pages})}">[末页]</a>
    <div>当前页/总页数:<a th:text="${page.pageNum}" th:href="@{/listall(start=${page.pageNum})}"></a>
        /<a th:text="${page.pages}" th:href="@{/listall(start=${page.pages})}"></a></div>
</div>

启动项目,多次访问 http://localhost:8080/user/add?name=pp&age=26 增加数据,然后访问 http://localhost:8080/listall 可以查看到分页列表。

在这里插入图片描述
但是,上述代码有一个缺陷:显示分页处无论数据多少都会显示“上页、下页”。所以,需要通过以下代码加入判断,如果没有上页或下页则不显示。

<a  th:if="${not page.IsFirstPage}" th:href="@{/listall(start=${page.pageNum-1})}">[上页]</a>
<a  th:if="${not page.IsLastPage}" th:href="@{/listall(start=${page.pageNum+1})}">[下页]</a>

上述代码的作用是:如果是第一页,则不显示“上页”;如果是最后一页,则不显示“下页”。

在这里插入图片描述
在这里插入图片描述

还有一种更简单的方法:在 Mapper 中直接返回 page 对象,见以下代码:

@Select("SELECT * FROM user")
Page<User> getUserList();

然后在控制器中这样使用:

package com.example.demo.controller;

import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserListControllerB {
    @Autowired
    UserMapper userMapper;
    // http://localhost:8080/listall2?pageNum=1&pageSize=2
    @RequestMapping("/listall2")
    // 如果方法的参数不指定默认值,且请求地址也没有指定参数值,则项目运行时会报错。
    public Page<User> getUserList(@RequestParam(value="pageNum",defaultValue="0")int pageNum, @RequestParam(value = "pageSize", defaultValue = "5") int pageSize)
    //public Page<User> getUserList(Integer pageNum, Integer pageSize)
    {
        PageHelper.startPage(pageNum, pageSize);
        Page<User> userList= userMapper.getUserList();
        return userList;
    }
}

代码解释如下。

  • pageNum:页码。
  • pageSize:每页显示多少记录。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/920719.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构-二叉树_堆

目录 1.二叉树的概念 ​编辑1.1树的概念与结构 1.2树的相关语 1.3 树的表示 2. ⼆叉树 2.1 概念与结构 2.2 特殊的⼆叉树 2.2.2 完全⼆叉树 2.3 ⼆叉树存储结构 2.3.1 顺序结构 2.3.2 链式结构 3. 实现顺序结构⼆叉树 3.2 堆的实现 3.2.2 向下调整算法 1.二叉树的概…

独家原创 | SCI 1区 高创新预测模型!

往期精彩内容&#xff1a; 时序预测&#xff1a;LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较 全是干货 | 数据集、学习资料、建模资源分享&#xff01; EMD变体分解效果最好算法——CEEMDAN&#xff08;五&#xff09;-CSDN博客 拒绝信息泄露&#xff01;VMD滚动分…

IDEA+Docker一键部署项目SpringBoot项目

文章目录 1. 部署项目的传统方式2. 前置工作3. SSH配置4. 连接Docker守护进程5. 创建简单的SpringBoot应用程序6. 编写Dockerfile文件7. 配置远程部署7.1 创建配置7.2 绑定端口7.3 添加执行前要运行的任务 8. 部署项目9. 开放防火墙的 11020 端口10. 访问项目11. 可能遇到的问题…

Arcgis 地图制作

地图如下,不同历史时期&#xff1a;

【K8S系列】Kubernetes 中如何调试imagePullSecrets配置详细步骤介绍

调试 imagePullSecrets 配置是确保 Kubernetes 能够成功拉取私有镜像所需的关键步骤。以下是详细的调试步骤和建议。 1. 确认 imagePullSecrets 配置 首先&#xff0c;确保在 Pod 的 YAML 配置中正确引用了 imagePullSecrets。其基本结构如下&#xff1a; apiVersion: v1 kin…

山东春季高考-C语言-综合应用题

&#xff08;2018年&#xff09;3.按要求编写以下C语言程序&#xff1a; &#xff08;1&#xff09;从键盘上输入三个整数a、b、c&#xff0c;判断能否以这三个数为边构成三角形&#xff0c;若可以则计算机三角形的面积且保留两位小数&#xff1b;若不可以则输出“不能构成三角…

UE5 第一人称射击项目学习(二)

在上一章节中。 得到了一个根据视角的位置创建actor的项目。 现在要更近一步&#xff0c;对发射的子弹进行旋转。 不过&#xff0c;现在的子弹是圆球形态的&#xff0c;所以无法分清到底怎么旋转&#xff0c;所以需要把子弹变成不规则图形。 现在点开蓝图。 这里修改一下&…

如何实现点击目录跳转到指定位置?【vue】

需求&#xff1a;实现目录点击跳转到指定位置&#xff0c;点击后直接定位到指定模块 效果&#xff1a; 实现方法&#xff1a; &#xff08;1&#xff09;a标签跳转 普通使用&#xff1a; <!DOCTYPE html> <html><head><title>a-Demo</title>&l…

使用chrome 访问虚拟机Apache2 的默认页面,出现了ERR_ADDRESS_UNREACHABLE这个鸟问题

本地环境 主机MacOs Sequoia 15.1虚拟机Parallels Desktop 20 for Mac Pro Edition 版本 20.0.1 (55659)虚拟机-操作系统Ubuntu 22.04 服务器版本 最小安装 开发环境 编辑器编译器调试工具数据库http服务web开发防火墙Vim9Gcc13Gdb14Mysql8Apache2Php8.3Iptables 第一坑 数…

deepin系统下载pnpm cnpm等报错

deepin系统下载pnpm cnpm等报错 npm ERR! request to https://registry.npm.taobao.org/pnpm failed, reason: certificate has expired 报错提示证书过期&#xff0c;执行以下命令 npm config set registry https://registry.npmmirror.com下载pnpm npm install pnpm -g查…

零基础上手WebGIS+智慧校园实例(1)【html by js】

请点个赞收藏关注支持一下博主喵&#xff01;&#xff01;&#xff01; 等下再更新一下1. WebGIS矢量图形的绘制&#xff08;超级详细&#xff01;&#xff01;&#xff09;&#xff0c;2. WebGIS计算距离&#xff0c; 以及智慧校园实例 with 3个例子&#xff01;&#xff01;…

Matlab 答题卡方案

在现代教育事业的飞速发展中&#xff0c;考试已经成为现代教育事业中最公平的方式方法&#xff0c;而且也是衡量教与学的唯一方法。通过考试成绩的好与坏&#xff0c;老师和家长可以分析出学生掌握的知识多少和学习情况。从而老师可以了解到自己教学中的不足来改进教学的方式方…

【实操之 图像处理与百度api-python版本】

1 cgg带你建个工程 如图 不然你的pip baidu-aip 用不了 先对图片进行一点处理 $ 灰度处理 $ 滤波处理 参考 import cv2 import os def preprocess_images(input_folder, output_folder):# 确保输出文件夹存在if not os.path.exists(output_folder):os.makedirs(output_fol…

Python小游戏28——水果忍者

首先&#xff0c;你需要安装Pygame库。如果你还没有安装&#xff0c;可以使用以下命令进行安装&#xff1a; 【bash】 pip install pygame 《水果忍者》游戏代码&#xff1a; 【python】 import pygame import random import sys # 初始化Pygame pygame.init() # 设置屏幕尺寸 …

基于SpringBoot的校园二手商品在线交易系统+含项目运行说明文档

一、项目技术栈 二、项目功能概述 管理员可以完成的功能包括管理员登录、管理员首页展示、系统设置、物品管理、学生管理、评论管理、举报管理、新闻公告、网站设置等&#xff0c;前台的客户可以进行查看所有商品分类、搜索商品、登录或注册、发布商品、求购商品等。 三、部分…

最新Kali安装详细版教程(附安装包,傻瓜式安装教程)

本文主要详细介绍 kali 的安装过程&#xff0c;以及安装完成后的基本设置&#xff0c;比如安装增强工具&#xff0c;安装中文输入法以及更新升级等操作。 文章目录 实验环境准备工作步骤说明安装虚拟机安装 Kali安装增强工具安装中文输入法更新升级 实验环境 VMware &#x…

将网站地址改成https地址需要哪些材料

HTTPS&#xff08;安全超文本传输协议&#xff09;是HTTP协议的扩展。它大大降低了个人数据&#xff08;用户名、密码、银行卡号等&#xff09;被拦截的风险&#xff0c;还有助于防止加载网站时的内容替换&#xff0c;包括广告替换。 在发送数据之前&#xff0c;信息会使用SSL…

React基础知识一

写的东西太多了&#xff0c;照成csdn文档编辑器都开始卡顿了&#xff0c;所以分篇写。 1.安装React 需要安装下面三个包。 react:react核心包 react-dom:渲染需要用到的核心包 babel:将jsx语法转换成React代码的工具。&#xff08;没使用jsx可以不装&#xff09;1.1 在html中…

VUE:基于MVVN的前端js框架

文章目录 vue框架v-show vue框架 注意是 先写函数名&#xff0c;再写function。 handle:function (){}下面是错误的 function:handle(){}3 v-show 本质上等于号后面还是判断条件&#xff0c;所以不能写赋值语句&#xff0c;下面是正确的 下面是错误的 v-show " ge…

六、卷积神经网络(CNN)基础

卷积神经网络&#xff08;CNN&#xff09;基础 前言一、CNN概述二、卷积层2.1 卷积2.2 步幅(Stride)2.3 填充(Padding)2.4 多通道卷积2.5 多卷积计算2.6 特征图大小计算2.7 代码演示 三、池化层3.1 池化层计算3.1.1 最大池化层3.1.2 平均池化层 3.2 填充(Padding)3.3 步幅(Stri…