1. 程式人生 > 實用技巧 >mysql基礎-進階三【排序查詢】

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的原型

  1. 控制反轉:物件A獲得依賴物件B的過程,由主動行為變為了被動行為,控制權顛倒過來了。
  2. 依賴注入:所謂依賴注入,就是由IOC容器在執行期間,動態地將某種依賴關係注入到物件之中。

3、IOC建立物件的方式

  1. 使用無參構造建立物件,預設!

  2. 假設使用有參構造建立物件

    • 下標賦值

       <!--有參創造 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物件中的所有屬性,由容器注入!
    1. 複雜型別

      public class Address {
          private String addrerss;
      
          public String getAddrerss() {
              return addrerss;
          }
      
          public void setAddrerss(String addrerss) {
              this.addrerss = addrerss;
          }
      }
      
    2. 真實測試物件

      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;
              }
      
    3. 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>
      
    4. 測試類

      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());
      
          }
      }
      
      
    5. 完善注入資訊

      <?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"/>
  1. 原型模式: 每次從容器中get的時候,都會產生一個新物件!

<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>
  1. 其餘的request、session、application 這些只能在web開發中使用到!

7、Bean的自動裝配

  1. 在xml中顯式的裝配
  2. 在java中顯式裝配
  3. 隱式的自動裝配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 使用註解實現自動裝配

使用註解須知:

  1. 匯入約束

  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"
        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 靜態代理

角色分析:

  • 抽象角色:一般會使用介面或者抽象類來解決
  • 真實角色:被代理的角色
  • 代理角色:代理真實角色,代理後,一般會做一些附屬操作
  • 客戶:訪問代理物件的人!

程式碼步驟:

  1. 介面
//  租房
public interface Rent {
    public void rent();

}
  1. 真實角色

    public class Host {
        public void rent(){
            System.out.println("房東要出租房子!");
        }
    }
    
  2. 代理角色

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("籤合同!");
    }


  1. 客戶端訪問代理角色

    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

步驟:

  1. 匯入相關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

    1. 編寫實體類
    2. 編寫核心配置檔案
    3. 編寫介面
    4. 編寫Mapper.xml
    5. 測試

12.2 Mybatis-spring

  1. 編寫資料來源配置
  2. sqlSessionFactory
  3. sqlSessionTemplate
  4. 需要給介面加實現類
  5. 將自己寫的實現類,注入到Spring中
  6. 測試使用即可
<?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&amp;useUnicode=true&amp;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中去配置宣告式事務,就需在程式碼中手動配置事務
  • 事務在專案開發中很重要,涉及到資料一致性和完整性問題