当前位置: 首页 > news >正文

基于Spring原生框架构建原生Spring的第一个程序!

😉😉 学习交流群:

✅✅1:这是孙哥suns给大家的福利!

✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料

🥭🥭3:QQ群:583783824   📚📚  工作微信:BigTreeJava 拉你进微信群,免费领取!

🍎🍎4:本文章内容出自上述:Spring应用课程!💞💞

💞💞5:以上内容,进群免费领取呦~ 💞💞💞💞

第一个Spring应用程序目录

一:第一个Spring程序

1:Spring依赖 

2:Spring核心配置文件

(一):Spring配置文件的要求

(二):Spring核心API

二:程序开发

1:Spring核心配置文件

2:Java代码

3:实现思路

4:补充说明

三:细节分析

1:什么叫做Bean或者组件

2:Spring工厂提供的一些方法

3:Bean标签的特殊写法

四:Spring工厂实现问答


一:第一个Spring程序

1:Spring依赖 

        当前我们都是基于maven进行jar包的管理,我们只需要引入相应的坐标就可以了。maven会自动为我们下载我们所以来的jar包和依赖的依赖进行下载下来,单纯的使用一个Spring的IOC的话,spring-context就够用了,我们使用的版本是spring-context 5.1.4release版本。

        一个spring-context一个junit单元测试,对于我们编写第一个Spring程序就够了!

        <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.4.RELEASE</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version></dependency>

2:Spring核心配置文件

(一):Spring配置文件的要求

        任何一个框架都需要进行配置文件,Spring框架的配置文件,不要求具体的放置位置,在项目中都可以,也没有具体的配置名称。但是ApplicationContext.xml是Spring官方推荐的配置名称, 日后应用Spring框架时需要进行配置文件路径的配置,需要告诉Spring我们的配置文件的位置在哪里,在创建对象的时候有体现。

在Spring核心配置文件的根标签是一个Beans标签,在里边引入了Spring的一个默认的Schema【书写提示】,方便进行获取标签中的xml语法书写提示

(二):Spring核心API

        ApplicationContext是Spring的核心Api就是指的spring的核心类,这是一个框架最核心的类。这是一个接口。Spring当中最为核心的API就是提出的那个工厂ApplicationContext.java工厂主要作用是对象的创建,他的好处就是解耦合。

        为什么spring进行设计的时候会把核心Api设计成接口:

        Spring设计工厂的时候会设计成接口,接口的最主要的目的是为了屏蔽实现的差异,提供规范性作者考虑到这个工厂会应用到不同的开发环境(例如web与非web),为了屏蔽具体工厂类型之间的差异,Spring将工厂API设计成了接口,可以屏蔽具体工厂之间的差异,提供规范性。

        Spring当中提供的常用的两种工厂类型:
        1:非web环境:ClassPathXmlApplicationContext (main junit)
        2:web环境: XmlWebApplicationContext

        补充说明:
        1:以上是Spring中主要提供了两种类型的工厂
        2:对于web环境,我们很熟悉,非web英勇主要指的是我们的,main函数和Junit单元测试,在main函数和Junit单元测试里边是不启动服务器的,在main函数和Junit当中和在web当中用到的工厂类是不一样的
        3:查看继承关系,idea快捷键是ctrl+h,如果查看继承关系图当中没有这个类的话,是因为没有导入相关的web依赖。添加依赖的快捷键是<dep

        为什么ApplicationContext是一个重量级资源
        1:ApplicationContext工厂的对象会占用大量内存资源。
        2:ApplicationContext工厂对象不会频繁的创建,一个应用只会有一个工厂对象。
        3:ApplicationContext工厂一定是线程安全的。


        重量级资源都具有以下三种特性:
        1:区分一个资源或者对象的轻重量级的区别在于在内存中占用资源的多少,如果一个对象占用内存比较小,就是一个轻量级资源,重量级资源就是会占用大量内存
        2:我们在这值得工厂是他的具体的实现类,主要指的是那两种的实现类,我们不会频繁的创建这两个的对象,一个应用只会创建一个工厂对象
        3:在一个项目中只有一个这个对象,在一个项目中只会有一个这个对象实例,大家都会访问,那么就会产生比并发访问问题,但凡是这种重量级资源可以被多线程多用户访问,说明他们一定是线程安全的,一定做了锁的设置,它是线程安全的,可以被多线程并发访问

二:程序开发

1:Spring核心配置文件

    <!--id属性:起个名字,要求:唯一--><!--class属性:写全限定类名--><bean id = "person" class = "com.pactera.spring.Person"/>

2:Java代码

        //获取spring的工厂对象,这里我们在单元测试当中指定的是非web工厂。ApplicationContext clx = new ClassPathXmlApplicationContext("/applicationContext.xml");//getBean返回的是Object对象。Person person = (Person)clx.getBean("person");//这里边传入的是id值。System.out.println(person.getClass());


3:实现思路

        1:创建Bean的类文件。
        2:在ApplicationContext.xml文件中配置该对象属性;
        3:使用spring原生工厂类获取对象;

4:补充说明

        Spring最大的特点就是为我们提供了工厂对象,而这个工厂创建对象起到了一个很好的解耦合的作用,Spring提供的工厂和我们写的工厂本质上是没有区别的,都是创建对象解耦合,对于Spring工厂和通用工厂模式是没有本质区别的

        如果在Junit当中进行测试的话,应该使用ClassPathXmlApplicationContext这个类

三:细节分析

1:什么叫做Bean或者组件

        Spring工厂为我们创建对象,由spring为我们创建的对象叫做bean或者组件(Component)这些指的都是spring工厂为我们创建的对象

2:Spring工厂提供的一些方法

        这些都是Spring工厂为我们提供的获取Bean的方法!

ApplicationContext clx = new ClassPathXmlApplicationContext("/applicationContext.xml");
Person person = (Person)clx.getBean("person");
Person person = clx.getBean("person", Person.class);
Person person1 = clx.getBean(Person.class);
package com.pactera.spring;import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestSpring {/*** 研究目的:用于测试第一个spring的程序。* */@Testpublic void test03(){//获取spring的工厂对象,这里我们在单元测试当中指定的是非web工厂。ApplicationContext clx = new ClassPathXmlApplicationContext("/applicationContext.xml");Person person = (Person)clx.getBean("person");//这里边传入的是id值。System.out.println(person.getClass());}/*** 用于测试Spring工厂为我们提供的其他的方法。* 研究目的:Spring工厂对象核心方法getBean方法的重载。* */@Testpublic void test04(){ApplicationContext clx = new ClassPathXmlApplicationContext("/applicationContext.xml");//这个重载的getBean的方法的好处在于不用进行强制类型转换了。Person person = clx.getBean("person", Person.class);System.out.println("person="+person);//person=com.pactera.spring.Person@2a4fb17bSystem.out.println("person="+person.getClass());//person=class com.pactera.spring.Person//这个重载的getBean的方法的好处在于不用进行强制类型转换了。//如果是这种方式://<bean id = "person" class = "com.pactera.spring.Person"/>//<bean id = "person1" class = "com.pactera.spring.Person"/>//使用getBean(Person.class)会抛出异常,因为无法保证一个唯一性。//使用这个方法的时候必须保证spring配置文件中标签的唯一性。//Person person1 = clx.getBean(Person.class);//expected single matching bean but found 2/*** 在上边创建了一次Person的对象,将这个对象储存了起来,如果下边使用的话直接拿给我们* spring当中的当前这个对象只创建了一次,默认是单例设计模式。* *///System.out.println("person1="+person1);//person1=com.pactera.spring.Person@2a4fb17b//获取spring核心配置文件当中所有的id值;//---bean的定义:就是在spring核心配置文件当中的bean标签就叫做bean的定义//---bean定义的名字就是获取的是:id的值,返回的是是一个名字的数组。String[] beanDefinitionNames = clx.getBeanDefinitionNames();for (String beanDefinitionName : beanDefinitionNames) {System.out.println("beanDefinitionName="+beanDefinitionName);}//根据类型获取spring配置文件当中的所有的id值//---获取工厂类型当中所有Person类的值。获取的都是idString[] beanNamesForType = clx.getBeanNamesForType(Person.class);for (String id : beanNamesForType) {System.out.println("id="+id);}//判断spring工厂中是否存在这个bean,参数传入的是id值;boolean b = clx.containsBeanDefinition("a");System.out.println("b="+b);//判断spring工厂中是否存在指定id的beanSystem.out.println(clx.containsBean("person"));//目前角度来讲这两个方法是没啥区别的。}/*** 研究目的:在spring核心配置文件中的bean标签当中值配置class,spring可以不可以创建对象。*        :可以*        :spring会不会为他默认分配一个id值呢?*        :会,默认是 全限定名+#+num,这个id是spring按照一定的算法生成的。这个num是因为在*          配置文件当中可能默认不止配置一次。* 应用场景:如果这个bean只使用一次,那么就可以省略id值,如果这个bean会被使用多次,或者被其他bean*          就需要进行设置。* 研究目的2:name属性在spring配置文件中的使用*         :为bean对象定义别名,小名。id是大名,是唯一标识,name属性定义的内容是别名,是小名,*           spring当中通过大名和小名都是找到这个bean对象的,可以获取到这个bean对象。* */@Testpublic void test05(){ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");Person person = ctx.getBean(Person.class);System.out.println("person="+person);//person=com.pactera.spring.Person@128d2484String[] beanDefinitionNames = ctx.getBeanDefinitionNames();for (String beanDefinitionName : beanDefinitionNames) {System.out.println("beanDefinitionName="+beanDefinitionName);//beanDefinitionName=com.pactera.spring.Person#0}}/***研究目的2:name属性在spring配置文件中的使用*        :为bean对象定义别名,小名。id是大名,是唯一标识,name属性定义的内容是别名,是小名,*          spring当中通过大名和小名都是找到这个bean对象的,可以获取到这个bean对象。*应用场景:id和name有共性,他们相同的地方在于都能使用获取对象,相同的地方在于<bean id,class/>等效与* <bean name,class/>都可以定义一个对象。*       :区别在于别名可以定义多个,别名之间用,间隔就可以了使用任何一个别名都可以找到这个。,id只能定义一个,*         applicationContext.xml(xml语法导致的区别)这个文件当中id属性值命名的时候必须以字母开头,后面可以根字母、数字、下划线、连字符。*         name属性定义的时候比较灵活没有要求,可以明明在特殊场景下,比方说\的使用*         到了今天xml里的id属性的限制已经不存在了,已经没有这个约束了。*        :区别当中的类的 containsBeanDefinition()和containsBean;**  */@Testpublic void test06(){ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");Person person = (Person)ctx.getBean("p");System.out.println("person="+person);//person=com.pactera.spring.Person@2a4fb17bPerson person1 = (Person)ctx.getBean("p",Person.class);System.out.println("person1="+person1);//person=com.pactera.spring.Person@2a4fb17bboolean p1 = ctx.containsBean("p1");//既能判断id也能判断name属性。System.out.println(p1);//trueboolean p11 = ctx.containsBeanDefinition("p1");//只能判断id,不能判断name值。System.out.println(p11);//false}
}


3:Bean标签的特殊写法

1.只配置class属性不配置id属性
<bean class =  "..."/>

        这样是可以的,spring会默认分配一个默认的id值,格式一般是全限定类名+特殊符号+num


四:Spring工厂实现问答

        为什么我们应用了Spring工厂实现类,写了类搞了配置之后,就可以通过工厂创建对象呢?

        当我们定义好类,在applicationContext.xml配置文件中配置好Bean标签之后,创建工厂对象就可以获取相应的配置文件中的对象配置,Spring在Junit或者main方法的程序入口执行之后,创建工厂类对象的时候,Spring会读取applicationContext.xml配置文件,读取之后获取每个bean标签的id和class,根据class采用反射的方式获取对象,并将引用地址赋值给id属性,随后可以通过Spring工厂对象中重载的getBean的方法进行获取对应的对象引用

        反射创建对象调用不调用这个类的构造方法呢?

        一定会的,默认调用的是无参的构造方法。验证方法:在无参构造方法内部加入一个打印语句就可以了。虽然反射创建了对象,但是反射创建对象其实等效于new创建对象,底层也会调用new来创建对象。反射的底层调用的这个对象的无参构造方法

        如果一个类的构造方法是私有的怎么办呢?

        private修饰的内容只可以在本类中进行使用,如果构造器是private的,spring也能够创建对象,实际上底层通过反射调用私有的属性或者方法的,在反射中私有的内容也可以通过暴力反射的方式进行获取

        在开发过程中,是不是所有的对象都会交由spring进行创建?

        理论上来讲是这样的,但是有特例:实体对象(entity)这个对象中的属性是和数据库进行一一对应的,他的对象往往用于封装数据库中的数据,所以一般实体类对象都是交由Mybatis、hibernate等持久层框架进行创建。

😉😉 学习交流群:

✅✅1:这是孙哥suns给大家的福利!

✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料

🥭🥭3:QQ群:583783824   📚📚  工作微信:BigTreeJava 拉你进微信群,免费领取!

🍎🍎4:本文章内容出自上述:Spring应用课程!💞💞

💞💞5:以上内容,进群免费领取呦~ 💞💞💞💞

相关文章:

基于Spring原生框架构建原生Spring的第一个程序!

&#x1f609;&#x1f609; 学习交流群&#xff1a; ✅✅1&#xff1a;这是孙哥suns给大家的福利&#xff01; ✨✨2&#xff1a;我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 &#x1f96d;&#x1f96d;3&#xff1a;QQ群&#xff1a;583783…...

[个人笔记] Git的CLI笔录

Git - CLI笔录 Git的CLI笔录 Git - CLI笔录Git的CLI笔录 Git的CLI笔录 origin: 表示远程仓库节点名称。 当有多个远程仓库时 可新增远程仓库节点名称如 new_origin | new_remote origin/HEAD: 表示当前Git仓库默认分支的引用&#xff0c;通常指向origin/master或origin/main g…...

如何运行C/C++程序

一、在线运行C/C 码曰 - 让代码在云端多飞一会&#xff1a;这是一个支持C/C&#xff0c;Java&#xff0c;Python等多种语言的在线编程&#xff0c;编译运行&#xff0c;粘贴分享的平台。你可以在这里输入你的代码&#xff0c;点击运行按钮&#xff0c;就可以看到输出结果。你也…...

HTML中input标签的23种type类型

一、概述 随着html5的出现&#xff0c;input标签新增了多种类型&#xff0c;用以接收各种类型的用户输入。其中传统输入控件有10种&#xff0c;新增输入控件有13种。 二、传统类型 传统输入控件有10种&#xff0c;如下所示 text 定义单行文本输入框 password 定义…...

接口多态与方法多态

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 在上一篇设计山寨版Str…...

js小技巧|如何提取经过Function函数混淆了的代码

关注它&#xff0c;不迷路。 本文章中所有内容仅供学习交流&#xff0c;不可用于任何商业用途和非法用途&#xff0c;否则后果自负&#xff0c;如有侵权&#xff0c;请联系作者立即删除&#xff01; 1.需求 星友发过来一个混淆代码&#xff0c;打开一看&#xff0c;长这…...

【GitLab】流水线入门

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…...

es 中文前缀短语匹配(搜索智能补全)

需求&#xff1a;es进行前缀匹配&#xff0c;用来进行智能补全 过程&#xff1a;es正常的prefix只能进行词语匹配&#xff0c;而中文的分词大部分按字分词&#xff0c;不按语义分词&#xff0c;所以无法搜索出正确的前缀匹配&#xff0c;而能进行短语匹配的match_phrase_prefix…...

机器学习之决策树及随机森林

决策树 概念 决策树(Decision Tree)是一种常见的机器学习算法,用于分类和回归任务。它是一种树状结构,其中每个内部节点表示一个特征或属性,每个分支代表一个决策规则,而每个叶节点表示一个输出标签或值。 构建决策树过程 构建决策树的过程通常涉及以下步骤: 数据准…...

用通俗的方式讲解Transformer:从Word2Vec、Seq2Seq逐步理解到GPT、BERT

直到今天早上&#xff0c;刷到CSDN一篇讲BERT的文章&#xff0c;号称一文读懂&#xff0c;我读下来之后&#xff0c;假定我是初学者&#xff0c;读不懂。 关于BERT的笔记&#xff0c;其实一两年前就想写了&#xff0c;迟迟没动笔的原因是国内外已经有很多不错的资料&#xff0…...

数据结构-01-数组

每一种编程语言中&#xff0c;基本都会有数组这种数据类型。不过&#xff0c;它不仅仅是一种编程语言中的数据类型&#xff0c;还是一种最基础的数据结构。 1-数组的概念和特性 数组&#xff08;Array&#xff09;是一种线性表数据结构。它用一组连续的内存空间&#xff0c;来…...

甘草书店记: 2023年10月11日 星期三 晴 「做有光的人,照亮他人,也引人同行」

发了两篇《甘草书店记》&#xff0c;书店计划公之于众&#xff0c;收获了不少人的赞扬和鼓励&#xff0c;来自生活中的友人&#xff0c;来自麦田的客户和朋友&#xff0c;来自图书界的同行前辈&#xff0c;也来自商界的同仁。其中&#xff0c;最特别留言来自甘草书店投资方的张…...

让 OpenAI GPT4 出 10 道题测试其他开源大语言模型

让 OpenAI GPT4 出 10 道题测试其他开源大语言模型 1. 中文题目及答案2. 日文题目及答案3. 英文题目及答案 1. 中文题目及答案 数学题&#xff1a;一个矩形的长是10厘米&#xff0c;宽是5厘米&#xff0c;求它的面积。 答案&#xff1a;面积 长 x 宽 10厘米 x 5厘米 50平方厘…...

动态库与静态库

1. 库 是代码的二进制的封装形式 在其他的源代码或库中&#xff0c;可以直接调用库的&#xff0c;但是又看不到它 没有公开源代码 库的这种实现方法有利于模块化 而且只要接口合理 不影响库的使用的 sum.c sum.h int sum(int a,int b) { return ab; } xxx.c 需要使用…...

pdf文件编辑,[增删改查]

pdf文件是投标文件中必不可少的格式&#xff0c;传统的方式先编辑word格式&#xff0c;最后生成pdf&#xff0c;但是有时候需要直接编辑pdf文件&#xff0c;编辑pdf的工具无疑 “adobe acrobat dc”是最好用的之一了 1.把图片文件添加到pdf指定位置&#xff0c;例如把一张图片添…...

如何与LEONI建立EDI连接?

莱尼LEONI是一家为汽车及其他行业提供能源数据管理产品、解决方案及服务的全球供应商。供应链范围从研发生产标准化电缆、特种电缆和数据电缆到高度复杂的布线系统和相关组件。本文将介绍如何与莱尼LEONI建立EDI连接。 什么是EDI&#xff1f; EDI全称Electronic Data Interch…...

算法中的时间复杂度,空间复杂度

一、前言 算法&#xff08;Algorithm&#xff09;是指用来操作数据、解决程序问题的一组方法。对于同一个问题&#xff0c;使用不同的算法&#xff0c;也许最终得到的结果是一样的&#xff0c;但在过程中消耗的资源和时间却会有很大的区别 衡量不同算法之间的优劣主要是通过时…...

Python基础:推导式(Comprehensions)详解

1. 推导式概念 Python推导式&#xff08;comprehensions&#xff09;是一种简洁而强大的语法&#xff0c;用于从已存在的数据&#xff08;列表、元组、集合、字典等&#xff09;中创建新的数据结构。推导式包括&#xff1a; 列表推导式元组推导式字典推导式集合推导式 2. 列表…...

安防监控视频融合平台EasyCVR定制化页面开发

安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。安防视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视频录像、云存储、回放与检索…...

Roll-A-Ball 游戏

Roll-A-Ball 游戏 1&#xff09;学习资料 b站视频教程&#xff1a;https://www.bilibili.com/video/BV18W411671S/文档&#xff1a; * Roll-A-Ball 教程&#xff08;一)&#xff0c; * Roll-A-Ball 教程&#xff08;二)线上体验roll-a-ball成品 * http://www-personal.umich.e…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...