MyBatis查询数据库(2)

简介: MyBatis查询数据库(2)

一、增删查改操作🍭

下面操作会使用到Spring Boot单元测试,可以先看:

Spring Boot单元测试

1、查🍉

查询所有的用户:

Ⅰ、mapper接口:🍓


package com.example.ssmdemo1.mapper;
import com.example.ssmdemo1.entity.Userinfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper//需要添加 @Mapper 注解
public interface UserMapper {
    /**
     * 根据用户id查询用户信息
     * @param id
     * @return
     */
    Userinfo getUserById(@Param("id") Integer id);
    //查询所有的用户
    List getAll();
}

image.png

Ⅱ、UserMapper.xml 查询所有用户的具体实现 SQL:🍓

image.png

使用$进行传递参数可能会SQL注入,所以大部分情况下是使用#的


"1.0" encoding="UTF-8"?>
mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.ssmdemo1.mapper.UserMapper">
    <select id="getUserById" resultType="com.example.ssmdemo1.entity.Userinfo">
        select * from userinfo where id=${id}
    select>
    <select id="getAll" resultType="com.example.ssmdemo1.entity.Userinfo">
        select * from userinfo
    select>
mapper>

Ⅲ、进行单元测试🍓

image.png

image.png

在UserMapperTest中就有了getAll的测试代码:

image.png

添加单元测试业务逻辑


package com.example.ssmdemo1.mapper;
import com.example.ssmdemo1.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 java.util.List;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest//1、表明当前单元测试是运行在Spring Boot环境中的
class UserMapperTest {
    //2、注入测试对象
    @Autowired
    private UserMapper userMapper;
    @Test
    void getUserById() {
        //3、添加单元测试的业务代码
        Userinfo userinfo=userMapper.getUserById(1);
        System.out.println(userinfo);
        //判断1是否等于2 简单断言
        Assertions.assertEquals("admin",userinfo.getUsername());
    }
    @Test
    void getAll() {
        List list=userMapper.getAll();
        Assertions.assertEquals(1,list.size());//断言判断list集合里面是否只有一条数据,即查询数据库中只有一个用户
    }
}

测试正确:

image.png

如果我们没有设置resultType,则 MyBatis无法自动将查询结果映射到Java对象,这就会导致单元测试失败并报错。

image.png

2、增、删、改操作🍉

与查询操作都是一样的,只是使用的标签不一样:

  • insert标签:插入语句
  • update标签:修改语句
  • delete标签:删除语句

Ⅰ、增🍓

添加用户🍒

①、在接口(UserMapper)中声明方法


Integer add(Userinfo user);

②、UserService


public Integer getAdd(Userinfo user) {return userMapper.add(user);}

③、在xml中提供实现


<insert id="add">
        insert into userinfo(username,password) values(#{username},#{password})
insert>

#{} 进行赋值使用的是对象中的属性。

注意:对应的不是数据库的字段,而是程序类中的属性。

④、controller 实现代码:


@RequestMapping(value = "/add",method = RequestMethod.POST)
    public Integer add(@RequestBody Userinfo user){
        return userService.getAdd(user);
    }

⑤、单元测试


@Test
    void add() {
        //伪代码,构建对象并设置对应的值
        //本来是前端传值过来
        Userinfo userinfo=new Userinfo();
        userinfo.setUsername("张三");
        userinfo.setPassword("123456");
        //调用mybatis 添加方法执行添加操作
        int result=userMapper.add(userinfo);
        Assertions.assertEquals(1,result);
    }

单元测试成功,可以去看数据库也添加了一条数据

image.png

但是如果我们去获取这个用户的id,就会报空指针异常:

image.png

添加用户并且返回自增 id🍒

如果我们想在添加用户的时候同时去获取他的id,具体实现如下:

①、在接口(UserMapper)中声明方法


Integer addGetid(Userinfo user);

②、UserService


public Integer addGetid(Userinfo user) {return userMapper.addGetid(user);}

③、在xml中提供实现


<insert id="addGetid" useGeneratedKeys="true" keyProperty="id">
        insert into userinfo(username,password) values(#{username},#{password})
insert>
  • useGeneratedKeys:这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的自动递增字段),默认值:false。
  • keyColumn:设置生成键值在表中的列名,在某些数据库(像 PostgreSQL)中,当主键列 不是表中的第⼀列的时候,是必须设置的。如果⽣成列不止⼀个,可以用逗号分隔多个属性 名称。
  • keyProperty:指定能够唯⼀识别对象的属性,MyBatis会使用 getGeneratedKeys 的返回值或 insert 语句的 selectKey 子元素设置它的值,默认值:未设置(unset)。如果生成列不止⼀个,可以⽤逗号分隔多个属性名称。

④、controller 实现代码:


@RequestMapping(value = "/add2", method = RequestMethod.POST)
    public Integer add2(@RequestBody Userinfo user) {
        userService.addGetid(user);
        return user.getId();
    }

⑤、单元测试


@Test
    void addGetid() {
        //伪代码,构建对象并设置对应的值
        //本来是前端传值过来
        Userinfo userinfo=new Userinfo();
        userinfo.setUsername("张三");
        userinfo.setPassword("123456");
        //调用MyBatis 添加方法执行添加操作 返回受影响的行数
        int result=userMapper.addGetid(userinfo);
        int id=userinfo.getId();//得到自增id(MyBatis自动赋值)
        System.out.println("id:"+id);
        Assertions.assertEquals(1,result);
    }

一样的代码,就一行代码不同

image.png

Ⅱ、改🍓

根据id修改用户名🍒

①、在接口(UserMapper)中声明方法


/**
     * 修改用户
     * @param userinfo
     * @return
     */
    Integer upUserName(Userinfo userinfo);

②、在xml中提供实现


<update id="upUserName">
        update userinfo set username=#{username} where id=#{id}
update>

③、单元测试

将之前添加的张三修改成为李四


@Test
    void upUserName() {
        // 构建测试数据
        Userinfo userinfo = new Userinfo();
        userinfo.setId(9);
        userinfo.setUsername("李四");
        int result = userMapper.upUserName(userinfo);
        System.out.println("修改:" + result);
        Assertions.assertEquals(1, result);
    }

修改成功:

image.png

如果我们需要在控制台看到SQL语句,需要去配置文件进行配置,因为这默认是隐藏MyBatic生成SQL语句的细节

开启 MyBatis sql 日志打印🍒

①、添加配置文件


# 开启 mybatis sql 日志打印
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
logging.level.com.example.demo=debug

②、重新运行单元测试


@Test
    void upUserName() {
        // 构建测试数据
        Userinfo userinfo = new Userinfo();
        userinfo.setId(9);
        userinfo.setUsername("张三");
        int result = userMapper.upUserName(userinfo);
        System.out.println("修改:" + result);
        Assertions.assertEquals(1, result);
    }

执行成功:

image.png

结论: 可以看到这个就是jdbc链接,这个SQL写法也是jdbc的写法,也就是说mybatis是基于jdbc的,MyBatis使用了JDBC来与数据库进行交互,它也简化了JDBC的使用,提供了更方便的数据库访问方式。。

建议大家在开发阶段是开启SQL的打印,可以更好的帮助你找到错误。

Ⅲ、删🍓

①、在接口(UserMapper)中声明方法


int delById(@Param("id") Integer id);

②、在xml中提供实现


<delete id="delById">
        delete from userinfo where id=#{id}
delete>

③、单元测试

将id为9的用户删除:


@Test
    void delById() {
        int id=9;
        int result=userMapper.delById(id);
        System.out.println("删除:"+result);
        Assertions.assertEquals(1,result);
    }

删除成功:

image.png

二、在单元测试时不污染数据库🍭

在需要的地方添加注解:@Transactional(可以修饰方法也可以修饰类)

image.png

如下面,去修饰UserMapper整个类:

image.png



相关文章
|
11月前
|
人工智能 安全 机器人
无代码革命:10分钟打造企业专属数据库查询AI机器人
随着数字化转型加速,企业对高效智能交互解决方案的需求日益增长。阿里云AppFlow推出的AI助手产品,借助创新网页集成技术,助力企业打造专业数据库查询助手。本文详细介绍通过三步流程将AI助手转化为数据库交互工具的核心优势与操作指南,包括全场景适配、智能渲染引擎及零代码配置等三大技术突破。同时提供Web集成与企业微信集成方案,帮助企业实现便捷部署与安全管理,提升内外部用户体验。
978 12
无代码革命:10分钟打造企业专属数据库查询AI机器人
|
Cloud Native 关系型数据库 分布式数据库
|
并行计算 关系型数据库 MySQL
如何用 esProc 将数据库表转储提速查询
当数据库查询因数据量大或繁忙变慢时,可借助 esProc 将数据导出为文件进行计算,大幅提升性能。以 MySQL 的 3000 万行订单数据为例,两个典型查询分别耗时 17.69s 和 63.22s。使用 esProc 转储为二进制行存文件 (btx) 或列存文件 (ctx),结合游标过滤与并行计算,性能显著提升。例如,ctx 并行计算将原查询时间缩短至 0.566s,TopN 运算提速达 30 倍。esProc 的简洁语法和高效文件格式,特别适合历史数据的复杂分析场景。
|
10月前
|
SQL XML Java
MyBatis Mapper中使用limit参数的查询问题
总结而言,MyBatis中使用 `limit`参数的查询可以高度定制并且灵活,基于方法签名和XML映射文件的组合来达成多样化的查询需求。通过参数化查询和动态SQL,MyBatis可以有效地处理各种复杂情境下的数据库操作,并且将SQL语句的维护与业务代码的编写相分离,提升代码的可维护性和可阅读性。
808 13
|
11月前
|
SQL Java 数据库
解决Java Spring Boot应用中MyBatis-Plus查询问题的策略。
保持技能更新是侦探的重要素质。定期回顾最佳实践和新技术。比如,定期查看MyBatis-Plus的更新和社区的最佳做法,这样才能不断提升查询效率和性能。
641 1
|
SQL 关系型数据库 MySQL
如何优化SQL查询以提高数据库性能?
这篇文章以生动的比喻介绍了优化SQL查询的重要性及方法。它首先将未优化的SQL查询比作在自助餐厅贪多嚼不烂的行为,强调了只获取必要数据的必要性。接着,文章详细讲解了四种优化策略:**精简选择**(避免使用`SELECT *`)、**专业筛选**(利用`WHERE`缩小范围)、**高效联接**(索引和限制数据量)以及**使用索引**(加速搜索)。此外,还探讨了如何避免N+1查询问题、使用分页限制结果、理解执行计划以及定期维护数据库健康。通过这些技巧,可以显著提升数据库性能,让查询更高效流畅。
|
数据库 Python
【YashanDB知识库】python驱动查询gbk字符集崖山数据库CLOB字段,数据被驱动截断
【YashanDB知识库】python驱动查询gbk字符集崖山数据库CLOB字段,数据被驱动截断
|
数据库
【YashanDB知识库】数据库用户所拥有的权限查询
【YashanDB知识库】数据库用户所拥有的权限查询
|
存储 运维 监控
百万指标,秒级查询,零宕机——时序数据库 TDengine 在 AIOps 中的硬核实战
本篇文章详细讲述了七云团队在运维平台中如何利用 TDengine 解决海量时序数据存储与查询的实际业务需求。内容涵盖了从数据库选型、方案落地到业务挑战及解决办法的完整过程,特别是分享了升级 TDengine 3.x 时的实战经验,给到有需要的小伙伴参考阅读。
669 1