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

news2025/3/12 1:07:14

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

 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 {
    @Autowired
    private 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;

    @Test
    void getUserById() {
        //3. 添加单元测试的业务代码
        UserInfo userinfo=userMapper.getUserById(1);
        System.out.println(userinfo);
        /**使用断言->判断最终结果是否符合预期!?
         *
         * */
        Assertions.assertEquals("John",userinfo.getName());
    }


    @Test
    void getAll() {
        List<UserInfo> list=userMapper.getAll();
        Assertions.assertEquals(8,list.size());
    }

    @Test
    void 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(); // 提交事务
    }

    @Test
    void 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


    }

    @Test
    void 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);

    }

    @Test
    void   getListByOrder() {
        List<UserInfo> list=userMapper.getListByOrder("asc");
        System.out.println(list);
    }

    @Test
    void 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?"失败":"成功"));
    }


    @Test
    void 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);
    }


    @Test
    void add3() {
        UserInfo userinfo=new UserInfo();
        userinfo.setId(13);
        userinfo.setName("sss");
        userinfo.setEmail("12432`");
        int result=userMapper.add3(userinfo);
        Assertions.assertEquals(1,result);

    }

    @Test
    void 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
    }

    @Test
    void 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, 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何获取方法上声明的注解

开发过程当中部分场景需要获取到方法或类上的注解&#xff0c;但是经常会有无法渠道注解的情况&#xff0c;这种情况很可能是该注解所在的类是一个代理类&#xff0c;比如被AOP动态代理【注意&#xff1a;通过】。本文以CGLIB为例&#xff0c;说明为什么无法取到方法或类上的注…

读《中国省级移动政务服务报告2023》

报告地址&#xff1a; 中国省级移动政务服务报告2022 https://www.digitalelite.cn/h-nd-7846.html 中国省级移动政务服务报告2023 中国省级移动政务服务报告2023 报告分为 引言、评估方法、概貌、指数、标杆、建言 六个部分。 一些思考 移动政务服务应用针对各省的常驻人口…

vueday02——使用NTableData

1.下载naivueui 2.按需导入&#xff0c;不要全局导入 注意不要导入错误组件或者写错组件名称 import { NDataTable } from naive-ui 3.定义表头和数据&#xff01;&#xff01;&#xff01; n-data-table标签必须要使用数据和数据 少一个都不能正确渲染&#xff01;&#xf…

在 Android 上恢复已删除音乐的 5 种简单方法

人们经常将重要的音乐文件保存在智能手机上&#xff0c;以方便随时随地收听自己喜欢的曲目。但是&#xff0c;如果这些珍贵的音乐文件因软件故障或硬件故障而被意外删除或丢失怎么办&#xff1f;这将是许多音乐爱好者的噩梦&#xff01; 如果您也是这些人中的一员&#xff0c;…

8月PMP出成绩了,意味着什么?

之前胖圆给大家分享过&#xff0c;10月16号PMI官网将发布8.19的PMP考试成绩&#xff0c;这两天已经有学员陆陆续续收到考试通过的邮件&#xff0c;还没有收到成绩通知的学员耐心等待&#xff0c;相信努力备考的学员一定都能够顺利通过~ 还没查询成绩的宝子可以移步胖圆上一篇笔…

C/C++面试常见问题——static关键字的主要用法

首先我们要明确一下C/C的内存区域划分 在C/C中内存主要被划分为四大块&#xff0c;堆&#xff0c;栈&#xff0c;全局/静态存储区&#xff0c;代码区 而全局/静态存储区又被细分为常量区(静态常量区&#xff0c;const关键字修饰)&#xff0c;全局区(全局变量区)和静态变量区(…

LiveGBS流媒体平台GB/T28181常见问题-安全控制HTTP接口鉴权勾选流地址鉴权后401Unauthorized如何播放调用接口

LiveGBS流媒体平台GB/T28181常见问题-安全控制HTTP接口鉴权勾选流地址鉴权后401 Unauthorized如何播放调用接口&#xff1f; 1、安全控制1.1、HTTP接口鉴权1.2、流地址鉴权 2、401 Unauthorized2.1、携带token调用接口2.1.1、获取鉴权token2.1.2、调用其它接口2.1.2.1、携带 Co…

微盟盈利困局难解

又是一年“双11”临近&#xff0c;微盟(2013.HK)、有赞等国内电商SaaS头部企业之间的战斗已经悄然打响。 作为从微信生态里生长出来的第三方服务商&#xff0c;根据微盟此前公布2023年半年报&#xff0c;其营收增长背后仍难掩亏损困局。 「不二研究」据微盟财报发现&#xff…

新产品发布新闻稿推广文案怎么写?纯干货

一篇优质的新闻稿传播速度是非常快的&#xff0c;可以让产品获得大量曝光和展现&#xff0c;提高产品的知名度和口碑&#xff0c;这样的稿件撰写起来是需要掌握一定的技巧的&#xff0c;新产品发布新闻稿推广文案怎么写&#xff1f;伯乐网络传媒十多年文案撰写经验&#xff0c;…

Windows10系统开启SNMP服务

Windows10系统开启SNMP服务 1、打开控制面板&#xff0c;选择卸载程序2、点击启用或关闭Windows功能3、将SNMP协议开启&#xff08;如果有该内容请直接跳至步骤7&#xff0c;如找不到该协议请继续看步骤4&#xff09;4、找不到步骤3中内容原因&#xff1a;Windwos10 1809后更新…

Flow深入浅出系列之更聪明的分享 Kotlin Flows

Flow深入浅出系列之在ViewModels中使用Kotlin FlowsFlow深入浅出系列之更聪明的分享 Kotlin FlowsFlow深入浅出系列之使用Kotlin Flow自动刷新Android数据的策略 Flow深入浅出系列之更聪明的分享 Kotlin Flows 使生命周期对上游流有效&#xff0c;以跳过不必要的工作。这是一…

vue2打包优化-小白也可快速上手的一套

需求&#xff1a;项目过大可以使用打包优化&#xff0c;减少项目体积&#xff0c;加速页面加载&#xff0c;增强用户体验&#xff0c;跟着步骤来即可实现&#xff0c;主要是vue2的打包优化&#xff0c;不是vue3&#xff0c;文章可能有点长&#xff0c;但是很实用哈哈&#xff0…

openGauss学习笔记-102 openGauss 数据库管理-管理数据库安全-客户端接入之查看数据库连接数

文章目录 openGauss学习笔记-102 openGauss 数据库管理-管理数据库安全-客户端接入之查看数据库连接数102.1 背景信息102.2 操作步骤 openGauss学习笔记-102 openGauss 数据库管理-管理数据库安全-客户端接入之查看数据库连接数 102.1 背景信息 当用户连接数达到上限后&#…

单片机入门后该怎么学习进一步提升?

单片机入门后该怎么学习进一步提升&#xff1f; 可以将你目前会的单片机基础先整理一下&#xff0c;你看看运用这些基本的外设或者一些入门知识能做个什么东西&#xff0c;最近很多小伙伴找我&#xff0c;说想要一些单片机资料&#xff0c;然后我根据自己从业十年经验&#xff…

Redis主从复制流程

前言 Redis 支持部署多节点&#xff0c;然后按照 1:n 的方式构建主从集群&#xff0c;即一个主库、n 个从库。主从库之间会自动进行数据同步&#xff0c;但是只有主库同时允许读写&#xff0c;从库只允许读。 搭建主从复制集群的目的&#xff1a; 从库可用于容灾备份从库可以…

Unity3D 基础——使用 Mathf.SmoothDamp 函数制作相机的缓冲跟踪效果

使用 Mathf.SmoothDamp 函数制作相机的缓冲跟踪效果&#xff0c;让物体的移动不是那么僵硬&#xff0c;而是做减速的缓冲效果。将以下的脚本绑定在相机上&#xff0c;然后设定好 target 目标对象&#xff0c;即可看到相机的缓动效果。通过设定 smoothTime 的值&#xff0c;可以…

安达发|AI人工智能APS系统:工业4.0的智能引擎

在工业4.0的背景下&#xff0c;人工智能&#xff08;AI&#xff09;和APS智能排程软件已经成为智能工厂的标准配置。它们通过集成先进的信息技术、通信技术和物联网技术&#xff0c;实现了生产过程的智能化、自动化和数据化&#xff0c;从而提高了生产效率、降低了生产成本、提…

运行.sln 32/64位程序,启动不了,无法显示界面

32/64位启动不了&#xff0c;无法显示界面。后台有进程 》环境变量--轴控下&#xff0c;选择的“串口”选择了虚拟串口(比如&#xff1a;com3&#xff0c;是蓝牙串口)&#xff0c;或者因为当前机台以前虚拟过这个串口&#xff0c;所以存在。串口存在&#xff0c;就会去调用函数…

微信小程序----会议oa项目---首页

目录 什么是Flex弹性布局 图解 代码演示 flex弹性布局的特点 Flex 弹性布局的常见属性 flex-wrap属性 flex-flow属性 轮播图后台数据获取及组件使用 首页布局 什么是Flex弹性布局 Flex 弹性布局&#xff08;Flexbox&#xff09;是一种用于在容器中进行灵活排列和对齐元素的…

Java数据结构——应用DFS算法计算流程图下游节点(1)

问题描述&#xff1a; 前端在绘制流程图的时候&#xff0c;某些情况需要对某个节点之后的流程图进行折叠&#xff0c;因此需要得到某个节点的ID后&#xff0c;计算出这个ID下游之后的所有节点&#xff08;找到的节点&#xff0c;边也就找到了&#xff09; 已知条件&#xff1a…