Spring与Mybatis-增删改查(注解方式与配置文件方式)

Spring框架下Mybaits的使用

  • 准备数据库
  • 配置application.properties
  • pom.xml添加lombok依赖
  • 创建Emp实体类
  • 准备Mapper接口:EmpMapper
  • 预编译SQL
  • 根据id查询数据
    • Mapper接口方法
    • 配置application.properties开启自动结果映射
    • 单元测试
  • 条件模糊查询
    • Mapper接口方法
    • 单元测试
  • 根据主键删除数据
    • Mapper接口方法
    • 单元测试
  • 添加数据
    • Mapper接口方法
    • 单元测试
  • 主键返回
    • Mapper接口方法
    • 单元测试
  • 根据员工id修改数据
    • Mapper接口方法
    • 单元测试
  • XML配置文件规范
    • XML配置步骤
      • 第一步:创建xml文件
      • 第二步:在EmpMapper接口中添加抽象方法
      • 第三步:编写XML映射文件
      • 第四步:测试
  • MybatisX的使用
    • MybatisX插件安装
    • MybatisX使用
  • 总结

准备数据库

-- 部门管理
create table dept
(
    id          int unsigned primary key auto_increment comment '主键ID',
    name        varchar(10) not null unique comment '部门名称',
    create_time datetime    not null comment '创建时间',
    update_time datetime    not null comment '修改时间'
) comment '部门表';
-- 部门表测试数据
insert into dept (id, name, create_time, update_time)
values (1, '学工部', now(), now()),
       (2, '教研部', now(), now()),
       (3, '咨询部', now(), now()),
       (4, '就业部', now(), now()),
       (5, '人事部', now(), now());


-- 员工管理
create table emp
(
    id          int unsigned primary key auto_increment comment 'ID',
    username    varchar(20)      not null unique comment '用户名',
    password    varchar(32) default '123456' comment '密码',
    name        varchar(10)      not null comment '姓名',
    gender      tinyint unsigned not null comment '性别, 说明: 1 男, 2 女',
    image       varchar(300) comment '图像',
    job         tinyint unsigned comment '职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师',
    entrydate   date comment '入职时间',
    dept_id     int unsigned comment '部门ID',
    create_time datetime         not null comment '创建时间',
    update_time datetime         not null comment '修改时间'
) comment '员工表';
-- 员工表测试数据
INSERT INTO emp (id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time)
VALUES 
(1, 'jinyong', '123456', '金庸', 1, '1.jpg', 4, '2000-01-01', 2, now(), now()),
(2, 'zhangwuji', '123456', '张无忌', 1, '2.jpg', 2, '2015-01-01', 2, now(), now()),
(3, 'yangxiao', '123456', '杨逍', 1, '3.jpg', 2, '2008-05-01', 2, now(), now()),
(4, 'weiyixiao', '123456', '韦一笑', 1, '4.jpg', 2, '2007-01-01', 2, now(), now()),
(5, 'changyuchun', '123456', '常遇春', 1, '5.jpg', 2, '2012-12-05', 2, now(), now()),
(6, 'xiaozhao', '123456', '小昭', 2, '6.jpg', 3, '2013-09-05', 1, now(), now()),
(7, 'jixiaofu', '123456', '纪晓芙', 2, '7.jpg', 1, '2005-08-01', 1, now(), now()),
(8, 'zhouzhiruo', '123456', '周芷若', 2, '8.jpg', 1, '2014-11-09', 1, now(), now()),
(9, 'dingminjun', '123456', '丁敏君', 2, '9.jpg', 1, '2011-03-11', 1, now(), now()),
(10, 'zhaomin', '123456', '赵敏', 2, '10.jpg', 1, '2013-09-05', 1, now(), now()),
(11, 'luzhangke', '123456', '鹿杖客', 1, '11.jpg', 5, '2007-02-01', 3, now(), now()),
(12, 'hebiweng', '123456', '鹤笔翁', 1, '12.jpg', 5, '2008-08-18', 3, now(), now()),
(13, 'fangdongbai', '123456', '方东白', 1, '13.jpg', 5, '2012-11-01', 3, now(), now()),
(14, 'zhangsanfeng', '123456', '张三丰', 1, '14.jpg', 2, '2002-08-01', 2, now(), now()),
(15, 'yulianzhou', '123456', '俞莲舟', 1, '15.jpg', 2, '2011-05-01', 2, now(), now()),
(16, 'songyuanqiao', '123456', '宋远桥', 1, '16.jpg', 2, '2010-01-01', 2, now(), now()),
(17, 'chenyouliang', '123456', '陈友谅', 1, '17.jpg', NULL, '2015-03-21', NULL, now(), now());

配置application.properties

#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://localhost:3306/数据库名
#连接数据库的用户名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=密码
#指定mybatis输出日志的位置, 输出控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# 自动结果映射
mybatis.configuration.map-underscore-to-camel-case=true

pom.xml添加lombok依赖

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

创建Emp实体类

//使用注解方式生成get、set、toString、构造器等
@Data //getter方法、setter方法、toString方法、hashCode方法、equals方法
@NoArgsConstructor //无参构造
@AllArgsConstructor//全参构造
public class Emp {
    private Integer id;
    private String username;
    private String password;
    private String name;
    private Short gender;
    private String image;
    private Short job;
    private LocalDate entrydate;     //LocalDate类型对应数据表中的date类型
    private Integer deptId;
    private LocalDateTime createTime;//LocalDateTime类型对应数据表中的datetime类型
    private LocalDateTime updateTime;
}

准备Mapper接口:EmpMapper

@Mapper
public interface EmpMapper {

}

预编译SQL

在Mybatis中提供的参数占位符有两种:${…} 、#{…}

  • #{…}

    • 执行SQL时,会将#{…}替换为?,生成预编译SQL,会自动设置参数值
    • 使用时机:参数传递,都使用#{…}
  • ${…}

    • 拼接SQL。直接将参数拼接在SQL语句中,存在SQL注入问题
    • 使用时机:如果对表名、列表进行动态设置时使用

注意事项:在项目开发中,建议使用#{…},生成预编译SQL,防止SQL注入安全。

根据id查询数据

问题:查询字段数据为null

  • 实体类属性名和数据库表查询返回的字段名一致,mybatis会自动封装。
  • 如果实体类属性名和数据库表查询返回的字段名不一致,不能自动封装。查询出来的数据为null

解决:

  1. 起别名
  2. 结果映射
  3. 开启驼峰命名

Mapper接口方法

配置application.properties开启自动结果映射

mybatis.configuration.map-underscore-to-camel-case=true

使用前提

  • 实体类的属性 与 数据库表中的字段名严格遵守驼峰命名
  • 表中字段名:abc_xyz
  • 类中属性名:abcXyz
	//2.结果映射查询
    @Select("select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp where id=#{id}")
    Emp getById(Integer id);
	
	//1.起别名查询
	@Select("select id, username, password, name, gender, image, job, entrydate, " +
	        "dept_id AS deptId, create_time AS createTime, update_time AS updateTime " +
	        "from emp " +
	        "where id=#{id}")
	Emp getById(Integer id);

	//3.手动结果映射
	@Results({@Result(column = "dept_id", property = "deptId"),
	          @Result(column = "create_time", property = "createTime"),
	          @Result(column = "update_time", property = "updateTime")})
	@Select("select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp where id=#{id}")
	public Emp getById(Integer id);

单元测试

    @Test
    public void testGetById(){
        Emp emp = empMapper.getById(1);
        System.out.println(emp);
    }

在这里插入图片描述

条件模糊查询

Mapper接口方法

    @Select("select * from emp " +
            "where name like concat('%',#{name},'%') " +
            "and gender = #{gender} " +
            "and entrydate between #{begin} and #{end} " +
            "order by update_time desc")
    List<Emp> getList(String name, Short gender, LocalDate begin, LocalDate end);

单元测试

    @Test
    public void testGet(){
        List<Emp> emps = empMapper.getList("张",(short)1,LocalDate.of(2000,1,1),LocalDate.of(2025,1,1));
        for (Emp emp : emps){
            System.out.println(emp);
        }
    }

在这里插入图片描述

根据主键删除数据

Mapper接口方法

    //如果mapper接口方法形参只有一个普通类型的参数,#{…} 里面的属性名可以随便写
    //但是建议保持名字一致
    @Delete("delete from emp where id = #{id}")
    int deletById(Integer id);

单元测试

    @Autowired//从Spring的IOC容器中,获取类型是EmpMapper的对象并注入
    private EmpMapper empMapper;

    @Test
    void deleteById(){
        Integer row = empMapper.deletById(16);
        System.out.println(row > 0 ? "删除成功" : "删除失败");
    }

在这里插入图片描述

添加数据

Mapper接口方法

    @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) values (#{username}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, #{updateTime})")
    int insert(Emp emp);

单元测试

   @Test
    public void testInsert(){
        //创建员工对象
        Emp emp = new Emp();
        emp.setUsername("tom");
        emp.setName("汤姆");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000,1,1));
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);
        //调用添加方法
        Integer row = empMapper.insert(emp);
        System.out.println(row > 0 ? "添加成功" : "添加失败");
    }

在这里插入图片描述

主键返回

在数据添加成功后,需要获取插入数据库数据的主键,主键在数据库中是自动增长的,在java代码中并未设置主键数据

  • 默认情况下,执行插入操作时,是不会主键值返回的。如果我们想要拿到主键值,需要在Mapper接口中的方法上添加一个Options注解,并在注解中指定属性useGeneratedKeys=true和keyProperty=“实体类属性名”

Mapper接口方法

    @Options(useGeneratedKeys = true,keyProperty = "id")
    @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) values (#{username}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, #{updateTime})")
    int insert(Emp emp);

单元测试

    @Test
    public void testInsert(){
        //创建员工对象
        Emp emp = new Emp();
        emp.setUsername("Jerry");
        emp.setName("杰瑞");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000,1,1));
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);
        //调用添加方法
        empMapper.insert(emp);

        System.out.println("id是:" + emp.getId());

    }

在这里插入图片描述

根据员工id修改数据

Mapper接口方法

    @Update("update emp set username=#{username}, name=#{name}, gender=#{gender}, image=#{image}, job=#{job}, entrydate=#{entrydate}, dept_id=#{deptId}, update_time=#{updateTime} where id=#{id}")
    int update(Emp emp);

单元测试

    @Test
    public void testUpdate(){
        //要修改的员工信息
        Emp emp = new Emp();
        emp.setId(23);
        emp.setUsername("songdaxia");
        emp.setPassword(null);
        emp.setName("老宋");
        emp.setImage("2.jpg");
        emp.setGender((short)1);
        emp.setJob((short)2);
        emp.setEntrydate(LocalDate.of(2012,1,1));
        emp.setCreateTime(null);
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(2);
        //调用方法,修改员工数据
        empMapper.update(emp);
    }

在这里插入图片描述

XML配置文件规范

使用Mybatis的注解方式,主要是来完成一些简单的增删改查功能。如果需要实现复杂的SQL功能,建议使用XML来配置映射语句,也就是将SQL语句写在XML配置文件中。
在Mybatis中使用XML映射文件方式开发,需要符合一定的规范:

  1. XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)
  2. XML映射文件的namespace属性为Mapper接口全限定名一致
  3. XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致。
    在这里插入图片描述
    在这里插入图片描述

XML配置步骤

第一步:创建xml文件

在resources配置文件夹下创建同包同名的xml文件
切记:在resources配置文件下创建包,包名之间使用 / 分割

第二步:在EmpMapper接口中添加抽象方法

   List<Emp> getListByName(String name);

第三步:编写XML映射文件

注意:
namespace:接口全路径
id:指向接口中的抽象方法名
resultType:返回值类型
parameterType:传入参数类型

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.EmpMapper">
    <select id="getListByName" resultType="com.example.model.Emp" parameterType="String">
        select * from emp where name like concat('%',#{name},'%')
    </select>
</mapper>

第四步:测试

    @Test
    public void testGetByName(){
        List<Emp> emps = empMapper.getListByName("张");
        for (Emp emp : emps){
            System.out.println(emp);
        }
    }

在这里插入图片描述

MybatisX的使用

MybatisX是一款基于IDEA的快速开发Mybatis的插件,为效率而生。

MybatisX插件安装

在这里插入图片描述

MybatisX使用

点击logo可以通过MybatisX快速定位
在这里插入图片描述

总结

使用Mybatis的注解,主要是来完成一些简单的增删改查功能。
如果需要实现复杂的SQL功能,建议使用XML来配置映射语句。

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

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

相关文章

大模型时序预测初步调研20240506

AI预测相关目录 AI预测流程&#xff0c;包括ETL、算法策略、算法模型、模型评估、可视化等相关内容 最好有基础的python算法预测经验 EEMD策略及踩坑VMD-CNN-LSTM时序预测对双向LSTM等模型添加自注意力机制K折叠交叉验证optuna超参数优化框架多任务学习-模型融合策略Transform…

目标检测常用评价指标详解

&#x1f380;个人主页&#xff1a; https://zhangxiaoshu.blog.csdn.net &#x1f4e2;欢迎大家&#xff1a;关注&#x1f50d;点赞&#x1f44d;评论&#x1f4dd;收藏⭐️&#xff0c;如有错误敬请指正! &#x1f495;未来很长&#xff0c;值得我们全力奔赴更美好的生活&…

数字孪生—物联网技术

数字孪生涉及到诸多技术领域&#xff0c;物联网技术在数据孪生项目中具有重要的应用价值&#xff0c;主要体现在以下几个方面&#xff1a; 1.数据采集和实时监测&#xff1a;物联网技术可以用于实时采集各种设备、传感器和设施的数据&#xff0c;包括温度、湿度、压力、振动等…

CMakeLists.txt语法规则:foreach循环的关键字

一. 简介 前一篇文章学习了 CMakeLists.txt语法中 foreach循环的基本用法。文章如下&#xff1a; CMakeLists.txt语法规则&#xff1a;foreach 循环基本用法-CSDN博客 本文继续 CMakeLists.txt语法中 foreach循环语句&#xff0c;主要学习 foreach循环中的关键字。 二. CM…

【OceanBase诊断调优】—— SQL 执行报错而不能计入 SQL_AUDIT 的情况

通常&#xff0c;执行成果的 SQL 都会计入 SQL_AUDIT 中&#xff0c;而执行报错的 SQL 则需要依据其执行报错的阶段来决定是否计入 SQL_AUDIT 中。 在 OceanBase 数据库中&#xff0c;SQL 请求的执行流程如图所示。 如果 SQL 在进入 Executor 阶段前发生报错&#xff0c;则该 …

java-Spring-Lombok-讲解-(一文一言)创伤是成熟的途径

高手都在孤独前进-致敬我们不悔的青春 我打算每篇文章下找一下文言警句-说不那天会用上&#x1f601;&#x1f601;&#x1f601;&#x1f601; 每篇一言 创伤是成熟的途径 希望经历过创伤的人,能更好享受当下, 爱自己胜过爱别人呀 目录 &#x1f3bb;Lombok简介 &#…

KIE关键信息抽取——SDMG-R

https://arxiv.org/pdf/2103.14470https://arxiv.org/pdf/2103.14470 1.概述 背景:传统的关键信息提取方法依赖于模板匹配,这使它们难以泛化到未见过的模板,且对文本识别错误不够鲁棒。SDMG-R方法:提出一种端到端的双模态图推理方法,通过构建双模态图(视觉和文本特征),…

Celery(分布式任务队列)入门学习笔记

Celery 的简单介绍 用 Celery 官方的介绍&#xff1a;它是一个分布式任务队列; 简单&#xff0c;灵活&#xff0c;可靠的处理大量消息的分布式系统; 它专注于实时处理&#xff0c;并支持任务调度。 Celery 如果使用 RabbitMQ 作为消息系统的话&#xff0c;整个应用体系就是下…

GStreamer日志调试笔记

1、查询所有分类 #gst-launch-1.0 --gst-debug-help 2、查询videotestsrc的日志 #gst-launch-1.0 --gst-debug-help | findstr videotestsrc 结果&#xff1a; 3、使用--gst-debug设置相应日志类型的相应等级&#xff0c;越大显示日志越多&#xff0c;排查内存泄露可以设置为9 …

【iOS】多线程

文章目录 前言一、多线程的选择方案二、GCD和NSOperation的比较二、多线程相关概念任务队列 三、死锁情况主队列加同步任务 四、任务队列组合主队列异步并发队列异步 前言 这两天将iOS的多线程的使用都看了一遍&#xff0c;iOS的多线程方案有许多&#xff0c;本篇博客主要总结…

打开深度学习的锁:(0)什么是神经网络?

PS&#xff1a;每每温故必而知新 什么是神经网络&#xff1f; 一、一个单神经元的神经网络二、多个单神经元的神经网络三、到底什么是机器学习&#xff1f;&#xff08;重点&#xff09;1&#xff1a;什么是机器学习的训练&#xff1f;2&#xff1a;什么是模型&#xff1f;权重…

python数据分析所需要的语法基础

Python语言基础——语法基础 前言语法基础变量标识符数据类型输入与输出代码缩进与注释 总结 前言 对于学过C语言的人来说&#xff0c;python其实很简单。学过一种语言&#xff0c;学习另一种语言&#xff0c;很显然的能感觉到&#xff0c;语言大体上都是相通的。当然&#xf…

【docker】常用的把springboot打包为docker镜像的maven插件

Spring Boot Maven Plugin: Spring Boot 自带的 Maven 插件 (spring-boot-maven-plugin) 支持直接生成 Docker 镜像。通过配置&#xff0c;可以在 Maven 构建过程中自动构建 Docker 镜像&#xff0c;而无需单独编写 Dockerfile。这种方法简化了将应用打包为 Docker 镜像的过程。…

武汉理工大学python123实验——流程控制结构

1.百分制成绩转换五分制#1707 n int(input())if n>90:print(A) elif n>80:print(B) elif n>70:print(C) elif n>60:print(D) else:print(E) 2.角古猜想#73963 n eval(input()) if n<0:print(ERROR) elif . in str(n):print(ERROR) else:print(n,end" …

Qt扫盲-Qt D-Bus概述

Qt D-Bus概述 一、概述二、总线三、相关概念1. 消息2. 服务名称3. 对象的路径4. 接口5. 备忘单 四、调试五、使用Qt D-Bus 适配器1. 在 D-Bus 适配器中声明槽函数1. 异步槽2. 只输入槽3. 输入输出槽4. 自动回复5. 延迟回复 一、概述 D-Bus是一种进程间通信(IPC)和远程过程调用…

Java面试题:多线程2

如何停止正在运行的线程 1,使用退出标志,使线程正常退出(run方法中循环对退出标志进行判断) 2,使用stop()方法强行终止(不推荐) 3,调用interrupt()方法中断线程 打断阻塞线程(sleep,wait,join),线程会抛出InterruptedException异常 打断正常的线程,可以根据打断状态来标记…

继承知识及扩展(C++)

1. 继承是什么&#xff1f; 继承是面向对象编程的三大特征之一&#xff0c;也是代码复用的手段之一。之前我们在很多的地方尝试函数的复用&#xff0c;而继承是为了类的复用提供了很好的方式。 &#xff08;1&#xff09;继承的代码怎么写 在一个类后面使用 &#xff1a;继承方…

知识图谱融入RAG模型:LinkedIn重塑智能客服新范式【附LeCun哈佛演讲PPT】

原文&#xff1a;Retrieval-Augmented Generation with Knowledge Graphs for Customer Service Question Answering 一、研究背景与问题 在客服领域,快速准确地匹配用户问题与历史工单,是提供优质回答的关键。传统的检索增强生成(Retrieval-Augmented Generation, RAG)方法虽…

IDEA-控制台日志过滤插件 - Grep Console

IDEA-控制台日志过滤插件 - Grep Console 当idea控制台日志较多时&#xff0c;为了方便查找关键字&#xff0c;使用Grep Console插件&#xff0c;指定控制台中关键字高亮显示 1.安装 2.使用 2.1 高亮显示 控制台中指定颜色高亮显示指定字符 效果: 重启项目后还是会高亮显示 取…

【软考高项】三十三、质量管理

一、管理基础 质量定义 国际标准&#xff1a;反映实体满足主体明确和隐含需求的能力的特性总和。 国家标准&#xff1a;一组固有特性满足要求的程度。固有特性是指在某事或某物中本来就有的&#xff0c;尤其是那种永久的可区分的特征。 ➢ 对产品来说&#xff0c;例如…