mysql基礎-進階三【排序查詢】
1、Spring
1.1 簡介
- Spring是一個開源框架,它由[Rod Johnson](https://baike.baidu.com/item/Rod Johnson)建立。它是為了解決企業應用開發的複雜性而建立的。
- Spring使用基本的JavaBean來完成以前只可能由EJB完成的事情。
- Spring的用途不僅限於伺服器端的開發。從簡單性、可測試性和鬆耦合的角度而言,任何Java應用都可以從Spring中受益。
- Spring理念:使現有技術更加容易使用,本身是一個大雜燴,整合了現有的技術框架!
官網:https://spring.io/projects/spring-framework#overview
官方下載地址: https://repo.spring.io/release/org/springframework/spring
Github: https://github.com/spring-projects/spring-framework
Maven依賴:
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.9.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.9.RELEASE</version> </dependency>
1.2 優點
- Spring是一個開源的免費框架(容器)!
- Spring是一個輕量級、非入侵式的框架!
- 控制反轉(IOC)、面向切面程式設計(AOP)
- 支援事務的處理,對框架整合的支援!
總結:Spring就是一個輕量級的控制反轉(IOC)和麵向切面程式設計(AOP)的框架!
1.3 組成
1.4 拓展
現代化的Java開發!是基於Spring的開發
- Spring Boot
- 一個快速開發的腳手架
- 基於SpringBoot可以快速開發單個微服務
- 約定大於配置
- Spring Cloud
- 基於SpringBoot實現
2、IOC理論推導
在我們之前的業務中,使用者的需求會影響我們原來的程式碼。我們需要根據使用者的需求去修改原始碼!如果程式程式碼量十分大,修改一次的成本十分昂貴
使用一個Set介面實現
private UserDao userDao;
// 利用set進行動態實現值的注入!
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
- 之前程式是主動建立物件,控制權在程式設計師手上!
- 使用了set注入後,程式不再具有主動性,而是變成了被動的接受物件!
這種思想,從本質上解決了問題,程式設計師不用再去管理物件的建立,系統的耦合性大大降低,可以更加專注業務的實現!這是IOC的原型
- 控制反轉:物件A獲得依賴物件B的過程,由主動行為變為了被動行為,控制權顛倒過來了。
- 依賴注入:所謂依賴注入,就是由IOC容器在執行期間,動態地將某種依賴關係注入到物件之中。
3、IOC建立物件的方式
-
使用無參構造建立物件,預設!
-
假設使用有參構造建立物件
-
下標賦值
<!--有參創造 1.下標賦值 --> <bean id="user" class="com.guo.pojo.User"> <constructor-arg index="0" value="郭玉紅"/> </bean>
-
通過型別建立
<!-- 2. 型別匹配 (不建議使用!) --> <bean id="user" class="com.guo.pojo.User"> <constructor-arg type="java.lang.String" value="郭玉紅"/> </bean>
-
通過引數名來設定
<!-- 第三種, 直接通過引數名來設定--> <bean id="user" class="com.guo.pojo.User"> <constructor-arg name="name" value="哈哈"/> </bean>
總結:在配置檔案載入的時候,容器中管理的物件就已經初始化了!
-
5、Spring配置
5.1 別名
<!--別名,如果添加了別名,我們可以使用別名來獲取到這個物件 -->
<alias name="user" alias="user2"/>
5.2 Bean的配置
<!--
id: bean的唯一識別符號,也就是相當於我們學的物件名
class: bean物件所對應的全限定名:包名+型別
name:也是別名,而且name可以取多個別名
-->
<bean id="user" class="com.guo.pojo.User" name="user3,user4,user5">
<property name="name" value="郭玉紅"/>
</bean>
5.3 import
一般用於團隊開發使用,可以將多個配置檔案,合併為一個
假設專案有多人開發,三人負責不同的類開發,不同的類需註冊不同的Bean中,我們可以用import將所有的beans.xml合併為一個,使用的時候,直接使用總的。
6、依賴注入
6.1 構造器注入
6.2 Set方式注入【重點】
-
依賴注入:Set注入!
- 依賴:bean物件的建立依賴於容器!
- 注入:bean物件中的所有屬性,由容器注入!
-
複雜型別
public class Address { private String addrerss; public String getAddrerss() { return addrerss; } public void setAddrerss(String addrerss) { this.addrerss = addrerss; } }
-
真實測試物件
public class Student { private String name; private Address address; private String[] books; private List<String> hobbys; private Map<String,String> card; private Set<String> games; private String wife; private Properties info; }
-
beans.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="student" class="com.guo.pojo.Student"> <!-- 第一種,普通值注入,value --> <property name="name" value="郭玉紅"/> </bean> </beans>
-
測試類
public class myTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Student student =(Student) context.getBean("student"); System.out.println(student.getAddress()); } }
-
完善注入資訊
<?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="address" class="com.guo.pojo.Address"> <property name="addrerss" value="西安"/> </bean> <bean id="student" class="com.guo.pojo.Student"> <!-- 第一種,普通值注入,value --> <property name="name" value="郭玉紅"/> <!-- 第二種,Bean注入,ref--> <property name="address" ref="address"/> <!-- 第三種,陣列注入 --> <property name="books"> <array> <value>紅樓夢</value> <value>三國演義</value> <value>水滸傳</value> <value>西遊記</value> </array> </property> <!--List --> <property name="hobbys"> <list> <value>聽歌</value> <value>看電影</value> <value>跑步</value> <value>打球</value> </list> </property> <!--Map --> <property name="card"> <map> <entry key="身份證" value="4115556655522"/> <entry key="銀行卡" value="46434464644611"/> </map> </property> <!-- Set --> <property name="games"> <set> <value>LOL</value> <value>COC</value> <value>BOB</value> </set> </property> <property name="wife"> <null></null> </property> <!--Properties --> <property name="info"> <props> <prop key="學號">2020262798</prop> <prop key="性別">男</prop> <prop key="姓名">小明</prop> </props> </property> </bean> </beans>
6.3 Bean的作用域
1. 單例模式
<bean id="user2" class="com.guo.pojo.User" scope="singleton"/>
- 原型模式: 每次從容器中get的時候,都會產生一個新物件!
<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>
- 其餘的request、session、application 這些只能在web開發中使用到!
7、Bean的自動裝配
- 在xml中顯式的裝配
- 在java中顯式裝配
- 隱式的自動裝配bean【重要】
7.1 ByName自動裝配
<!--
byName: 會自動在容器上下文中查詢和自己物件set方法後面的值對應的beanid;
-->
<bean id="people" class="com.guo.pojo.People" autowire="byName">
<property name="name" value="或玉紅"/>
</bean>
7.2 ByType自動裝配
<!--
byType: 會自動在容器上下文中查詢和自己物件屬性型別相同的bean
-->
<bean id="people" class="com.guo.pojo.People" autowire="byType">
<property name="name" value="或玉紅"/>
</bean>
小結:
- byname的時候,需要保證所有的bean的id唯一,並且這個bean需要和自動注入的屬性的set方法值一致!
- byname的時候,需要保證所有的bean的class唯一,並且這個bean需要和自動注入的屬性的型別一致!
7.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" 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 https://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> </beans>
@Autowired 預設byName方式
-
直接在屬性上使用即可!也可以在set方式上使用!
-
使用Autowired我們可以不用編寫Set方法,前提是這個自動裝配的屬性在IOC(Spring)容器中存在,且符合名字byname
-
如果@Autowired自動裝配的環境比較複雜,自動裝配無法通過一個註解完成的時候,可以使用@Qualifier(value="xxx") 去配置@Autowired的使用,指定一個唯一的bean物件注入!
@Autowired @Qualifier(value = "ccat111") private Cat cat; @Autowired @Qualifier(value = "fsfsf") private Dog dog; private String name;
小結:
@Resource和@Autowired的區別:
- 都是用來自動裝配的,都可以放在屬性欄位上
- @Autowired通過byname的方式實現
- @Resource預設通過byname的方式實現,如果找不到名字,則通過byType實現
-
8、使用註解開發
- 要使用註解開發,必須保證aop的包匯入
- 使用註解需匯入context約束,增加註解的支援!
<?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
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
8.1 bean
@Component 元件,放在類上,說明這個類被Spring管理了,就是Bean
8.2 屬性如何注入
@Component
public class User {
// 方式一
@Value("按最帥")
public String name;
// 方式二
@Value("郭玉紅")
public void setName(String name) {
this.name = name;
}
}
8.3 衍生的註解
@Component有幾個衍生註解,我們在web開發中,會按照mvc三層架構分層!
- dao [@Repository]
- service[@Service]
- controller[@Controller]
8.4 自動裝配註解
8.5 作用域
@Component
@Scope("prototype")
public class User {
// 方式一
@Value("按最帥")
public String name;
// 方式二
@Value("郭玉紅")
public void setName(String name) {
this.name = name;
}
}
8.6 小結
xml與註解:
- xml更加萬能,適合於任何場所!維護簡單方便
- 註解不是自己的類使用不了,維護相對複雜!
xml與註解最佳實踐:
- xml用來管理bean
- 註解只負責完成屬性的注入
- 我們在使用的過程中,只需注意一個問題必須讓註解生效,就需要開啟註解的支援
<!--指定要掃描的包,這個包下的註解就會生效 -->
<context:component-scan base-package="com.guo.pojo"/>
<context:annotation-config/>
9、使用Java的方式配置Spring
完全不使用Spring的xml配置了,全權交給java來做
實體類
@Component
public class User {
private String name;
public String getName() {
return name;
}
@Value("郭玉紅")
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
配置檔案
package com.guo.config;
import com.guo.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* @Date: 2020/11/4
* @author: 王瑞哲
* @version:1.0
*/
@Configuration // 這個也會被Spring容器託管註冊到容器中,因為他本來就是一個@Component 代表這是一個配置類,和之前的xml檔案一致
@ComponentScan("com.guo.pojo")
public class guoConfig {
// 註冊一個bean,就相當於之前寫的一個bean
// 這個方法的名字,就相當於bean標籤的id屬性
// 這個方法的返回值,就相當於bean標籤中的class屬性
@Bean
public User getUser(){
return new User(); // 就是要返回要注入到bean的物件!
}
}
這種純Java的配置檔案,在SpringBoot中隨處可見!
10、AOP(代理模式)
代理模式的分類:
- 靜態代理
- 動態代理
10.1 靜態代理
角色分析:
- 抽象角色:一般會使用介面或者抽象類來解決
- 真實角色:被代理的角色
- 代理角色:代理真實角色,代理後,一般會做一些附屬操作
- 客戶:訪問代理物件的人!
程式碼步驟:
- 介面
// 租房
public interface Rent {
public void rent();
}
-
真實角色
public class Host { public void rent(){ System.out.println("房東要出租房子!"); } }
-
代理角色
public class proxy implements Rent{
private Host host;
public proxy() {
}
public proxy(Host host) {
this.host = host;
}
public void rent(){
seeHoude();
host.rent();
hetong();
}
public void seeHoude(){
System.out.println("中介帶你看房!");
}
public void hetong(){
System.out.println("籤合同!");
}
-
客戶端訪問代理角色
public class Client { public static void main(String[] args) { // 房東要租房了 Host host = new Host(); //代理,中介幫房東租房子,但是代理一般有些附屬操作! proxy proxy = new proxy(host); // 你不用面對房東,直接找中介即可! proxy.rent(); } }
代理模式的好處:
- 可以使真實角色的操作更加純粹!不用去關注一些公共的業務
- 公共業務交給代理角色!實現業務的分工!
- 公共業務發生拓展時,方便集中管理!
缺點:
- 一個真實角色就會產生一個代理角色:程式碼量會翻倍開發效率會降低!
10.2 動態代理
- 動態代理和靜態代理角色一樣
- 動態代理的代理類是動態生成的,不是我們直接寫好的
- 動態代理分為兩大類:基於介面的動態代理,基於類的動態代理
- 基於介面---JDk動態代理
- 基於類:cglib
- java位元組碼實現:javasist
- 一個動態代理類代理的是一個介面,一般對應一類業務
- 一個動態代理可以代理多個類,只要是實現了同一個介面即可
11、AOP
11.1 什麼是AOP
11.2 使用Spring實現Aop
匯入依賴
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
方式一:使用Spring的API介面【主要SpringAPI介面實現】
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 註冊bean -->
<bean id="userService" class="com.kuang.service.UserServiceImpl"/>
<bean id="log" class="com.kuang.log.log"/>
<bean id="afterLog" class="com.kuang.log.afterLog"/>
<!-- 方式一:使用原生SpringApI介面-->
<!--配置aop:需要匯入aop的約束 -->
<aop:config>
<!--切入點:expression: 表示式:execution(要執行的位置!) -->
<aop:pointcut id="pointcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/>
<!--執行環繞增加! -->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
</beans>
方式二:自定義來實現AOP【主要是切面定義】
<!--方式二:自定義類 -->
<bean id="diy" class="com.kuang.diy.DiyPointCut"/>
<aop:config>
<!--自定義切面,ref要引用的類 -->
<aop:aspect ref="diy">
<!--切入點 -->
<aop:pointcut id="point" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/>
<!--通知 -->
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
</aop:aspect>
</aop:config>
方式三:使用註解來實現AOP
12、整合Mybatis
步驟:
-
匯入相關jar包
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.49</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.9.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.6</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.5</version> </dependency> </dependencies>
12.1 回憶mybatis
- 編寫實體類
- 編寫核心配置檔案
- 編寫介面
- 編寫Mapper.xml
- 測試
12.2 Mybatis-spring
- 編寫資料來源配置
- sqlSessionFactory
- sqlSessionTemplate
- 需要給介面加實現類
- 將自己寫的實現類,注入到Spring中
- 測試使用即可
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--DataSource:使用Spring的資料來源替換Mybatis的配置
我們使用這裡Spring提供的JDBC-->
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="wrz485251mysql"/>
</bean>
<!--執行緒池 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="datasource"/>
<!-- 繫結Mybatis配置檔案-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/guo/mapper/UserMapper.xml"/>
</bean>
<!--SqlSessionTemplate:就是我們使用的sqlSession -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!--只能使用構造器注入 sqlSessionFactory,因為它沒有set方法 -->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
<bean id="userMapper" class="com.guo.mapper.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
</beans>
13、宣告式事務
13.1 回顧事務
- 把一組事務當成一個業務來做,要麼都成功,要麼都失敗!
- 事務在專案開發中,十分重要,涉及資料一致性問題
- 確保完整性和一致性
事務ACID原則
-
原子性
-
一致性
-
隔離性
多個業務可能操作同一個資源,防止資料損壞
-
永續性
事務一旦提交,無論系統發生什麼問題,結果都不會再影響,資料被持久化的寫到儲存器中!
13.2 spring中的事務管理
- 宣告式事務:AOP
<!--配置宣告式事務-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--結和AOP實現事務的織入-->
<!--配置事務通知: -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--給哪些方法配置事務 -->
<!--配置事務的傳播特性: -->
<tx:attributes>
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="delete" propagation="REQUIRED"/>
<tx:method name="update" propagation="REQUIRED"/>
<tx:method name="query" read-only="true"/>
</tx:attributes>
</tx:advice>
<!--配置事務切入 -->
<aop:config>
<aop:pointcut id="txPointCut" expression="execution(* com.guo.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
- 程式設計式事務:需要在程式碼中進行事務的管理
為什麼需要事務?
- 如果不配置事務,可能存在資料提交不一致的情況
- 如果不在spring中去配置宣告式事務,就需在程式碼中手動配置事務
- 事務在專案開發中很重要,涉及到資料一致性和完整性問題