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

Spring框架IOC

Spring框架

1. 框架概念和理解

百度百科说法

框架(framework)是一个框子:指其约束性,也是一个架子——指其支撑性。是一个基本概念上的结构,用于去解决或者处理复杂的问题。

软件行业

框架( Framework )是一个集成了基本结构、规范、设计模式、编程语言和程序库等基础组件的软件系统,它可以用来构建更高级别的应用程序。框架的设计和实现旨在解决特定领域中的常见问题,帮助开发人员更高效、更稳定地实现软件开发目标。

我的理解

框架就是在不同行业。不同领域,帮助搭建一个基本的架子,结构,在这基础之上填充

2.框架优点

  1. 提高开发效率
  2. 降低开发成本
  3. 提高应用程序的稳定性
  4. 提高标准化解决方案:可以为开发人员提供一个公共的语言和思想基础,有助于沟通交流。

3、Spring Framework简介

Spring官网

3.1 Spring 和 SpringFramework

广义上的 Spring 泛指以 Spring Framework 为基础的 Spring 技术栈。
狭义的 Spring 特指 Spring Framework,通常我们将它称为 Spring 框架

Spring Framework(Spring框架)是一个开源的应用程序框架,由SpringSource公司开发,最初是为了解决企业级开发中各种常见问题而创建的。它提供了很多功能,例如:依赖注入(Dependency Injection)、面向切面编程(AOP)、声明式事务管理(TX)等。其主要目标是使企业级应用程序的开发变得更加简单和快速,并且Spring框架被广泛应用于Java企业开发领域。

3.2 SpringFramework主要功能模块
功能模块功能介绍
Core Container核心容器,控制反转和依赖注入
AOP&Aspects面向切面编程
TX声明式事务管理
Testing快速整合测试环境
Data Access/Integration提供了对数据访问/集成的功能。
Spring MVC提供了面向Web应用程序的集成功能。

4.Spring IoC/DI概念

4.1普通容器和复杂容器

4.1.1普通容器:普通容器只能用来存储,没有更多功能
程序中的普通容器

  • 数组
  • 集合
    4.1.2程序中的复杂容器

Servlet 容器能够管理 Servlet、Filter、Listener 这样的组件的一生,所以它是一个复杂容器。我们即将要学习的Spring IoC 容器也是一个复杂容器。它们不仅要负责创建组件的对象、存储组件的对象,还要负责调用组件的方法让它们工作,最终在特定情况下销毁组件。

  • 名称时机次数
    创建对象默认情况:接收到第一次请求 修改启动顺序后:Web应用启动过程中一次
    初始化操作创建对象之后一次
    处理请求接收到请求多次
    销毁操作Web应用卸载之前一次
    总结:Spring管理组件的容器,就是一个复杂容器,不仅存储组件,也可以管理组件之间依赖关系,并且创建和销毁组件等!
4.2.SpringIoC容器介绍

Spring IoC容器,负责实例化、配置和组装bean(组件)。容器通过读取配置元数据来获取有关要实例化配置和组装组件的指令。配置元数据以xml、java注解或java代码形式表现,它允许表达组成应用程序的组件以及这些组件之间的相互依赖关系

4.3SpringIoC容器接口和实现
4.3.1 SpringIoc容器接口

org.springframework.beansorg.springframework.context 包是 Spring Framework 的 IoC 容器的基础包。

BeanFactory 接口提供了一种高级配置机制,能够管理任何类型的对象,它是SpringIoC容器标准化超接口!

ApplicationContextBeanFactory 的子接口。它补充说:

  • 更容易与 Spring 的 AOP 功能集成

  • 消息资源处理(用于国际化)

  • 特定于应用程序给予此接口实现,例如Web 应用程序的 WebApplicationContext
    简而言之, BeanFactory 提供了配置框架和基本功能,而 ApplicationContext 添加了更多特定于企业的功能。 ApplicationContextBeanFactory 的完整超集!
    ApplicationContext容器实现类

    类型名简介
    ClassPathXmlApplicationContext通过读取类路径下的 XML 格式的配置文件创建 IOC 容器对象
    FileSystemXmlApplicationContext通过文件系统路径读取 XML 格式的配置文件创建 IOC 容器对象
    AnnotationConfigApplicationContext通过读取Java配置类创建 IOC 容器对象
    WebApplicationContext专门为 Web 应用准备,基于 Web 环境创建 IOC 容器对象,并将对象引入存入 ServletContext 域中。
4.4 SpringIoC容器管理配置方式

SpringIoC容器使用多种形式的配置元数据。此配置元数据表示您作为应用程序告诉开发人员Spring容器实例化、配置和组装应用程序中的对象

4.4.1Spring框架配置方式
  • XML配置方式:是Spring框架最早的配置方式之一,通过在XML中定义Bean及其依赖关系。改方式从Spring框架的第一版开始提供支持
  • 注解方式:Spring2.5版本开始提供支持,通过在Bean类上使用注解来替代XML配置文件的配置信息。通过在Bean类上加相应的注解(如@Component,@Service ),将bean注册到Spring IoC容器就可以管理bean之间的依赖关系了
  • java配置类方式:通过Java类来定义Bean、Bean之间的依赖关系和配置信息,从而代替XML配置文件的方式。Java配置类是一种使用Java编写配置信息的方式,通过@Configuration、@Bean等注解来实现Bean和依赖关系的配置。
4.5 Spring IoC / DI概念
  • IoC容器
    Spring Ioc容器,负责实例化、配置和组装。
  • Ioc控制反转
  • DI依赖注入

5. SpringIoC/DI实现步骤

5.1 配置元数据
5.2实例化IoC容器
5.3 使用容器,获取Bean(组件)

6.三种配置方式如下

6.1 基于XML方式管理Bean步骤
6.1.1 配置元数据
配置元数据,即是编写交给SpringIoC容器管理组件的信息,配置方式有三种
基于XML的配置元数据的基本结构
6.1.2导入相关依赖

(1)在父工程pom中导入Spring相关依赖

在父工程没有加dependencyManagement原因是在父工程不会下载子工程所有都可使用父工程的包。

**注意:**目录4.3.1导入基础包;以及测试

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.atguigu</groupId><artifactId>part01-spring</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.20</version></dependency><!--junit5测试--><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.3.1</version></dependency></dependencies><modules><module>spring-xml</module></modules></project>

(2)在子工程创建一个类

package com.atguigu.spring.pojo;

public class HappyComponent {public void doWork() {System.out.println("HappyComponent.doWork");}
}

(3) 在resources创建一个xml文件
在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="h1" class="com.atguigu.spring.pojo.HappyComponent"></bean><!--bean 标签声明Spring 容器创建的对象id  该对象在容器中的唯一标识class 该对象的全限定名(避免不同包同名)
-->
</beans>

(4)基于配置文件,构建IoC容器,从容器中拿到 配置文件 id class
test创建测试类

package com.atguigu.spring.test;import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Spring01Test {@Testpublic void test(){//        创建容器的2种方式
//        1.创建IoC容器,并读取配置信息。在构建容器时,直接指定配置文件ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-01.xml");
//    2. 先构建空容器,在指定配置文件,触发容器的刷新ClassPathXmlApplicationContext ioc2 = new ClassPathXmlApplicationContext();ioc2.setConfigLocation("spring-01.xml");ioc2.refresh();System.out.println(ioc);System.out.println(ioc2);}
}
org.springframework.context.support.ClassPathXmlApplicationContext@2b2948e2
org.springframework.context.support.ClassPathXmlApplicationContext@1460a8c0
6.1.3 获取bean
通过id获取
    @Testpublic void testIoCGetBean(){
//        ioc.getBean 通过唯一标识name进行获取,缺点:需要强转ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-01.xml");HappyComponent h1 =(HappyComponent) ioc.getBean("h1");h1.doWork();}
通过class获取
    @Testpublic void testIoCGetBeanMethod(){//ioc.getBean(class)//优点:根据类型获取,无需强转//缺点:类型不唯一则报错//org.springframework.beans.factory.NoUniqueBeanDefinitionException:ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-01.xml");HappyComponent h1 = ioc.getBean(HappyComponent.class);h1.doWork();}
通过id+class获取
@Testpublic void testIoCGetBeanMethod(){//ioc.getBean(class)//优点:根据类型获取,无需强转//缺点:类型不唯一则报错//org.springframework.beans.factory.NoUniqueBeanDefinitionException:ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-01.xml");
//        HappyComponent h1 = ioc.getBean(HappyComponent.class);
//        h1.doWork();HappyComponent h1 = ioc.getBean("h1", HappyComponent.class);h1.doWork();}
6.1.4 Bean属性赋值:setter注入

(1). 组件类添加属性

package com.atguigu.spring.pojo;public class HappyComponent {//添加属性private String componentName;public String getComponentName() {return componentName;}public void setComponentName(String componentName) {this.componentName = componentName;}public void doWork() {System.out.println("HappyComponent.doWork");}
}

(2) 配置时给属性指定值

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--    bean 标签  类似创建对象--><bean id="happyComponent" class="com.atguigu.spring.pojo.HappyComponent">
<!--        property 标签:通过组件的setXxx()方法給组件对象设置属性-->
<!--        name属性: 指定属性名(这个属性名是 getXxx(), setXxx()方法定义的,和成员变量无关)-->
<!--        value  值 范围  8大基本数据类型+8大包装类型+String   指定属性值-->
<!--        --><property name="componentName" value="小王"/></bean>
</beans>

(3) 测试属性输出

package com.atguigu.spring.test;import com.atguigu.spring.pojo.HappyComponent;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Spring03Test {@Testpublic void testGetLongSpring(){ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-03.xml");HappyComponent bean = ioc.getBean("happyComponent", HappyComponent.class);System.out.println(bean.getComponentName());}
}
6.1.4 Bean属性赋值:引用其他Bean

(1)创建一个新组件

package com.atguigu.spring.pojo;public class HappyMachine {private String machineName;public String getMachineName() {return machineName;}public void setMachineName(String machineName) {this.machineName = machineName;}@Overridepublic String toString() {return "HappyMachine{" +"machineName='" + machineName + '\'' +'}';}
}

(2)原组件引用新组件

package com.atguigu.spring.pojo;public class HappyComponent {//添加属性private String componentName;public String getComponentName() {return componentName;}public void setComponentName(String componentName) {this.componentName = componentName;}//   添加新属性private HappyMachine happyMachine;public HappyMachine getHappyMachine() {return happyMachine;}public void setHappyMachine(HappyMachine happyMachine) {this.happyMachine = happyMachine;}public Integer my;public Integer getMy() {return my;}public void setMy(Integer my) {this.my = my;}public void doWork() {System.out.println("HappyComponent.doWork");}@Overridepublic String toString() {return "HappyComponent{" +"componentName='" + componentName + '\'' +", happyMachine=" + happyMachine +", my=" + my +'}';}
}

(3)组件之间引用配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="happyComponent" class="com.atguigu.spring.pojo.HappyComponent"><property name="componentName" value="aaa"/><property name="happyMachine"  ref="happyMachine"/>
<!--            采用value赋值时,真正的类型是咋运行时,进行转化的-->
<!--            17种类型以外的赋值,不能采用value--><property name="my" value="2344"/></bean><bean id="happyMachine" class="com.atguigu.spring.pojo.HappyMachine"><property name="machineName" value="快乐星球"/></bean>
</beans>

注意事项

  • 声明bean,不分先后顺序,spring容器内部有缓存机制,先实例化后属性赋值
  • ref 容易错写成value,会抛出Caused by: java.lang.IllegalStateException: Cannot convert value of type ‘java.lang.String’ to required type 异常!
  • 只有声明到ioc容器,方可被其他bean引用!
Bean 属性赋值:内部Bean声明(了解)

(1)声明内部bean配置
在bean里面配置的bean就是内部bean,内部bean只能在当前bean内部使用,在其他地方不能使用。

不会在ioc容器中,实例和存储内部bean,只会缓存类信息,每次获取的时候再实例化!!

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--声明内部bean 就是为了避免外部bean 被多个bean共享时,数据被篡改导致多个bean数据都会受影响--><bean id="happyComponent" class="com.atguigu.spring.pojo.HappyComponent"><property name="componentName" value="ssonhe"/><property name="my" value="120000"/><property name="happyMachine" ><bean class="com.atguigu.spring.pojo.HappyMachine"><property name="machineName" value="卷网"/></bean></property></bean>
</beans>

(2)测试

package com.atguigu.spring.test;import com.atguigu.spring.pojo.HappyComponent;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Spring05Test {@Testpublic void testInnerBean(){ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-05.xml");HappyComponent bean = ioc.getBean("happyComponent", HappyComponent.class);System.out.println(bean);}
}
6.2基于 注解 方式管理 Bean
6.2.1 Bean注解标记和扫描(IoC)

(1)注解理解:和 XML 配置文件一样,注解本身并不能执行,注解本身仅仅只是做一个标记,具体的功能是框架检测到注解标记的位置,然后针对这个位置按照注解标记的功能来执行具体操作
(2)扫描理解:Spring 为了知道程序员在哪些地方标记了什么注解,就需要通过扫描的方式,来进行检测。然后根据注解进行后续操作。
(3) 代码测试
(3.1)准备三层架构
controller

package com.atguigu.spring.xml.controller;import com.atguigu.spring.xml.service.NewUserService;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
@Controller
public class NewUserController {private NewUserService newUserService;public void setNewUserService(NewUserService newUserService) {this.newUserService = newUserService;}public void showAllUser(){System.out.println("NewUserController执行了showAllUser");
//        newUserService.showAllUser();}
}

Service

package com.atguigu.spring.xml.service.impl;import com.atguigu.spring.xml.dao.NewUserDao;
import com.atguigu.spring.xml.dao.impl.NewUserDaoImpl;
import com.atguigu.spring.xml.service.NewUserService;
import org.springframework.stereotype.Service;@Service
public class NewUserServiceImpl implements NewUserService {private NewUserDao newUserDao;public void setNewUserDao(NewUserDao newUserDao) {this.newUserDao = newUserDao;}@Overridepublic void showAllUser() {System.out.println("NewUserServiceImpl执行showAllUser");
//        newUserDao.selectAll();}
}

dao

package com.atguigu.spring.xml.dao.impl;import com.atguigu.spring.xml.dao.NewUserDao;
import org.springframework.stereotype.Repository;@Repository
public class NewUserDaoImpl implements NewUserDao {@Overridepublic void selectAll() {System.out.println("NewUserDaoImpl执行了selectAll selectAll");}
}

spring-anno.xml配置文件确定扫描范围
(1-1)全部扫描

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--       直接扫描包及其子包-->
<!--        扫描规则--><context:component-scan base-package="com.atguigu.spring.xml"/>
</beans>

(1-2)指定排除扫描

<!-- 情况三:指定不扫描的组件 -->
<context:component-scan base-package="com.atguigu.components"><!-- context:exclude-filter标签:指定排除规则 --><!-- type属性:指定根据什么来进行排除,annotation取值表示根据注解来排除 --><!-- expression属性:指定排除规则的表达式,对于注解来说指定全类名即可 --><context:exclude-filter type="annotation" expression="com.atguigu.spring.xml.controller"/>
</context:component-scan>

(1-3)指定扫描组件

<!-- 情况四:仅扫描指定的组件 -->
<!-- 仅扫描 = 关闭默认规则 + 追加规则 -->
<!-- use-default-filters属性:取值false表示关闭默认扫描规则 -->
<context:component-scan base-package="com.atguigu.ioc.components" use-default-filters="false"><!-- context:include-filter标签:指定在原有扫描规则的基础上追加的规则 --><context:include-filter type="annotation" expression="com.atguigu.spring.xml.controller"/>
</context:component-scan>
6.2.2组件BeanName问题

在我们使用 XML 方式管理 bean 的时候,每个 bean 都有一个唯一标识——id 属性的值,便于在其他地方引用。现在使用注解后,每个组件仍然应该有一个唯一标识.
默认情况:
类名首字母小写就是 bean 的 id。例如:SoldierController 类对应的 bean 的 id 就是 soldierController

6.2.3Bean属性赋值:引用类型自动装配(DI)
假设场景
  • Controller 需要 Service
  • Service 需要Dao
    同时在各个组件中声明要调用的方法。
  • SoldierController中声明方法
自动装配实现

(1) 前提
参与自动装配的组件(需要装配、被装配)全部都必须在IoC容器中。
注意:不区分IoC的方式!XML和注解都可以!
(2)@Autowired注解
在成员变量上直接标记@Autowired注解即可,不需要提供setXxx()方法。以后我们在项目中的正式用法就是这样。
(3)给Controller装配Service

package com.atguigu.spring.xml.controller;import com.atguigu.spring.xml.service.NewUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
@Controller
public class NewUserController {@Autowiredprivate NewUserService newUserService;public void showAllUser(){System.out.println("NewUserController执行了showAllUser");newUserService.showAllUser();}
}

(4)给Service装配Dao

package com.atguigu.spring.xml.service.impl;import com.atguigu.spring.xml.dao.NewUserDao;
import com.atguigu.spring.xml.dao.impl.NewUserDaoImpl;
import com.atguigu.spring.xml.service.NewUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class NewUserServiceImpl implements NewUserService {@Autowiredprivate NewUserDao newUserDao;@Overridepublic void showAllUser() {System.out.println("NewUserServiceImpl执行showAllUser");newUserDao.selectAll();}
}

@Autowired注解解释就是替换

<property name="newUserDao" ref="newUserDao"></property>
配置类 方式管理 Bean
配置类

使用 @Configuration 注解将一个普通的类标记为 Spring 的配置类。

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;//标注当前类是配置类,替代application.xml    
@Configuration
//使用注解读取外部配置,替代 <context:property-placeholder标签
@PropertySource("classpath:application.properties")
//使用@ComponentScan注解,可以配置扫描包,替代<context:component-scan标签
@ComponentScan(basePackages = {"com.atguigu.components"})
public class MyConfiguration {}

测试创建IoC容器

// AnnotationConfigApplicationContext 根据配置类创建 IOC 容器对象
ApplicationContext iocContainerAnnotation = 
new AnnotationConfigApplicationContext(MyConfiguration.class);

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • vulhub远程执行命令漏洞CVE-2022-22963
  • flutter的入口和原生交互
  • Svn常用操作技巧详细说明
  • ES模块导入、导出学习笔记
  • Python条形码生成
  • Linux中的时间
  • Python中的`range()`函数及其用法
  • 九、制作卡牌预制体
  • windows清理图标缓存
  • 群晖最新版(DSM 7.2) 下使用 Web Station 部署 flask 项目
  • Xilinx FPGA 原语解析(二):IBUFDS差分输入缓冲器(示例源码及仿真)
  • Nosql数据库
  • 算法复杂度的简单介绍
  • 程序的格式框架与缩进
  • Unity之获取Avpro视频画面并在本地创建缩略图
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • 230. Kth Smallest Element in a BST
  • classpath对获取配置文件的影响
  • CSS实用技巧干货
  • docker容器内的网络抓包
  • ECMAScript6(0):ES6简明参考手册
  • Java,console输出实时的转向GUI textbox
  • java架构面试锦集:开源框架+并发+数据结构+大企必备面试题
  • Joomla 2.x, 3.x useful code cheatsheet
  • JSDuck 与 AngularJS 融合技巧
  • mysql innodb 索引使用指南
  • NSTimer学习笔记
  • quasar-framework cnodejs社区
  • spring security oauth2 password授权模式
  • uni-app项目数字滚动
  • WePY 在小程序性能调优上做出的探究
  • 案例分享〡三拾众筹持续交付开发流程支撑创新业务
  • 当SetTimeout遇到了字符串
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 前端之React实战:创建跨平台的项目架构
  • 微服务框架lagom
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • #{}和${}的区别是什么 -- java面试
  • #如何使用 Qt 5.6 在 Android 上启用 NFC
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • (01)ORB-SLAM2源码无死角解析-(56) 闭环线程→计算Sim3:理论推导(1)求解s,t
  • (2024,Flag-DiT,文本引导的多模态生成,SR,统一的标记化,RoPE、RMSNorm 和流匹配)Lumina-T2X
  • (3)llvm ir转换过程
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (接口自动化)Python3操作MySQL数据库
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • *p++,*(p++),*++p,(*p)++区别?
  • .NET Core 将实体类转换为 SQL(ORM 映射)
  • .net core 控制台应用程序读取配置文件app.config
  • .Net Core和.Net Standard直观理解