# Spring框架 ## 一、添加Spring依赖 ```xml 7.0.0-M9 org.springframework spring-context ${spring.version} org.springframework spring-jdbc ${spring.version} ``` ## 二、配置Spring Spring核心思想:控制反转、依赖注入: 除了JavaBean对象(po对象)都可以进行控制反转,注入到bean中。 Spring配置文件就相当于一个容器,此容器中负责创建对象,并实现对象与对象之间的装配; Java中每一个类都是一个bean,所以下面的bean标签,就是在容器中创建一个Java对象; bean标签中的class属性就是类名,id属性就是对象名。 在`resources`目录下创建`SpringConfig.xml`。 ```xml ``` ## 三、传统方法调用Java类 创建`cn.doooog.springdome.controller`、`cn.doooog.springdome.po`、`cn.doooog.springdome.service`、`cn.doooog.springdome.mapper`包,在`service`包下添加如下函数 ```java package cn.doooog.springdome.service; public class Service { public void serviceMethod01() { System.out.println("service层方法01调用"); } } ``` 在`controller`包下添加 ```java package cn.doooog.springdome.controller; import cn.doooog.springdome.service.Service; public class Controller { public void ctrlMethod01(){ Service service = new Service(); service.serviceMethod01(); } } ``` 如上述代码,若要调用service层的方法就需要new一个新的service对象。 ## 四、IOC/DI #### 1、手动方式创建Bean 在`SpringConfig.xml`中添加``标签代表创建一个JavaBean,调用了**无参构造**方法来实现对象的创建。 ```xml ``` 修改`Controller`的方法 ```java public void ctrlMethod01() { // 获得Spring容器 ApplicationContext app = new ClassPathXmlApplicationContext("SpringConfig.xml"); // 获得对象 Service service = (Service) app.getBean("service"); service.serviceMethod01(); } ``` 可以发现,上述方法内并没有去new一个对象,但是却能获得一个对应的对象,这种创建方法为 #### 2、手动依赖注入属性 如果`Service`中有多个属性,传统方法使用有参构造或者使用Setter方法修改,但在Spring中只需要在`SpringConfig.xml`配置注入规则即可为属性赋值。 ##### Set注入 在`SpringConfig.xml`中添加`` ```xml ``` **注意**:``标签中``对应的是类的属性,`name`为属性名,`ref`是提供属性类型的类,在`Controller.java`类中必须有该属性的`Setter`方法。 修改`Controller.java` ```java package cn.doooog.springdome.controller; import cn.doooog.springdome.service.Service; public class Controller { private Service service; public Service getService() { return service; } public void setService(Service service) { this.service = service; } public void ctrlMethod01() { System.out.println("Controller层方法01被调用"); service.serviceMethod01(); } } ``` 创建`cn.doooog.springdome/Test.java`测试类 ```java package cn.doooog.springdome; import cn.doooog.springdome.controller.Controller; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { // 获得Spring容器 ApplicationContext app = new ClassPathXmlApplicationContext("SpringConfig.xml"); // 获得对象 Controller controller = (Controller) app.getBean("ctrl"); controller.ctrlMethod01(); } } ``` **注入常用类型和基本数据**,同样的,在类中需要添加对应属性的`Setter`方法 ```xml ``` **集合类型注入**,同样的,在类中需要添加对应属性的`Setter`方法 ##### 构造器注入 需要添加有参构造方法,修改`Controller.java` ```java package cn.doooog.springdome.controller; import cn.doooog.springdome.service.Service; public class Controller { private Service service; public Controller() { } public Controller(Service service) { this.service = service; } public Service getService() { return service; } public void setService(Service service) { this.service = service; } public void ctrlMethod01() { System.out.println("Controller层方法01被调用"); service.serviceMethod01(); } } ``` 修改`SpringConfig.xml` ```xml ``` 测试方法不变。 **注意**:使用构造器注入时可能会出现**循环依赖**,就是A中的属性为B,B中的属性为A,解决循环依赖的方法是使用**Set注入** #### 3、自动方式创建Bean 使用指定的注解 Dao(Mapper)层 @Repository Service层 @Service Controller层 @Controller 任意类 @Component 以上注解只是名称不同,起区分作用,并无其他功能差异。 修改`SpringConfig.xml`,添加注解扫描器与自动化注入 ```xml ``` 修改`Service.java` ```java package cn.doooog.springdome.service; @org.springframework.stereotype.Service("service") public class Service { public void serviceMethod01() { System.out.println("service层方法01调用"); } } ``` 在测试类中调用 ```java package cn.doooog.springdome; import cn.doooog.springdome.service.Service; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { // 获得Spring容器 ApplicationContext app = new ClassPathXmlApplicationContext("SpringConfig.xml"); // 获得对象 Service service = (Service) app.getBean("service"); service.serviceMethod01(); } } ``` #### 4、自动依赖注入属性 依赖注入的注解有两种:`@Resource`与`@Autowired`,前者是先通过名称来注入,后者是先通过类型来注入,`@Autowired`比较常用 修改`Controller.java` ##### 字段注入 ```java package cn.doooog.springdome.controller; import cn.doooog.springdome.service.Service; import org.springframework.beans.factory.annotation.Autowired; @org.springframework.stereotype.Controller("ctrl") public class Controller { @Autowired private Service service; public Controller() { } public Controller(Service service) { this.service = service; } public Service getService() { return service; } public void setService(Service service) { this.service = service; } public void ctrlMethod01() { System.out.println("Controller层方法01被调用"); service.serviceMethod01(); } } ``` ##### 构造方法注入 ```java package cn.doooog.springdome.controller; import cn.doooog.springdome.service.Service; import org.springframework.beans.factory.annotation.Autowired; @org.springframework.stereotype.Controller("ctrl") public class Controller { private Service service; public Controller() { } @Autowired public Controller(Service service) { this.service = service; } public Service getService() { return service; } public void setService(Service service) { this.service = service; } public void ctrlMethod01() { System.out.println("Controller层方法01被调用"); service.serviceMethod01(); } } ``` **注意**:推荐使用构造方法注入,构造方法注入是非侵入式的注入,在注入时必须是有参的。 测试类内调用 ```java package cn.doooog.springdome; import cn.doooog.springdome.controller.Controller; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { // 获得Spring容器 ApplicationContext app = new ClassPathXmlApplicationContext("SpringConfig.xml"); // 获得对象 Controller controller = (Controller) app.getBean("ctrl"); controller.ctrlMethod01(); } } ``` ## 五、JavaConfig实现配置 需要添加`@Configuration` ```java package cn.doooog.springdome; import cn.doooog.springdome.controller.Controller; import cn.doooog.springdome.service.Service; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AppConfig { @Bean public Service service() { return new Service(); } @Bean public Controller controller() { return new Controller(new Service()); } } ``` ## 六、生命周期 #### Bean的作用域 可以使用`@Scope()`注解来修改作用域 | 作用域 | 注解值 | 说明 | 生命周期 | | :------------ | :------------ | :----------------------------------------------- | :------------------------------ | | **单例** | `singleton` | `默认`作用域,整个Spring容器中只存在一个Bean实例 | 容器启动时创建,容器关闭时销毁 | | **原型** | `prototype` | 每次获取时都创建一个新的Bean实例 | 每次获取时创建,使用后由GC回收 | | **请求** | `request` | 每个HTTP请求创建一个新的Bean实例 | 请求开始时创建,请求结束时销毁 | | **会话** | `session` | 每个HTTP会话创建一个Bean实例 | 会话开始时创建,会话结束时销毁 | | **应用** | `application` | 每个ServletContext生命周期内一个实例 | 应用启动时创建,应用关闭时销毁 | | **WebSocket** | `websocket` | 每个WebSocket会话一个实例 | WebSocket连接时创建,断开时销毁 | **示例** 在`Controller.java`中添加`@Scope("prototype")`注解,使其变成原型 ```java package cn.doooog.springdome.controller; import cn.doooog.springdome.service.Service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; @org.springframework.stereotype.Controller("ctrl") @Scope("prototype") public class Controller { private Service service; public Controller() { } @Autowired public Controller(Service service) { this.service = service; } public Service getService() { return service; } public void setService(Service service) { this.service = service; } public void ctrlMethod01() { System.out.println("Controller层方法01被调用"); service.serviceMethod01(); } } ``` 在测试类中调用 ```java package cn.doooog.springdome; import cn.doooog.springdome.controller.Controller; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { // 获得Spring容器 ApplicationContext app = new ClassPathXmlApplicationContext("SpringConfig.xml"); // 获得对象 Controller controller1 = (Controller) app.getBean("ctrl"); Controller controller2 = (Controller) app.getBean("ctrl"); System.out.println(controller1 == controller2); System.out.println(controller1.getService() == controller2.getService()); } } ``` 会发现输出`false、true`,因为`Controller`是原型Bean,每一个都是新的对象,而里面的`service`属性并没有设置作用域,默认为单例,所以两个`service`属性其实都是一个。 # MySQL题目 ## 一、 查询下表中所有学科成绩都大于90的人  #### 方法一 使用笛卡尔积内连接 ```sql SELECT * FROM chengji yw, chengji sx, chengji yy WHERE ... ``` #### 方法二 使用SUM函数增列 ```sql SELECT * FROM ( SELECT sname, SUM(CASE knm WHEN '语文' THEN cj ELSE 0 END) 语文, SUM(CASE knm WHEN '数学' THEN cj ELSE 0 END) 数学, SUM(CASE knm WHEN '英语' THEN cj ELSE 0 END) 英语, FROM chengji GROUP BY sname ) t WHERE t.语文>90 and 数学>90 and 英语>90; ``` #### 方法三 求出所有科目>90的所有人,用HAVING过滤出姓名出现三次的人。 ```sql SELECT sname FROM chengji WHERE (knm="语文" AND cj>90) OR (knm="数学" AND cj>90) OR (knm="英语" AND cj>90) GROUP BY sname HAVING COUNT(knm)=3; ``` Loading... # Spring框架 ## 一、添加Spring依赖 ```xml <properties> <spring.version>7.0.0-M9</spring.version> </properties> <dependencies> <!-- Spring相关依赖 --> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> </dependencies> ``` ## 二、配置Spring Spring核心思想:控制反转、依赖注入: 除了JavaBean对象(po对象)都可以进行控制反转,注入到bean中。 Spring配置文件就相当于一个容器,此容器中负责创建对象,并实现对象与对象之间的装配; Java中每一个类都是一个bean,所以下面的bean标签,就是在容器中创建一个Java对象; bean标签中的class属性就是类名,id属性就是对象名。 在`resources`目录下创建`SpringConfig.xml`。 ```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"> </beans> ``` ## 三、传统方法调用Java类 创建`cn.doooog.springdome.controller`、`cn.doooog.springdome.po`、`cn.doooog.springdome.service`、`cn.doooog.springdome.mapper`包,在`service`包下添加如下函数 ```java package cn.doooog.springdome.service; public class Service { public void serviceMethod01() { System.out.println("service层方法01调用"); } } ``` 在`controller`包下添加 ```java package cn.doooog.springdome.controller; import cn.doooog.springdome.service.Service; public class Controller { public void ctrlMethod01(){ Service service = new Service(); service.serviceMethod01(); } } ``` 如上述代码,若要调用service层的方法就需要new一个新的service对象。 ## 四、IOC/DI #### 1、手动方式创建Bean 在`SpringConfig.xml`中添加`<bean>`标签代表创建一个JavaBean,调用了**无参构造**方法来实现对象的创建。 ```xml <bean id="service" class="cn.doooog.springdome.service.Service"/> ``` 修改`Controller`的方法 ```java public void ctrlMethod01() { // 获得Spring容器 ApplicationContext app = new ClassPathXmlApplicationContext("SpringConfig.xml"); // 获得对象 Service service = (Service) app.getBean("service"); service.serviceMethod01(); } ``` 可以发现,上述方法内并没有去new一个对象,但是却能获得一个对应的对象,这种创建方法为 #### 2、手动依赖注入属性 如果`Service`中有多个属性,传统方法使用有参构造或者使用Setter方法修改,但在Spring中只需要在`SpringConfig.xml`配置注入规则即可为属性赋值。 ##### Set注入 在`SpringConfig.xml`中添加`<bean>` ```xml <bean id="ctrl" class="cn.doooog.springdome.controller.Controller"> <property name="service" ref="service"/> </bean> ``` **注意**:`<bean>`标签中`<property>`对应的是类的属性,`name`为属性名,`ref`是提供属性类型的类,在`Controller.java`类中必须有该属性的`Setter`方法。 修改`Controller.java` ```java package cn.doooog.springdome.controller; import cn.doooog.springdome.service.Service; public class Controller { private Service service; public Service getService() { return service; } public void setService(Service service) { this.service = service; } public void ctrlMethod01() { System.out.println("Controller层方法01被调用"); service.serviceMethod01(); } } ``` 创建`cn.doooog.springdome/Test.java`测试类 ```java package cn.doooog.springdome; import cn.doooog.springdome.controller.Controller; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { // 获得Spring容器 ApplicationContext app = new ClassPathXmlApplicationContext("SpringConfig.xml"); // 获得对象 Controller controller = (Controller) app.getBean("ctrl"); controller.ctrlMethod01(); } } ``` **注入常用类型和基本数据**,同样的,在类中需要添加对应属性的`Setter`方法 ```xml <bean id="ctrl" class="cn.doooog.springdome.controller.Controller"> <property name="属性名" value="属性值"/> </bean> ``` **集合类型注入**,同样的,在类中需要添加对应属性的`Setter`方法 ##### 构造器注入 需要添加有参构造方法,修改`Controller.java` ```java package cn.doooog.springdome.controller; import cn.doooog.springdome.service.Service; public class Controller { private Service service; public Controller() { } public Controller(Service service) { this.service = service; } public Service getService() { return service; } public void setService(Service service) { this.service = service; } public void ctrlMethod01() { System.out.println("Controller层方法01被调用"); service.serviceMethod01(); } } ``` 修改`SpringConfig.xml` ```xml <bean id="ctrl" class="cn.doooog.springdome.controller.Controller"> <constructor-arg name="service" ref="service"/> </bean> ``` 测试方法不变。 **注意**:使用构造器注入时可能会出现**循环依赖**,就是A中的属性为B,B中的属性为A,解决循环依赖的方法是使用**Set注入** #### 3、自动方式创建Bean 使用指定的注解 Dao(Mapper)层 @Repository Service层 @Service Controller层 @Controller 任意类 @Component 以上注解只是名称不同,起区分作用,并无其他功能差异。 修改`SpringConfig.xml`,添加注解扫描器与自动化注入 ```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" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--加入自动化扫描--> <context:component-scan base-package="cn.doooog.springdome"/> <!--自动化装配--> <context:annotation-config/> </beans> ``` 修改`Service.java` ```java package cn.doooog.springdome.service; @org.springframework.stereotype.Service("service") public class Service { public void serviceMethod01() { System.out.println("service层方法01调用"); } } ``` 在测试类中调用 ```java package cn.doooog.springdome; import cn.doooog.springdome.service.Service; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { // 获得Spring容器 ApplicationContext app = new ClassPathXmlApplicationContext("SpringConfig.xml"); // 获得对象 Service service = (Service) app.getBean("service"); service.serviceMethod01(); } } ``` #### 4、自动依赖注入属性 依赖注入的注解有两种:`@Resource`与`@Autowired`,前者是先通过名称来注入,后者是先通过类型来注入,`@Autowired`比较常用 修改`Controller.java` ##### 字段注入 ```java package cn.doooog.springdome.controller; import cn.doooog.springdome.service.Service; import org.springframework.beans.factory.annotation.Autowired; @org.springframework.stereotype.Controller("ctrl") public class Controller { @Autowired private Service service; public Controller() { } public Controller(Service service) { this.service = service; } public Service getService() { return service; } public void setService(Service service) { this.service = service; } public void ctrlMethod01() { System.out.println("Controller层方法01被调用"); service.serviceMethod01(); } } ``` ##### 构造方法注入 ```java package cn.doooog.springdome.controller; import cn.doooog.springdome.service.Service; import org.springframework.beans.factory.annotation.Autowired; @org.springframework.stereotype.Controller("ctrl") public class Controller { private Service service; public Controller() { } @Autowired public Controller(Service service) { this.service = service; } public Service getService() { return service; } public void setService(Service service) { this.service = service; } public void ctrlMethod01() { System.out.println("Controller层方法01被调用"); service.serviceMethod01(); } } ``` **注意**:推荐使用构造方法注入,构造方法注入是非侵入式的注入,在注入时必须是有参的。 测试类内调用 ```java package cn.doooog.springdome; import cn.doooog.springdome.controller.Controller; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { // 获得Spring容器 ApplicationContext app = new ClassPathXmlApplicationContext("SpringConfig.xml"); // 获得对象 Controller controller = (Controller) app.getBean("ctrl"); controller.ctrlMethod01(); } } ``` ## 五、JavaConfig实现配置 需要添加`@Configuration` ```java package cn.doooog.springdome; import cn.doooog.springdome.controller.Controller; import cn.doooog.springdome.service.Service; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AppConfig { @Bean public Service service() { return new Service(); } @Bean public Controller controller() { return new Controller(new Service()); } } ``` ## 六、生命周期 #### Bean的作用域 可以使用`@Scope()`注解来修改作用域 | 作用域 | 注解值 | 说明 | 生命周期 | | :------------ | :------------ | :----------------------------------------------- | :------------------------------ | | **单例** | `singleton` | `默认`作用域,整个Spring容器中只存在一个Bean实例 | 容器启动时创建,容器关闭时销毁 | | **原型** | `prototype` | 每次获取时都创建一个新的Bean实例 | 每次获取时创建,使用后由GC回收 | | **请求** | `request` | 每个HTTP请求创建一个新的Bean实例 | 请求开始时创建,请求结束时销毁 | | **会话** | `session` | 每个HTTP会话创建一个Bean实例 | 会话开始时创建,会话结束时销毁 | | **应用** | `application` | 每个ServletContext生命周期内一个实例 | 应用启动时创建,应用关闭时销毁 | | **WebSocket** | `websocket` | 每个WebSocket会话一个实例 | WebSocket连接时创建,断开时销毁 | **示例** 在`Controller.java`中添加`@Scope("prototype")`注解,使其变成原型 ```java package cn.doooog.springdome.controller; import cn.doooog.springdome.service.Service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; @org.springframework.stereotype.Controller("ctrl") @Scope("prototype") public class Controller { private Service service; public Controller() { } @Autowired public Controller(Service service) { this.service = service; } public Service getService() { return service; } public void setService(Service service) { this.service = service; } public void ctrlMethod01() { System.out.println("Controller层方法01被调用"); service.serviceMethod01(); } } ``` 在测试类中调用 ```java package cn.doooog.springdome; import cn.doooog.springdome.controller.Controller; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { // 获得Spring容器 ApplicationContext app = new ClassPathXmlApplicationContext("SpringConfig.xml"); // 获得对象 Controller controller1 = (Controller) app.getBean("ctrl"); Controller controller2 = (Controller) app.getBean("ctrl"); System.out.println(controller1 == controller2); System.out.println(controller1.getService() == controller2.getService()); } } ``` 会发现输出`false、true`,因为`Controller`是原型Bean,每一个都是新的对象,而里面的`service`属性并没有设置作用域,默认为单例,所以两个`service`属性其实都是一个。 # MySQL题目 ## 一、 查询下表中所有学科成绩都大于90的人  #### 方法一 使用笛卡尔积内连接 ```sql SELECT * FROM chengji yw, chengji sx, chengji yy WHERE ... ``` #### 方法二 使用SUM函数增列 ```sql SELECT * FROM ( SELECT sname, SUM(CASE knm WHEN '语文' THEN cj ELSE 0 END) 语文, SUM(CASE knm WHEN '数学' THEN cj ELSE 0 END) 数学, SUM(CASE knm WHEN '英语' THEN cj ELSE 0 END) 英语, FROM chengji GROUP BY sname ) t WHERE t.语文>90 and 数学>90 and 英语>90; ``` #### 方法三 求出所有科目>90的所有人,用HAVING过滤出姓名出现三次的人。 ```sql SELECT sname FROM chengji WHERE (knm="语文" AND cj>90) OR (knm="数学" AND cj>90) OR (knm="英语" AND cj>90) GROUP BY sname HAVING COUNT(knm)=3; ``` 最后修改:2025 年 10 月 29 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 👆请简单粗暴地爱我。