当前位置: 首页 > news >正文

Mybatis对数据库进行增删查改以及单元测试

这篇写的草率了,是好几天前学到,以后用来自己复习 

 UserInfo

import lombok.Data;@Data
public class UserInfo {private int id;private String name;private int age;private String email;//LocalDateTime可用于接收  时间}

Mapper 

UserMapper

package com.example.demo1014.mapper;import com.example.demo1014.entity.UserInfo;
import lombok.Data;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.*;@Mapper
public interface UserMapper {// UserInfo getUserById(Integer id);UserInfo getUserById(@Param("user_id") Integer id);//这里的参数“user_id”与resources.mybatis.UserMapper.xml里面的id的值相对应//查所有用户信息List<UserInfo> getAll();//插入信息int add(UserInfo userinfo);//添加并返回用户的自增ID:int addGetId(UserInfo userinfo);//修改操作:int upUserName(UserInfo userinfo);//删除操作:int delById(@Param("id") Integer id);List<UserInfo> getListByOrder(@Param("order") String order);//类似登录逻辑的实现————根据name和id一起查询信息,只有一个就不行;UserInfo login(@Param("name") String name,@Param("email") String email);//进行模糊查询List<UserInfo> getListByName(@Param("name") String name);int add2(UserInfo userinfo);int add3(UserInfo userinfo);List<UserInfo>   getListByParam(String name,Integer id);int update2(UserInfo userinfo);int dels(List<Integer> ids);}
/**mapper里面有接口有xml文件;* */
/**接口:* 接口中的方法都没有方法体都是抽象方法* **//**单元测试:* 1.在需要进行单元测试的类中选择generate* */

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.example.demo1014.mapper.UserMapper"><select id="getUserById" resultType="com.example.demo1014.entity.UserInfo">SELECT * FROM UserInfo WHERE id = #{user_id}<!--这里的#{user_id}是与Java对象中的属性对应的,而不是数据库的字段--></select><select id="getAll" resultType="com.example.demo1014.entity.UserInfo">select * from userinfo</select><insert id="add">insert into userinfo(id,name,age,email) values(#{id},#{name},#{age},#{email})</insert><!--insert默认返回值就是int--><!--返回自增id,这里的“”里面一定是程序中实体类的属性而不是数据库中的字段--><insert id="addGetId" useGeneratedKeys="true" keyProperty="id">insert into userinfo(id,name,age,email) values(#{id},#{name},#{age},#{email})</insert><update id="upUserName">update userinfo set name= #{name} where id=#{id}</update><delete id="delById">delete from userinfo where id = #{id}</delete><select id="getListByOrder" resultType="com.example.demo1014.entity.UserInfo">select* from userinfo order by id ${order}</select><select id="login" resultType="com.example.demo1014.entity.UserInfo">select* from userinfo where name='${name}' and email =#{email}</select><select id="getListByName"  resultType="com.example.demo1014.entity.UserInfo">select* from userinfo where name like  CONCAT('%', #{name}, '%')</select><!--必填和非必填的<if>标签--><insert id="add2">insert into userinfo(id,<if test="name!=null">name,</if>age) values(#{id},<if test="name!=null">#{name},</if>#{age})</insert><insert id="add3">insert into userinfo<trim prefix="(" suffix=")" suffixOverrides=","><if test="id!=null">id,</if><if test="name!=null">name,</if><if test="age!=null">age,</if><if test="email!=null">email,</if></trim> values<trim prefix="(" suffix=")" suffixOverrides=","><if test="id!=null">#{id},</if><if test="name!=null">#{name},</if><if test="age!=null">#{age},</if><if test="email!=null">#{email},</if></trim></insert><select id="getListByParam" resultType="com.example.demo1014.entity.UserInfo">select* from userinfo
<!--        <where>-->
<!--            <if test="name!=null">-->
<!--              and  name=#{name}-->
<!--            </if>-->
<!--            <if test="id!=null">-->
<!--              and  id=#{id}--><!--            </if>-->
<!--        </where>--><trim prefix="where" prefixOverrides="and"><if test="name!=null">and name=#{name}</if><if test="id!=null">and id=#{id}</if></trim></select><update id="update2">update userinfo<set><if test="id!=null">id=#{id},</if><if test="name!=null">name=#{name},</if></set>where id=#{id}</update><delete id="dels">     <!--delete from userinfo where id in ()-->delete from userinfo where id in<foreach collection="ids" open="(" close=")" item="id" separator=",">#{id}</foreach></delete></mapper>
<!--namsespace是xml实现接口的全路径(包名+接口名) id是实现的方法名  resultType是返回的类型 ${}是标签,用来传递参数-->

service

package com.example.demo1014.service;import com.example.demo1014.entity.UserInfo;
import com.example.demo1014.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class UserService {@Autowired//依赖注入private UserMapper userMapper;public UserInfo getUserById(Integer id){return userMapper.getUserById(id);}
}

controller

package com.example.demo1014.controller;import com.example.demo1014.entity.UserInfo;
import com.example.demo1014.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController//=@ResponseBody+@Controller
@RequestMapping("/user")public class UserController {@Autowiredprivate UserService userservice;@RequestMapping("/getuserbyid")public UserInfo getUserById(Integer id ){if(id==null) return null;return userservice.getUserById(id);}}

//此时就可以用postman查询了使用http://127.0.0.1:8080/user/getuserbyid?id=1
//查询到{
    "id": 1,
    "name": "John",
    "age": 25,
    "email": "john@example.com"
}
 

 如何进行单元测试?

在UserMApper类里面,右键->generate ->Test->勾选你想要的方法

进入Test

需要注意@Transaction可开启事务,不污染数据库。

package com.example.demo1014.mapper;
/**单元测试:* 1.在需要进行单元测试的类中选择generate* */import com.example.demo1014.entity.UserInfo;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;import java.util.List;import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest//1. 表明当前单元测试是运行在SpringBoot中
//@Transactional //Spring 将会在方法执行前开启一个事务,在方法执行结束后根据方法的执行结果进行事务的提交或回滚
class UserMapperTest {@Autowired//2. 注入测试对象private UserMapper userMapper;@Testvoid getUserById() {//3. 添加单元测试的业务代码UserInfo userinfo=userMapper.getUserById(1);System.out.println(userinfo);/**使用断言->判断最终结果是否符合预期!?** */Assertions.assertEquals("John",userinfo.getName());}@Testvoid getAll() {List<UserInfo> list=userMapper.getAll();Assertions.assertEquals(8,list.size());}@Testvoid add() {UserInfo userinfo = new UserInfo();userinfo.setId(11);userinfo.setName("小龙女");userinfo.setAge(18);userinfo.setEmail("xxx@example.com");int result = userMapper.add(userinfo);assertEquals(1, result); // 验证插入是否成功// sqlSession.commit(); // 提交事务}@Testvoid addGetId() {//UserInfo userinfo=new UserInfo();userinfo.setId(9);userinfo.setAge(30);userinfo.setName("小龙女");userinfo.setEmail("33780908@qq.com");//调用mybatis添加方法执行添加操作int result=userMapper.addGetId(userinfo);System.out.println("添加:"+result);int uid=userinfo.getId();System.out.println("用户id:"+uid);Assertions.assertEquals(1,result);//2023-10-15 16:50:24.135  INFO 23020 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...//2023-10-15 16:50:24.327  INFO 23020 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.//添加:1//用户id:5}@Testvoid upUserName() {//构建测试数据UserInfo userinfo=new UserInfo();userinfo.setId(6);userinfo.setName("孙悟空");//受影响的行数:int result=userMapper.upUserName(userinfo);System.out.println("修改:"+result);Assertions.assertEquals(1,result);}@Test// @Transactional//加上后就不会污染我们的数据库信息;void delById() {Integer id=6;int result= userMapper.delById(id);System.out.println("删除:"+result);Assertions.assertEquals(1,result);}@Testvoid   getListByOrder() {List<UserInfo> list=userMapper.getListByOrder("asc");System.out.println(list);}@Testvoid login() {String email="1111@qq.com";// String name="mike";String name="' or 1='1";UserInfo userinfo=userMapper.login(name,email);System.out.println("用户登陆状态:"+(userinfo==null?"失败":"成功"));}@Testvoid add2() {UserInfo userinfo=new UserInfo();userinfo.setId(11);userinfo.setName(null);userinfo.setAge(111111);// userinfo.setEmail("222");int result=userMapper.add2(userinfo);System.out.println("result:"+result);}@Testvoid add3() {UserInfo userinfo=new UserInfo();userinfo.setId(13);userinfo.setName("sss");userinfo.setEmail("12432`");int result=userMapper.add3(userinfo);Assertions.assertEquals(1,result);}@Testvoid getListByParam() {List<UserInfo> list=userMapper.getListByParam("John",1);//select* from userinfo WHERE name=? and id=?List<UserInfo> list1=userMapper.getListByParam("John",null);// select* from userinfo WHERE name=?List<UserInfo> list2=userMapper.getListByParam(null,1);//select* from userinfo WHERE id=?List<UserInfo> list3=userMapper.getListByParam(null,null);//select* from userinfo}@Testvoid update2() {UserInfo userinfo=new UserInfo();userinfo.setId(2);userinfo.setName("小李子zi");userMapper.update2(userinfo);}/**在pom.xml中添加配置* # 开启mybatis sql 日志打印;*   configuration:*     log-impl: org.apache.ibatis.logging.stdout.StdOutImpl** # 配置打印MyBatis执行的sql;* logging:*   level:*     com:*       example:*         demo1014: debug*  后,可进行打印日志* ==>  Preparing: update userinfo set name= ? where id=?* ==> Parameters: 孙悟空(String), 4(Integer)* <==    Updates: 1* **/}/**  参数占位符 #{} 和 ${} :* #{}:预编译处理;* ${}: 字符直接替换;** Mybatis在处理#{}时,会把SQL中的#{}替换成?,使用PaeparedStatement的set方法来复制,直接替换:Mybatis在处理${},是把${}替换成变量的值;* $的应用场景:使用Java中的关键字的时候!* ${sort}可以实现排序查询,而是用#{sort}就不能实现排序查询了,因为当使用#{sort}查询的时候,如果查询的值是String,则会加单引号,就会导致sql错误;** **/

这个插件好用,推荐MyBatisx, 

相关文章:

Mybatis对数据库进行增删查改以及单元测试

这篇写的草率了&#xff0c;是好几天前学到&#xff0c;以后用来自己复习 UserInfo import lombok.Data;Data public class UserInfo {private int id;private String name;private int age;private String email;//LocalDateTime可用于接收 时间}Mapper UserMapper pack…...

.bat 批处理 - 查看 MySQL 状态然后启动或关闭

我的 MySQL 服务名为 MySQL80&#xff0c;具体的以实际为准&#xff1a; echo off setlocal:check_status cls sc query MySQL80 | find "RUNNING" > nul 2>&1 if %errorlevel%0 (echo Current status of MySQL service: Running ) else (echo Current st…...

跳转传参有几种方式

在Vue Router中&#xff0c;实现路由跳转并传参有以下几种方式&#xff1a; 1. 路由参数&#xff08;Route Params&#xff09;&#xff1a; 可以通过在路由配置中定义动态的占位符&#xff08;即路由参数&#xff09;&#xff0c;并在跳转时通过URL路径来传递参数。这种方式适…...

DVWA靶场Medium难度部分解析

前言 好久没做题&#xff0c;不想吹牛逼了&#xff0c;消停做点题QAQ Vulnerability: Command Injection 这题不咋难&#xff0c;老Ping题了 输个分号ls试试&#xff0c;没回显即被Ban了&#xff0c;试试别的&#xff0c;例如|或者&& 出了&#xff0c;看看源代码 把…...

SVG图形

什么是SVG SVG&#xff08;Scalable Vector Graphics&#xff09;是一种用于描述二维矢量图形的XML 格式文件。它是一种用于在网络上显示图形的开放标准&#xff0c;旨在与Web上的其他技术&#xff08;如HTML和CSS&#xff09;集成&#xff0c;并支持在不失真的情况下缩放和调…...

冒泡排序和简答选择排序

冒泡排序 一种典型的交换排序 类似水冒泡&#xff0c;大元素经不断的交换由水底慢慢的浮出 从头到尾&#xff0c;循环比较两相邻的元素 大的元素移到后面&#xff0c;小的放前面-每次循环&#xff0c;大的元素会排到最后 代码如下&#xff1a; #include<stdio.h> …...

leetcode3. 无重复字符的最长子串 [滑动窗口]

题目 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。示例 2: 输入: s "bbbbb" 输出: 1 解释:…...

软件工程与计算总结(十六)详细设计的设计模式

一.设计模式基础 某种意义上来说&#xff0c;设计模式就是设计经验的总结~ 设计模式不是简单的经验总结&#xff0c;更不是无中生有&#xff0c;它是经过实践反复检验、能解决关键技术难题、有广泛应用前景和能够显著提高软件质量的有效的经验总结。 每个模式都不是独立的&a…...

List集合拆分为多个List

list 拆分 目录概述需求&#xff1a; 设计思路实现思路分析1.list 拆分是2.用stream的parallel实现list的分批处理3.使用stream的parallel实现list的分批处理 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full bus…...

Hadoop3教程(十三):MapReduce中的分区

文章目录 &#xff08;96&#xff09; 默认HashPartitioner分区&#xff08;97&#xff09; 自定义分区案例&#xff08;98&#xff09;分区数与Reduce个数的总结参考文献 &#xff08;96&#xff09; 默认HashPartitioner分区 分区&#xff0c;是Shuffle里核心的一环&#xf…...

笔记本Win10系统一键重装操作方法

笔记本电脑已经成为大家日常生活和工作中必不可少的工具之一&#xff0c;如果笔记本电脑系统出现问题了&#xff0c;那么就会影响到大家的正常操作。这时候就可以考虑给笔记本电脑重装系统了。接下来小编给大家介绍关于一键重装Win10笔记本电脑系统的详细步骤方法。 推荐下载 系…...

FilterRegistrationBean能不能排除指定url

文章目录 什么是FilterRegistrationBean举个栗子但是如果我想要排除某些uri方法总结FilterRegistrationBean只能设置指定的url进行过滤,而不能指定排除uri,只能使用OncePerRequestFilter的shouldNotFilter方法,排除uri 什么是FilterRegistrationBean FilterRegistrationBean是…...

【LeetCode】36. 有效的数独

1 问题 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 &#xff0c;验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&#xff08;请参考示例图&…...

华为---PPP协议简介及示例配置

PPP协议简介 PPP是Point-to-Point Protocol的简称&#xff0c;中文翻译为点到点协议。与以太网协议一样,PPP也是一个数据链路层协议。以太网协议定义了以太帧的格式&#xff0c;PPP协议也定义了自己的帧格式&#xff0c;这种格式的帧称为PPP帧。 利用PPP协议建立的二层网络称为…...

asp.net老年大学信息VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio计算机毕业设计

一、源码特点 asp.net老年大学信息管理系统是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使用c# 语言开发 asp.net老年大学信息管理系统…...

模型量化笔记--对称量化和非对称量化

1–量化映射 量化映射的通用公式为: r S ( q − Z ) r S(q - Z) rS(q−Z) 其中r表示量化前数据的真实值&#xff0c;S表示缩放因子&#xff0c;q表示量化后的数值&#xff0c;Z表示零点 2–非对称量化 非对称量化需要一个偏移量Z来完成零点的映射&#xff0c;即量化前的零…...

PA2019 Terytoria

洛谷P5987 [PA2019] Terytoria 题目大意 在一个平面直角坐标系上&#xff0c;有一个长度为 X X X&#xff0c;宽度为 Y Y Y的地图&#xff0c;这个地图的左边界和右边界是连通的&#xff0c;下边界和上边界也是连通的。 在地图中&#xff0c;有 X Y X\times Y XY个格子以及…...

内容分发网络CDN分布式部署真的可以加速吗?原理是什么?

Cdn快不快&#xff1f;她为什么会快&#xff1f;同样的带宽为什么她会快&#xff1f;原理究竟是什么&#xff0c;同学们本着普及知识的想法&#xff0c;我了解的不是很深入&#xff0c;适合小白来看我的帖子&#xff0c;如果您是大佬还请您指正错误的地方&#xff0c;先谢谢大佬…...

微服务docker部署实战

docker基础和进阶(*已掌握的可以跳过 *) 基础 docker基础 进阶 docker进阶 准备工作 提前准备好mysql和redis的配置&#xff0c;如下 在/zzq/mysql/conf目录下配置mysql配置文件my.cnf [client] #设置客户端字符集 default_character_setutf8 [mysqld] #开启定时任务 event_s…...

js实现拖拽功能

基于onMouseDown 、onMouseMove 、onMouseUp 使用 mousedown、mousemove 和 mouseup 事件来实现拖拽的基本思路是&#xff1a; 在 mousedown 事件中&#xff0c;开始追踪拖拽操作并记录鼠标按下的位置。 在 mousemove 事件中&#xff0c;根据鼠标的移动&#xff0c;更新被拖拽…...

数据库主从切换过程中Druid没法获取连接错误

背景&#xff1a; 今天dba在进行DB的主从切换&#xff0c;导致应用一直报错&#xff0c;获取不到DB连接&#xff0c;druid的错误信息如下&#xff1a; Could not open JDBC Connection for transaction; nested exception is com.alibaba.druid.pool.GetConnectionTimeoutExc…...

【iOS】Mac M1安装iPhone及iPad的app时设置问题

【iOS】Mac M1安装iPhone及iPad的app时设置问题 简介一&#xff0c;设置问题二&#xff0c;适配问题 简介 由于 苹果M1芯片的Mac可用安装iPhone以及iPad应用&#xff0c;因为开发者并没有适配Mac&#xff0c;因此产生了很多奇怪问题&#xff0c;这里总结归纳Mac M1安装iPhone和…...

Springboot 启动报错@spring.active@解析错误

Caused by: org.yaml.snakeyaml.scanner.ScannerException: while scanning for the next token found character that cannot start any token. (Do not use for indentation)in reader, line 10, column 13:active: spring.active^查看是否勾选...

【算法挨揍日记】day15——560. 和为 K 的子数组、974. 和可被 K 整除的子数组

560. 和为 K 的子数组 560. 和为 K 的子数组 题目描述&#xff1a; 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的连续子数组的个数 。 子数组是数组中元素的连续非空序列。 解题思路&#xff1a; 我们可以很容易想到暴力解法&#xf…...

数字时代的探索与革新:Socks5代理的引领作用

在当今快速发展的数字时代&#xff0c;技术创新推动着社会的变革与进步。Socks5代理作为一项重要的网络技术&#xff0c;正引领着跨界电商、爬虫数据分析、企业全球化和游戏体验优化等领域的发展。本文将深入探讨Socks5代理技术在这些领域中的引领作用&#xff0c;以及它如何塑…...

算法-堆/归并排序-排序链表

算法-堆/归并排序-排序链表 1 题目概述 1.1 题目出处 https://leetcode.cn/problems/sort-list/description/?envTypestudy-plan-v2&envIdtop-interview-150 1.2 题目描述 2 优先级队列构建大顶堆 2.1 思路 优先级队列构建小顶堆链表所有元素放入小顶堆依次取出堆顶…...

word 如何编写4x4矩阵

百度上给的教程&#xff0c;打印出来没有对齐 https://jingyan.baidu.com/article/6b182309995f8dba58e159fc.html 百度上的方式试了一下&#xff0c;不会对齐。导致公式看起来很奇怪。 下面方式会自动对齐 摸索了一下发现可以用下面这种方式编写 4x4 矩阵。先创建一个 3x3…...

INTELlij IDEA编辑VUE项目

菜单中选择setting–>Plugins 或者快捷键 ctrlalts 搜索vue&#xff0c;但有些情况会搜索不出来&#xff0c;先说搜索到的情况 如下图所示&#xff1a; 如果没有vue.js则说明过去已经安装了。 搜索到了后点击Install安装即可&#xff0c; 但即使搜索成功了&#xff0c;也不…...

linux进程间通讯--信号量

1.认识信号量 方便理解&#xff1a;信号量就是一个计数器。当它大于0能用&#xff0c;小于等于0&#xff0c;用不了&#xff0c;这个值自己给。 2.特点&#xff1a; 信号量用于进程间同步&#xff0c;若要在进程间传递数据需要结合共享内存。信号量基于操作系统的 PV 操作&am…...

VS Code连接远程Linux服务器开发c++项目

1.在远程 Linux 上安装包 yum groupinstall "development tools" -y yum install cmake -y2.在 VSCode 上安装插件 C/CC/C Extension PackCMakeCMake ToolsCMake Language Support 3.连接远程Linux服务器...