MyBatis 环境搭建+基本使用

news/2024/11/14 14:51:09/

目录

  • MyBatis
    • 创建MyBatis环境搭建
    • MyBatis模式开发
    • MyBatis 获取动态参数(查询操作)
      • ${} 直接替换
      • #{} 占位符模式替换
      • like查询(模糊查询)
      • 多表查询
        • 一对一的表映射
        • 一对多的表映射
    • 增、删、改操作
      • 改操作
      • 删除操作
      • 增加操作
        • 添加用户
        • 添加用户并获取用户id
    • 返回类型与返回字典映射
      • 返回类型 resultType
      • 返回字典映射 resultMap
    • 动态SQL
      • \<if\>标签
      • \<trim\>标签
      • \<where\>标签
      • \<set\>标签
      • \<foreach\>标签

MyBatis是优秀的持久层框架,支持自定义SQL,存储过程以及高级映射。
MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
使用MyBatis是更简单完成程序和数据库交互的工具,可以更简单的操作和读取数据库工具。

MyBatis官网

MyBatis

MyBatis是基于JDBC的,在JDBC上又封装了一层

创建MyBatis环境搭建

和maven项目不同的两步:

  1. 添加MyBatis框架支持 (老项目 / 新项目)
  2. 设置MyBatis的配置信息
    • 设置数据库链接的相关信息
    • 配置 MyBatis xml 的保存路径和 xml 命名模式
# 数据库的连接字符串设置
spring.datasource.url=jdbc:mysql://localhost:3306/mycnblog?characterEncoding=utf8&useSSL=false
spring.datasource.username=root
spring.datasource.password=111
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver# 设置MyBatis
mybatis.mapper-locations=classpath:/mybatis/*Mapper.xml

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

添加MyBatis框架支持
在这里插入图片描述
注意:第一次创建好了MyBatis项目之后,启动会报错。
在这里插入图片描述
需要在application.properties下设置数据库的连接字符串设置和 MyBatis 的 XML ⽂件配置。
在这里插入图片描述

# 数据库的连接字符串设置
spring.datasource.url=jdbc:mysql://localhost:3306/mycnblog?characterEncoding=utf8&useSSL=false
spring.datasource.username=root
spring.datasource.password=111
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver# 设置MyBatis
mybatis.mapper-locations=classpath:/mybatis/*Mapper.xml

MyBatis模式开发

MyBatis模式开发由两部分组成

  1. interface :让其他层可以注入使用的接口
  2. MyBatis xml:具体实现sql【他是上面interface的实现】
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

MyBatis 获取动态参数(查询操作)

${} 直接替换

MyBatis 获取动态参数有两种实现:

  1. ${paramName} 直接替换
    <select id="getUserById" resultType="com.example.demo.entity.UserEntity">select * from userinfo where id=${uid}
<!--    如果param和形参中的值不一样,需要使用@Param中的参数    --></select>

在这里插入图片描述

#{} 占位符模式替换

  1. #{paramName} 占位符模式
    是一种预执行,可以有效的排除SQL的安全问题
    <select id="getUserById" resultType="com.example.demo.entity.UserEntity">select * from userinfo where id=#{uid}</select>

在这里插入图片描述

    @Testvoid login() {String username = "admin";String password = "' or 1='1";UserEntity inputUser = new UserEntity();inputUser.setUsername(username);inputUser.setPassword(password);UserEntity user = userMapper.login(inputUser);System.out.println(user);}
    <select id="login" resultType="com.example.demo.entity.UserEntity">select * from userinfo where username='${username}' and password='${password}'</select>

没有输入密码,但是可以构造,得到用户数据
在这里插入图片描述
$:直接替换
只要or前后有一个条件满足即可

select * from userinfo where username='${username}' and password='' or 1='1'

#是预执行处理,填充的东西只看做一个字符串,不会查到用户数据

    <select id="login" resultType="com.example.demo.entity.UserEntity">select * from userinfo where username=#{username} and password=#{password}</select>

在这里插入图片描述

$:直接替换,当需要传递一个SQL关键字的时候比较适合使用
比如需要对数据进行倒序或者正序排序时

//UserMapper.javaList<UserEntity> getAllByIdOrder(@Param("ord") String ord);
//UserMapper.xml<select id="getAllByIdOrder" resultType="com.example.demo.entity.UserEntity">select * from userinfo order by id ${ord}</select>
//UserMapperTest@Testvoid getAllByIdOrder() {List<UserEntity> list = userMapper.getAllByIdOrder("desc");System.out.println(list.size());}

like查询(模糊查询)

    //根据用户名模糊查询List<UserEntity> getListByName(@Param("username") String username);
    <select id="getListByName" resultType="com.example.demo.entity.UserEntity">select * from userinfo where username like concat('%', #{username},'%')</select>
    @Testvoid getListByName() {String username = "oo";List<UserEntity> list = userMapper.getListByName(username);list.stream().forEach(System.out::println);}

多表查询

一对一的表映射

(企业中几乎不用)

一对多的表映射

增、删、改操作

改操作

修改密码

//UserMapper.java//修改密码int updatePassword(@Param("id")Integer id,@Param("password") String password,@Param("newPassword") String newPassword);
<!--  UserMapper.xml  -->
<!--  select 要求必须设置两个属性,update设置一个参数就行,update默认会返回一个受影响的行数,返回类型默认是int  --><update id="updatePassword">update userinfo set password=#{newPassword}where id=#{id} and password=#{password}</update>

在UserMapper.java下右键生成updatePassword的Test

//UserMapperTest.java@Transactional  //事务(执行前新建事务,执行完进行回滚) 该注解让操作不污染数据库,可以加在类上,也可以加在方法上。@Testvoid updatePassword() {int result = userMapper.updatePassword(1, "123456", "aaaaa");System.out.println("修改:" + result);}

删除操作

//UserMapper.java//删除用户int delById(@Param("id") Integer id);
<!--  UserMapper.xml  -->
<!--  删除  --><delete id="delById">delete from userinfo where id=#{id}</delete>
//UserMapperTest.java@Transactional@Testvoid delById() {int id = 1;int result = userMapper.delById(id);System.out.println("删除结果:" + result);}

增加操作

添加用户

//UserMapper.java//添加操作int addUser(UserEntity user);
<!--  UserMapper.xml  -->
<!--  添加  返回影响行数--><insert id="addUser">insert into userinfo(username, password) values(#{username}, #{password})</insert>
//UserMapperTest.java@Testvoid addUser() {UserEntity user = new UserEntity();user.setUsername("root");user.setPassword("123456");int result = userMapper.addUser(user);System.out.println("添加用户" + result);}

添加用户并获取用户id

//UserMapper.javaint addUserGetId(UserEntity user);
<!--  UserMapper.xml  -->
<!--  数据库中要给id设置自增主键,不然这些会报错  -->
<!--  useGeneratedKeys="true"  表示是否自动生成id(主键) 默认为false  -->
<!--  开启自动生成主键后,keyProperty表示将生成的主键赋值给哪个属性字段上,放在id字段  -->
<!--    添加 返回影响行数 和 id--><insert id="addUserGetId" useGeneratedKeys="true" keyProperty="id">insert into userinfo(username, password) values(#{username}, #{password})</insert>
//UserMapperTest.java@Testvoid addUserGetId() {UserEntity user = new UserEntity();user.setUsername("root");user.setPassword("123456");int result = userMapper.addUserGetId(user);System.out.println("添加结果:" + result);System.out.println("ID:" + user.getId());}

返回类型与返回字典映射

返回类型 resultType

大多数的场景都可以使用resultType进行返回。使用方便,直接定义实体类即可

返回字典映射 resultMap

resultMap的使用场景

  • 字段名称和程序中的属性名不同,使用resultMap配置映射
  • 一对一和一对多关系可以使用resultMap映射并查询数据

动态SQL

动态SQL是MyBatis的强大特性之一,能够描述不同条件下不同SQL的拼接。允许在XML中写逻辑判断
保证了数据的一致性

<if>标签

有时候有必填字段和⾮必填字段,如果在添加的时候有不确定的字段传⼊,需要使用动态标签 <if> 判断

    int addUser2(UserEntity user);
    <insert id="addUser2">insert into userinfo(username, password<if test="photo != null and photo !=''">      <!--   这里test里面判断的key是属性,不是数据库字段  -->,photo       <!--  数据库字段  --></if>) values(#{username}, #{pwd}<if test="photo != null and photo !=''">,#{photo}     <!--  这里是属性,不是数据库字段 (特殊字符 #{} 等,里面的都属于程序里面的)  --></if>)</insert>
    @Transactional@Testvoid addUser2() {String username = "ss";String password = "1008611";String photo = "this is a photo";UserEntity user = new UserEntity();user.setUsername(username);user.setPwd(password);user.setPhoto(photo);int result = userMapper.addUser2(user);System.out.println("添加:" + result);}

<trim>标签

如果所有的字段都是非必填的情况下,只使用if标签就无法解决问题了。
就要使用<trim>标签结合<if>标签,对多个字段都采取动态生成的方式。

<trim>标签属性:

  • prefix:整个语句块,以prefix的值为前缀
  • suffix:整个语句块,以suffix的值作为后缀
  • prefixOverrides:表示整个语句块要去除的前缀,有则去除,没有也不会报错
  • suffixOverrides:表示整个语句块要去除的后缀

<trim>标签的处理方法:

  • 基于prefix配置,在开始部分加上 (
  • 基于suffix配置,在结束部分加 )
  • 在多个 <if> 组织的语句后都以 , 结尾,在最后拼接好的字符串还会以 , 结尾,会基于suffixOverrides配置去掉最后一个 ,
  • <if test="createTime!=null">中的 createTime 是传入对象的属性

使用 trim 什么都不传的话会报错

select * from articleinfo
where
<trim suffixOverrides="and"><if test="id != null and id > 0">id=#{id} and</if><if test="title != null and title != ''">title like concat('%', #{title},'%')</if>
</trim>

当MyBatis中多个都是非必传参数的解决方案
① 1=1


<!--除非在最前面加上 1=1 -->
<!--   这样是可行的    -->
select * from articleinfo
where 1=1
<trim prefixOverrides="and"><if test="id != null and id > 0">and id=#{id}</if><if test="title != null and title != ''">and title like concat('%', #{title},'%')</if>
</trim>

② 在trim中使用where作为前缀和and作为整个语句块要去除的后缀
当trim中生成了代码,才会添加<trim>中的前缀和后缀,如果trim中没有生成代码,前缀和后缀都会省略

<select id="getListByIdOrTitle" resultType="com.example.demo.entity.VO.ArticleInfoVO">select * from articleinfo<trim prefix="where" suffixOverrides="and"><if test="id != null and id > 0">id=#{id} and</if><if test="title != null and title != ''">title like concat('%', #{title},'%')</if></trim>
</select>

③ where标签

<where>标签

where标签是专门用来解决多个都是非必传参数的。

<where>会自动帮你取出最前面的 and 关键字,但要注意,使用where标签不会自动帮你去除最后的and标签。
where 会自动检测 <where>内是否有数据传入,如果没有就不会生成where语句

select * from articleinfo
<where><if test="id != null and id > 0">id=#{id}</if><if test="title != null and title != ''">and title like concat('%', #{title},'%')</if>
</where>

<set>标签

<set>会自动取出最后面的关键字。

<update id="updateById" parameterType="org.example.model.User">update user<set><if test="username != null">username=#{username},</if><if test="password != null">password=#{password},</if><if test="sex != null">sex=#{sex},</if></set>where id=#{id}
</update>

<foreach>标签

对集合进行遍历
常用属性:

  • collection:传递过来的集合的名称,List,set,map或数组
  • item:集合中遍历的每一个对象
  • open:语句块开头的字符串
  • close:语句块结束的字符串
  • separator:每次遍历之间间隔的分隔符

使用foreach 标签最常见的使用:批量删除


http://www.ppmy.cn/news/110752.html

相关文章

面向Java开发者的ChatGPT提示词工程(5)

GPT 的局限性 在探讨开发大型语言模型应用程序时&#xff0c;我们必须认识到 GPT 存在一些局限性。这些限制对于我们保持清醒的头脑至关重要。 尽管在 GP T的训练过程中融入了大量知识&#xff0c;但它并非能够完美地记住所见之物&#xff0c;并且对这些知识的边界了解有限。…

dxf文件解析,g代码解析,图片解析C#工程文件 可用于激光切割机,打印机,打码机,巡边机,点胶机等运动控制系统

dxf文件解析&#xff0c;g代码解析&#xff0c;图片解析C#工程文件 1.解析完成的图形坐标自动保存&#xff0c;通过通信接口直接下发即可 2.可用于激光切割机&#xff0c;打印机&#xff0c;打码机&#xff0c;巡边机&#xff0c;点胶机等运动控制系统 ID:48300065905135565…

在你可以执行与打印机有关的任务(例如页面设置或打印一个文档)之前,你必须已经安装打印机。你想现在安装打印机吗?

Powerdesigner 创建、打开工程提示"打印错误" 在你可以执行与打印机有关的任务(例如页面设晋或打印一个文档)之前&#xff0c;你必须已经安装打印机。你想现在安装打印机吗? 只需要将Print Spooler 服务启动即可。 服务启动步骤 1、Windows10 左下角搜索按钮点击输…

配置:以爱普生TM-T81热敏打印机为例:小票打印驱动安装配置

一、爱普生官网驱动下载 1、官网网址&#xff1a;https://www.epson.com.cn/ 2、热敏打印机型号&#xff1a;TM-T81 热敏票据打印机 3、驱动下载与安装&#xff1a; 二、系统打印机设置 1、驱动选择&#xff1a; 2、设置打印机默认份数&#xff1a;2份&#xff1a;目前没起…

3d打印(3):购买3d打印机,组装打印

本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/49643521 未经博主允许不得转载。 博主地址是&#xff1a;http://blog.csdn.net/freewebsys 1&#xff0c;关于3d打印机 现在在国内外非常流行的机器。直接降3d设计打印成模型。 创客利器。作为工程师必…

国民MCU 微型打印机解决方案

概述 微型打印机应用非常广泛&#xff0c;涉及超市、金融票据、商店、互联餐饮、互联物流、快递等行业&#xff0c;结合 市场微打印机的销售情况以及未来爆发增长趋势。鉴此产品体系将基于 N32G020 系列中 K6/7/8 型号 MCU 芯片实现高性价比的热敏型微型打印机解决方案(简称微…

打印机不打印故障简单排除方法

日常工作中经常会遇到打印机不能打印的情况&#xff0c;那么又没有专业的技术人员在场帮忙的情况下我们也可以自己动手简单的处理一下故障&#xff0c;可以尝试以下的方法进行简单的故障排除&#xff1b; 一、使打印机处于联机状态&#xff0c;如果打印机没有处于联机状态&…

关于打印机

1、打印机的作用与种类&#xff1a; 1、1 作用&#xff1a;它是计算机的外部输出设备之一&#xff0c;可以将计算机中经过编辑和校对后的文件、数据、图片、信息等以黑色或彩色打印到各种载体&#xff08;纸张、胶片、塑料薄膜等&#xff09;上&#xff0c;以供保存和交流。 1、…