【JavaEE】懒人的福音-MyBatis框架—复杂的操作-动态SQL

【JavaEE】MyBatis框架要点总结(3)

在这里插入图片描述

文章目录

  • 【JavaEE】MyBatis框架要点总结(3)
    • 1. 多表查询
      • 1.1 映射表resultMap
      • 1.2 只有部分属性跨表查询
        • 1.2.1 依照常规去写代码
        • 1.2.2 用标签去实现接口
      • 1.3 分多步的解决方案
      • 1.4 与多线程的结合
    • 2. 动态SQL
      • 2.1 if 标签
      • 2.2 test值
      • 2.3 trim标签
      • 2.4 where标签
      • 2.5 set标签
      • 2.6 foreach标签
        • 2.6.1 通过Integer数组批量删除
        • 2.6.2 通过UserInfo集合批量插入
        • 2.6.3 传入多个集合
    • 3. 最后的碎碎念 of MyBatis完结✿✿ヽ(°▽°)ノ✿

【JavaEE】MyBatis框架要点总结(3)

上一篇文章,我们学习了MyBatis框架对数据库的各种单表操作,想必已经对增删改查语法已经熟悉很多了

但是,我们学习的只是一些固定的功能,更复杂的业务要求还是不能满足:

  1. insert一个对象,如果这个对象有些属性是没有被赋值的,则插入的时候,values中不传值
    • 因为对象属性的默认值,并不一定是数据库表的字段的默认值
  2. 批量增删…
  3. 多表查询…
  4. 等等…

我们先从多表查询讲起~

1. 多表查询

有些时候,我们要的信息并非在同一张表中(其实很少,因为一般一个实体类就代表一张表)

  • 这个时候就需要联合查询了~

1.1 映射表resultMap

这种方法很麻烦,无非就是能手动加一些映射关系而实现功能,个人觉得比较暴力:

大概代码差不多长这样:

<resultMap id="BaseMap” type="com.example.demo .model.ArticleInfo".<id property="id” column="id"></id>
    <result property="title" column="title"></result>
    <result property="content" column="content"></result>
    <result property="createtime" column="createtime"></result>
    <result property="updatetime" column="updatetime"></result>
    <result property="uid" column="uid"></result>
    <result property="rcount" column="rcount"></result>
    <result property="state" column="state"></result>
    <association property="user" 
                 resultMap="com.example.demo.mapper.UserMapper.BaseMap" 
                 columnPrefix="u_"></association>
</resultMap>
<select id="getAll" resultMap="BaseMap">
    select a.*,u.username u username from articleinfo aleft join userinfo u on a.uid=u.id
</select>     
  • association标签,可实现一篇文章对应一个作者

  • 除此之外,还有collection标签去实现一个用户对应多篇文章

太麻烦了,可读性不高,基本不会有人会用的,所以我不演示了~

1.2 只有部分属性跨表查询

对于这种情况的话,就不需要,查询出另一张表的整个实体对象了~

例如一篇博客文章联合上作者的名字:

在这里插入图片描述

当然,如果你要携带一个对象也不是不行,把他的属性全部写一遍~

  • 特别不建议,这样很不美观
  • 并且只能一对一,不能一对多

其实一遍情况下,这样是够用的,因为我们在实际场合中,一对一都只需要另一张表的几个重要信息!

这种情况,则跟平常的写法一致:

  • 因为 “赋值规则” 是以 最终呈现的表的情况为准
    • 即, 只要通过联合查询方式出现的列,都能赋值给属性

创建对应的mapper接口和xml文件:

  • 低耦合高内聚,封装和隔离嘛

在这里插入图片描述

1.2.1 依照常规去写代码

在这里插入图片描述

<?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.demo.mapper.ArticleMapper">

    

</mapper>

测试:

在这里插入图片描述

效果:

在这里插入图片描述

原理就是:

在这里插入图片描述

  • 最终呈现的表的列是可以赋值的

1.2.2 用标签去实现接口

在这里插入图片描述

注解代替xml的原理:

  1. @Select代替select标签
    • 增删改查对应增删改查的注解
  2. 加在哪个方法上id就是啥,resultType就是其返回类型
  3. 注解内的字符串,就是原标签内部的sql代码

测试:

在这里插入图片描述

结果一致:

在这里插入图片描述

在这样的简单内部sql代码而言,这样写很方便,而在复杂的操作下,并不是很方便~

  • 例如,等一下要讲的动态sql代码
  • 弊端:引号限制,书写字符串禁锢思想…

1.3 分多步的解决方案

在这里插入图片描述

对于一对多(例如一个作者携带多篇文章)情况,我们一般采取, 分多步的解决方案(数据库没有集合类型)

假设要找的用户为id=1

  1. 在userinfo中去找id等于1的用户对象
  2. 在articleinfo中去找uid等于1的文章对象
  3. 合并结果

实现:

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


效果:

在这里插入图片描述

1.4 与多线程的结合

有时候面试官可能会问你,你的项目有没有结合多线程呢?

你可能不知道怎么回答,但是你可以说,多表查询的时候,可以用到线程池!

  • 两张表同时查后一起合并~
  • 没有线程安全问题,提高CPU利用率,提高代码效率

代码实现:

  • 线程池博客:【JavaEE】线程案例-定时器-线程池 and 工厂模式_s:103的博客-CSDN博客
  • 等待线程结束方法博客:【JavaEE】Callable接口(NO.6线程创建方法)-JUC的常见类-与线程安全有关集合类_s:103的博客-CSDN博客

获得线程池:

在这里插入图片描述

用计数员CountDownLatch去判断线程是否结束:

在这里插入图片描述

等待两个线程结束才继续后面的内容:

在这里插入图片描述

效果:

在这里插入图片描述

多表查询讲完后,就是MyBatis篇章的最后一个内容:动态SQL

2. 动态SQL

主要是因为,这是xml去实现接口的方法,并不像jdbc编程,我们可以用java做一些自定义的业务逻辑去构造sql字符串,到目前为止的功能,似乎都是我们写死的,但是如果要用jdbc结合java代码去写一些操作,也是麻烦的

例如:

在这里插入图片描述

我们并不能给枚举每个种情况,写那么多的方法!

然后通过笨方法去判断使用哪个方法!

因此MyBatis在xml是实现接口中加入了语法:动态SQL

  • 在标签中编写sql代码的杂合语法
  • 标签进行一些业务逻辑,再呈现出最终的SQL语句

千万别把这个过程看成写字符串,而是书写代码

即让方法实现有了逻辑的,是活的,是动态的SQL;又让方法实现更加简单,这就是框架的意义!


接下来讲解实现常见逻辑的便签:(等一下记得题一下,注解这样写不方便!还有引号不方便,开发不方便,写字符串的限制…)

2.1 if 标签

在这里插入图片描述

对于这个要求,其实在很多场合都会出现,例如填报信息中的*必选项非必选项

  • 这样导致最终提交的信息,属性的赋值情况参差不齐,啥情况都有

而if标签实现的逻辑,就可以很好的解决这个问题

在这里插入图片描述

补充:

  • state的值是0或者是1,而对象中没有被赋值是0,无法判断这个值是否是有效值
  • 所以state在定义时应该改为Integer类型
    • 可以看出,基本数据类型的包装类,只有在不得不写的时候才会用~

在这里插入图片描述

xml实现:

在这里插入图片描述

显然这段代码不能复制给之前注解实现的方法的括号里,因为写法不方便,并且有引号的限制

测试:

在这里插入图片描述

效果:

在这里插入图片描述

数据库:

在这里插入图片描述

在这里插入图片描述

数据库:

在这里插入图片描述

想必你能感受到一点,“动态”的感觉,动态SQL就是MyBatis的一个强大特性

2.2 test值

test值的内容就是,一段java代码的逻辑表达式,结果true或者是false

test值中的对象的变量名:

  1. 传入自定义对象的属性名(由于传入自定义对象,就必然是单参,所以就只是这个对象中的属性)
  2. 传入多个参数的参数名(默认/自己设置)

不需要#{}去包起来,就看成java代码,直接使用变量名代表变量!

  • 不规范写法就等着报错吧 (╬▔皿▔)凸

传入多个参数:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

效果:

在这里插入图片描述

数据库:

在这里插入图片描述

2.3 trim标签

其实,刚才的要求并没有,完成,还是有可能会出bug

  • 报错可以,但是报的错应该是必选项没有填,而不是sql语句错误

正确的报500:

在这里插入图片描述

  • 这个错是因为数据库的userinfo表,规定了username和password是不能为空的,也就是说, 必须传这两个值,否则就会这样报错,以此实现“必选项”的功能

错误的报500:

在这里插入图片描述

原因是:SQL语句变成了:

insert into userinfo(username, password,) values(#{username}, #{password},)

那两个逗号,导致sql语句不符合语法!

而trim标签的出现,就是为了避免这样以及类似的语法错误!

  • trim标签的 “修理功能”,可以有效解决,这些前缀后缀,分隔符的问题

trim标签的功能分为四个属性:

在这里插入图片描述

  1. prefix
    • 如果语块内进行一系列标签的逻辑操作动态变化后,最终不为空,增加前缀prefix
  2. suffix
    • 如果语块内进行一系列标签的逻辑操作动态变化后,最终不为空,增加后缀suffix
  3. prefixOverrides
    • 如果语块内进行一系列标签的逻辑操作动态变化后,前缀为prefixOverrides,则删除
  4. suffixOverrides
    • 如果语块内进行一系列标签的逻辑操作动态变化后,后缀为prefixOverrides,则删除

优化刚才的代码:

在这里插入图片描述

方法的实现:

在这里插入图片描述

测试:

在这里插入图片描述

效果:

在这里插入图片描述

  • 多余的后缀去掉了,并且括号加上了

数据库:

在这里插入图片描述

补充:可想而知,如果啥也不传,就是:

在这里插入图片描述

insert into userinfo values;

显然是语法错误的,但是也正常,因为啥也不传本来就不合理,啥也没有干哈子添加操作~

  • 即使一张表每个字段都有默认值,但是一个都不传,本身就是不合实际的!
  • 这个点不需要解决,就该报500

在sql语句后加一些空格、换行、tab等空白符,不会影响后缀的判断

  • 不演示…

2.4 where标签

其实trim的功能更加灵活,可以实现的功能很全面了,静待你的发挥

而where标签,则是trim中的一种特殊而且常见的情况,用于条件查询的where条件:

select * from userinfo where username = #{username} and password = #{password} and state = #{state};

在这里插入图片描述

  • 这个方法的功能是,查询所有跟传过来的userinfo已有属性值都相同的用户
    • 如果userinfo中属性都没被赋值,则就是全表查询
    • 被赋值的越少,条件越简单

xml实现:

在这里插入图片描述

但是,你也会很快意识到,这会出现 where and的情况出现!

测试:

在这里插入图片描述

效果:

在这里插入图片描述

错误效果:

在这里插入图片描述

where没去掉

在这里插入图片描述

出现了where and

所以就有了where标签:

  1. 如果语块最终非空,则默认在前面加where前缀
  2. 如果语块最终的前缀and或者or会去除
    • 没有涉及NOT
    • 只适合简单的删除前缀and/or,不涉及其他复杂的逻辑表达式
    • 其实sql本身逻辑表达式在实际情况里不会很复杂,最多就这样了!
    • 标签的功能是有限的,我们要遵守框架规则,才能吃到框架的红利!

在这里插入图片描述

  • 在前面就不要加where了,否则就会出现两个where的情况!

效果:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

where本质其实就是这样:

<trim prefix="where" prefixOverrides="and">
    <trim prefixOverrides="or">
        
    </trim>
</trim>

在这里插入图片描述

测试:

在这里插入图片描述

注意:

  • 删除and/or,只是前缀
  • 后缀不行!

在这里插入图片描述

效果:

在这里插入图片描述

2.5 set标签

跟where标签一样,也是trim标签的一种特殊的创建情况,主要是代替修改操作的set语句:

update username set state = 0, username = '尊嘟假嘟' where id = #{id};

同样的,里面的逗号,,可能会出现set ,的尴尬情况

所以set标签能解决这个问题:

  1. 语句非空,加前缀set
  2. 抹除后缀的逗号,

相当于这个trim标签:

<trim prefix="set" suffixOverrides=",">
    
</trim>

接口方法:

在这里插入图片描述

  • 要求:根据这个用户信息的id,将username password state属性更新到表里对应的用户

xml实现:

在这里插入图片描述

测试:

在这里插入图片描述

效果:

在这里插入图片描述

  • 用户名赋值的是'尊嘟假嘟'; 密码赋值的是'666'

在这里插入图片描述

数据库:

在这里插入图片描述

注意:前缀逗号不会被去掉的,并且前面别加set,否则会出现set set的情况,其他应用猜猜就能写了,交给你了…

2.6 foreach标签

顾名思义就是,遍历集合/数组的意思,这个标签常常用于批量增删的操作

  • 并且没有这个标签,是不能传入List<Object> 或者Object[],因为数据读不了~
  • 批量操作的出现概率也比较低,之前我们对于批量操作,是用for循环进行n次的数据库操作,而不是一次到位

foreach有以下属性:

  1. collection:绑定方法参数中的集合名
    • 可以是List,Map,Set,数组…
  2. item:遍历时的每一个对象
  3. open和close:语句非空时的前后缀
  4. separator:每次遍历的数据之间的分隔符
  5. index,循环变量,从0开始一次循环加一,不常用~

java代码的理解(伪代码):

String subSQL = "delete from userinfo where id in ";
subSQL += "(";
for(Object item : collection) {
    subSQL += #{item.property};
    //自动检测要不要添加分隔符separator
}
subSQL += ")";

2.6.1 通过Integer数组批量删除

在这里插入图片描述

xml实现:

在这里插入图片描述

  • 就是打算将Integer集合转化为(1,2,3)的这种形式跟in搭配!

测试:

在这里插入图片描述

在这里插入图片描述

效果:

在这里插入图片描述

在这里插入图片描述

数据库:

在这里插入图片描述

2.6.2 通过UserInfo集合批量插入

在这里插入图片描述

xml实现:

  • 我写的测试用例信息全面,重点突出foreach标签的功能,虽然可以和其他标签结合使用发挥更大的功能,所以我的写法并不全面,通用性不高~
    • 这里讲基础,更多想法和应用交给你咯😀😀😀
  • 但是在这里还是以讲解foreach功能为主!

在这里插入图片描述

测试:

在这里插入图片描述

准备测试用例:

在这里插入图片描述

注意添加不带参数的构造方法,不然Bean对象无法存储

在这里插入图片描述

  • 因为我们自己写的构造方法会顶替原来的构造方法

在这里插入图片描述

效果:

在这里插入图片描述

数据库:

在这里插入图片描述

2.6.3 传入多个集合

我猜测,主要是因为传入的集合的,有可能是Integer,String…的非自定义对象集合,我们有时候需要传入多个这样的不同类型的集合,原本的@Param显然不适用了~

  • 所以foreach标签提供的机制是 collection去连接集合,item规定对象名
  1. 非自定义类型集合中的一个的包装类元素,起了个名item,可以#{item}
    • (直接)跟元素(已是最小单元)建立对应
  2. 自定义类型集合中的一个对象元素,起了个名item,可以#{item.property}
    • (间接)跟元素的属性建立对应
  • 因此,我们反而可以传入两个自定义类型集合等多个集合,因为不会出现冲突

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

效果:

在这里插入图片描述

数据库:

在这里插入图片描述

3. 最后的碎碎念 of MyBatis完结✿✿ヽ(°▽°)ノ✿

在MyBatis的学习过后,想必你有很多想法,因为我讲的毕竟是常见写法,至于他们杂合起来是什么样的,这就是你可以发挥的了!

如果可以,可以去学习MyBatis Plus的语法!

实际后端需要的sql有关的逻辑,不会再复杂了,即使有,也应该在使用接口方法前进行简化,趋向于按照框架的规定进行操作,所以不要焦虑于用这些标签进行复杂逻辑操作!

其实后端程序操作数据库,都应该是简单且安全的sql语句,所以创建库创建表,删库删表等操作都不是程序来操作的,虽然jdbc能够实现这些操作,但是学了没用!

我们学会的就是技能,用这些技能,有了思想,要怎么实现功能,能实现什么功能,发挥你的头脑,去自由的应用吧,都能实现的了的!

你可能发现你的知识按照这个逻辑来实现某个功能是可行的,对,就这么去猜,然后去实践它!

我做不到把每个属性每个语法都讲,但是这些足以实现会遇到的问题了!

  • 即使会遇到不会的,就上网去学,因为更多巧妙的东西还可以进一步去学!
  • 主打个“有需要再学”

文章到此结束!谢谢观看
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭🦆

代码位置:mybatis_demo/src · 游离态/马拉圈2023年8月 - 码云 - 开源中国 (gitee.com)


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

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

相关文章

【springboot启动报错】java: 错误: 无效的源发行版:17

报错截图 解决方案 第一步&#xff1a;编辑配置&#xff0c;改为想用的jdk版本 第二步&#xff1a;文件--->项目结构&#xff0c;改为对应的SDK 第三步&#xff1a;文件--->设置--->构建、执行、部署--->编译器--->Java编译器&#xff0c;修改目标字节码版本 第…

c++中的多态

文章目录 1.多态的概念1.1概念 2.多态的定义及实现2.1多态的构成条件2.2虚函数2.3虚函数的重写2.4 C11 override 和 final2.5 重载、覆盖(重写)、隐藏(重定义)的对比 3. 抽象类3.1概念3.2接口继承和实现继承 4.多态的原理4.1虚函数表4.2多态原理分析4.3 动态绑定与静态绑定 5.单…

使用mybatis-plus的updateById方法更新一个numeric(1)类型字段,sql成功执行,但是updates为0,更新失败的解决办法

使用mybatis-plus的updateById方法更新一个numeric(1)类型字段&#xff0c;sql成功执行&#xff0c;但是updates为0&#xff0c;更新失败的解决办法&#xff1a; 背景&#xff1a;我有一张表&#xff0c;有个启用禁用功能&#xff0c;没有放在编辑页面一起编辑保存&#xff0c;…

Vue.js快速入门指南:零基础也能轻松上手,开启前端开发之旅!

目录 MVC设计模式与MVVM设计模式选项式API的编程风格与优势声明式渲染及响应式数据实现原理指令系统与事件方法及传参处理计算属性与侦听器区别与原理条件渲染与列表渲染及注意点class样式与style样式的三种形态表单处理与双向数据绑定原理生命周期钩子函数及原理分析 MVC设计模…

Vscode-工具使用

Vscode &#xff0c;这玩意儿是开源的&#xff0c;以前用收费的破解版&#xff0c;过段时间就高版本不匹配&#xff0c;这次搞个不要钱的玩玩&#xff0c;记录使用心得 下载 下载地址&#xff1a;官网 点击下载&#xff0c;但是这里有个问题下载比较慢&#xff0c;解决办法&a…

Linux零基础快速入门到精通

一、操作系统概述 二、初始Linux Linux的诞生 Linux内核 Linux发行版 小结 三、虚拟机 认识虚拟机 虚拟化软件及安装 VMware Workstation 17 Pro安装教程https://blog.csdn.net/weixin_62332711/article/details/128695978 远程连接Linux系统 小结 扩展-虚拟机快照 …

python_PyQt5运行股票研究python方法工具V1.0

写在前面&#xff1a; 1 在写研究方法过程中&#xff08;例如&#xff1a;股票研究&#xff09;&#xff0c;很多方法根据数据的更新需要重复运行获取新的结果&#xff0c;本工具就是固化这些需要重复运行的代码&#xff0c;可以直接在工具中运行得到更新的结果。 2 本文是V1…

Sharding-JDBC概述

前言 ​ 随着业务数据量的增加&#xff0c;原来所有的数据都是在一个数据库上的&#xff0c;网络IO及文件IO都集中在一个数据库上的&#xff0c;因此CPU、内存、文件IO、网络IO都可能会成为系统瓶颈。当业务系统的数据容量接近或超过单台服务器的容量、QPS/TPS接近或超过单个数…

自动方向识别式 LSF型电平转换芯片

大家好&#xff0c;这里是大话硬件。 今天这篇文章想分享一下电平转换芯片相关的内容。 其实在之前的文章分享过一篇关于电平转换芯片的相关内容&#xff0c;具体可以看链接《高速电路逻辑电平转换设计》。当时这篇文章也是分析的电平转换芯片&#xff0c;不过那时候更多的是…

打造企业或者个人IP引流法

打造企业或者个人IP引流法. 大家好&#xff0c;我是百收网SEO编辑&#xff1a;狂潮老师&#xff0c;今天给大家分享企业IP打造的方法 首先我们想让人知道你的企业叫什么&#xff0c;怎么找到你的企业 这个时候我们就需要去各大平台发布信息&#xff0c;客户想了解直接去搜索…

Unity2D RPG开发笔记 P1 - Unity界面基础操作和知识

文章目录 工具选择简单快捷键Game 窗口分辨率检视器Transform 组件Sprite Renderer综合检视器 工具选择 按下 QWERTY 可以选择不同的工具进行 旋转、定位、缩放 简单快捷键 按下 Ctrl D 可以复制物体 Game 窗口分辨率 16:9 为最常见的分辨率 检视器 Transform 组件 物体在…

Vue3 引用第三方Swiper内容触摸滑动简单应用

去官网查看更多教程→&#xff1a;Swiper官网 → 点击教程在vue中使用Swiper→ 在Vue中使用Swiper cd 到项目 安装Swiper&#xff1a; cnpm install --save swiper 安装指定版本 cnpm install --save swiper8.1.6 9.4.1 10.1.0…

了解 Langchain️是个啥?:第 1 部分

一、说明 在日常生活中&#xff0c;我们主要致力于构建端到端的应用程序。我们可以使用许多自动 ML 平台和 CI/CD 管道来自动化 ml 管道。我们还有像Roboflow和Andrew N.G.的登陆AI这样的工具来自动化或创建端到端的计算机视觉应用程序。 如果我们想在OpenAI或拥抱脸的帮助下创…

[C++] 模板template

讲模板之前呢&#xff0c;我们先来谈谈泛型编程&#xff1a; 泛型编程&#xff1a;编写与类型无关的通用代码&#xff0c;是代码复用的一种手段。模板是泛型编程的基础。 模板分为两类&#xff1a;函数模板与类模板 1、函数模板 1.1 函数模板概念 函数模板代表了一个函数家…

在pycharm中对使用脚本文件运行的程序进行调试

在github中下载的许多项目都可以使用给出的脚本文件运行&#xff0c;本文介绍如果在pycharm中对使用脚本文件运行的程序进行调试的方法。 1.点击 edit configurations 2.选择要debug的py文件&#xff0c;并且填写参数 3.点击运行旁边的debug按钮

尚硅谷大数据项目《在线教育之离线数仓》笔记001

视频地址&#xff1a;尚硅谷大数据项目《在线教育之离线数仓》_哔哩哔哩_bilibili 目录 P003 P004【数仓概念讲的颇为详细】 P018 P019 P020 P021 P022 P023 P024 P003 时间切片&#xff1a;时间回溯&#xff0c;找回以前的数据。 P004【数仓概念讲的颇为详细】 核心架…

前端开发实习总结参考范文(合集)

▼前端开发实习总结篇一 今天就简单聊聊上面的StrutsSpringHibernate吧。 Struts 代表&#xff1a;表示层;Spring代表&#xff1a;业务逻辑层;Hibernate则代表持久层。他们是目前在Java Web编程开发中用得最多的框架&#xff0c;其实这样区分是为了适应软件开发过程中各个分工…

Android 实现 RecyclerView下拉刷新,SwipeRefreshLayout上拉加载

上拉、下拉的效果图如下&#xff1a; 使用步骤 1、在清单文件中添加依赖 implementation ‘com.android.support:recyclerview-v7:27.1.1’ implementation “androidx.swiperefreshlayout:swiperefreshlayout:1.0.0” 2、main布局 <LinearLayout xmlns:android"http…

HTML详解连载(4)

HTML详解连载&#xff08;4&#xff09; 专栏链接 [link](http://t.csdn.cn/xF0H3)下面进行专栏介绍 开始喽CSS定义书写位置示例注意 CSS引入方式内部样式表&#xff1a;学习使用 外部演示表&#xff1a;开发使用代码示例行内样式代码示例 选择器作用基础选择器标签选择器举例特…

日常BUG——SpringBoot关于父子工程依赖问题

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;日常BUG、BUG、问题分析☀️每日 一言 &#xff1a;存在错误说明你在进步&#xff01; 一、问题描述 在父子工程A和B中。A依赖于B&#xff0c;但是A中却无法引入B中的依赖&#xff0c;具体出现的…