1. 程式人生 > 其它 >33 _ 腦裂:一次奇怪的資料丟失

33 _ 腦裂:一次奇怪的資料丟失

Spring概述

Spring介紹

  • EJB(面向元件程式設計), jboss,Spring是一個分層的Java SE/EE(web) full-stack(一站式)輕量級開源框架,以 IoC(Inversion Of Control:反轉控制)和 AOP(Aspect Oriented Programming:面向切面程式設計)為核心。

  • 一站式(一條龍,全家桶):Spring可以通過任何javaEE方向的開發支援

  • 輕量級:當前的框架對硬體的要求不高,容易上手,容易使用

  • 開源

  • 無縫連線:整合目前市面上使用javaEE開發技術

  • 在java三層架構當中分別提供了相應激素

    • 表現層(web層):SpringMVC(框架)
    • 業務層(service層):Bean管理(IOC容器)
    • 持久層(dao層):JdbcTemplate模板以及提供了ORM模組整合其他優秀的持久層技術

Spring框架的優勢(高內聚 低耦合)

  • 方便解耦,簡化開發:Spring就一個大工廠,可以管理的所有物件的建立和依賴關係維護,交給Spring管理(池子概念)
  • AOP程式設計的支援:可以方便的實現對程式進行許可權攔截,日誌記錄,執行監控
  • 宣告式事務的支援:通過配置方式完成對事務的管理,無需手動程式設計
  • 整合外邊優秀技術:Spring內部提供了各種優秀框架(Hibernate,Mybatis,Quartz javamial 等)的直接支援
  • javaEE技術的封裝:Spring對javaEE開發當中複雜難用的API(JavaEmail, RMI等)進行封裝,降低了這些API的使用難度

程式的耦合和解耦

程式的耦合

  • 程式的耦合是程式之間的關聯性,也就是多個類的聯絡是否緊密,多個物件之間的關係是否密切。
  • 寫程式的目標是:高內聚 低耦合

解決程式耦合

  • 編譯不依賴,執行時依賴

  • 使用工廠模式解耦合

    • 在實際開發中可以把三層的物件都使用配置檔案配置起來,當啟動伺服器應用載入的時候,讓一個類中的方法通過讀取配置檔案,把物件創建出來並存起來。

SpringIOC機制詳解

IOC概述及作用

  • IOC簡介,設計思想

    • SpringIOC:IOC 是 Inversion of Control 的縮寫,翻譯成“控制反轉”,“控制反向”或者“控制倒置”。
    • 控制:Spring框架提供了一個容器控制java開發中的物件
    • 正轉:洗車-->使用者主動的去將車交給洗車店玩車個清洗 (沒有ioc機制)
    • 反轉:洗車--> 洗車店的工作人員 上門洗車服務(接收容器給我們的物件內容)
  • IOC作用

    • IOC本質上就是一個大工程,大容器。主要作用就是建立和管理物件的依賴關係,削減計算機程式的耦合(解決程式碼中的依賴關係),提高程式的可拓展性和可維護性

SpringIOC機制詳解

  • SpringIOC入門案例

Spring基於XML的IOC細節

  • IOC配置檔案詳解:配置標籤書寫規範,配置標籤的屬性

    • bean標籤:用於配置物件交給Spring來建立
      預設情況下會呼叫類中無參的構造器,如果沒有無參構造器,則不能成功建立
    • 基本屬性:id: Bean例項物件在Spring容器當中的唯一標識
      class:Bean的全限定類名

手動實現自己的IOC容器

  • bean類

    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    /**
     * @author: ChengLong
     * @version: 11.0.2
     * @datetime: 2021/9/16 13:58
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Student {
        private Integer StuId;
        private String StuName;
    }
    
    
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    /**
     * @author: ChengLong
     * @version: 11.0.2
     * @datetime: 2021/9/16 14:00
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Teacher {
        private Integer TeaId;
        private String TeaName;
    }
    
  • spring配置檔案

    <?xml version="1.0" encoding="UTF-8"?>
    <beans>
        <bean id="student" class="com.offcn.bean.Student"></bean>
    
        <bean id="teacher" class="com.offcn.bean.Teacher"></bean>
    </bea
    
  • pom.xml配置檔案

    <?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>om.offcn</groupId>
        <artifactId>spring02</artifactId>
        <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.18</version>
        </dependency>
    </dependencies>
    
    </project>
    
  • ApplicationContextDao

    
    /**
     * @author: ChengLong
     * @version: 11.0.2
     * @datetime: 2021/9/16 14:43
     */
    public interface ApplicationContext {
        public Object getBean(String name);
    }
    
    
  • ClassPathXmlApplicationContext

    import org.dom4j.Document;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * @author: ChengLong
     * @version: 11.0.2
     * @datetime: 2021/9/16 14:43
     */
    public class ClassPathXmlApplicationContext implements ApplicationContext {
        Map<String,Object> map = new HashMap<>();
    
        public ClassPathXmlApplicationContext(String path)  {
    
            //解析過程發生在構造器中
            /**
             * 1.構建解析器
             * 2.解析指定位置的xml檔案
             * 3.獲取根標籤
             * 4.獲取子標籤
             * 5.獲取子標籤的屬性
             * 6.通過反射生成屬性對應物件
             * 7.將物件放入集合中
             */
            try {
                SAXReader reader =new SAXReader();
                //解析配置檔案,將檔案構成dom物件
                Document document = reader.read(path);
                //根標籤
    
                Element rootElement = document.getRootElement();
    //            System.out.println(rootElement.getName());
                List<Element> bean = rootElement.elements("bean");
                for (Element one :bean){
                    String id = one.attributeValue("id");
                    String aClass = one.attributeValue("class");
                    //反射
                    Object instance = Class.forName(aClass).newInstance();
                    //放入集合
                    map.put(id,instance);
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        @Override
        public Object getBean(String name) {
            return map.get(name);
        }
    }
    
    

Spring管理bean細節

  • bean例項化介紹

    • 容器管理物件的詳細的過程(new 物件過程)
  • bean例項化方式

    • 構造方法的方式
    • 靜態工廠方式
  • bean作用域

    • bean作用域介紹

      • 所謂Bean的作用域其實就是指Spring給創建出的物件的存活範圍,在配置檔案中通過bean的scope屬性指定

      • scope:指物件的作用範圍

        • 子主題 1
    • bean作用域的解析

      • 當scope的取值為singleton時,單例

        • Bean的例項化個數:1個
        • Bean的例項化時機:當Spring核心檔案被載入時,例項化配置的Bean例項
      • 當scope的取值為prototype時,多例

        • Bean的例項化個數:多個
        • Bean的例項化時機:當呼叫getBean()方法時例項化Bean

Spring依賴注入(容器給屬性賦值)

依賴注入的介紹

  • 依賴注入(Dependency Injection):它是 Spring 框架核心 IOC 的具體實現。
  • 依賴:servlet依賴service才能完成自己的功能
  • 注入:依賴的service物件,容器給程式進行賦值(在程式的執行期間容器將管理的service的物件載入到servlet程式中)
  • 通過控制反轉,把物件的建立交給了 Spring,但是程式碼中不可能出現沒有依賴的情況。
    IOC 解耦只是降低他們的依賴關係,但不會消除。
    坐等框架把持久層物件傳入業務層

Spring中依賴注入方式

  • 建構函式注入

        <!--    構造器注入-->
        <bean id="person" class="com.offcn.bean.Person">
            <constructor-arg name="pid" value="12"></constructor-arg>
            <constructor-arg name="pname" value="admin"></constructor-arg>
            <!--       ref:屬性的值必須是容器管理的物件-->
            <constructor-arg name="dog" ref="newdog"></constructor-arg>
        </bean>
    
    
  • setter注入

     <!--    通過物件set方法屬性值注入-->
    <bean id="newperson" class="com.offcn.bean.Person">
            <property name="pid" value="11"></property>
            <property name="pname" value="user"></property>
            <property name="dog" ref="newdog"></property>
    </bean>
    
  • 注入集合資料

    <!--        陣列注入-->
            <property name="myStrs">
                <array>
                    <value>red</value>
                    <value>green</value>
                    <value>blue</value>
                </array>
            </property>
    
            <!--        list注入-->
            <property name="myList">
                <list>
                    <ref bean="newdog"></ref>
                    <bean class="com.offcn.bean.Dog">
                        <property name="did" value="004"></property>
                        <property name="fuColor" value="blue"></property>
                    </bean>
                </list>
            </property>
    
            <!--        set集合-->
            <property name="mySet">
                <set>
                    <value>張三</value>
                    <value>趙六</value>
                    <value>王五</value>
                </set>
            </property>
    
            <!--        map集合注入-->
            <property name="myMap">
                <map>
                    <entry>
                        <!--                    鍵-->
                        <key>
                            <value>a</value>
                        </key>
                        <!--                    值-->
                        <value>李四</value>
                    </entry>
                    <entry>
                        <key>
                            <value>a</value>
                        </key>
                        <value>李四2</value>
                    </entry>
                </map>
            </property>
            <!--props注入-->
            <property name="myProps">
                <props>
                    <prop key="username">root</prop>
                    <prop key="password">123</prop>
                </props>
            </property>
    

Spring配置檔案模組化

Spring模組化介紹

  • 現在的配置都集中配在了一個applicationContext.xml檔案中,當開發人員過多時, 如果所有bean都配 置到同一個配置檔案中,會使這個檔案巨大,而且也不方便維護。 針對這個問題,Spring提供了多配置檔案的方式,也就是所謂的配置檔案模組化

Spring模組化配置

  • Spring模組化配置方式一

    • 並列的多個配置檔案 直接編寫多個配置檔案,比如說beans1.xml,beans2.xml......, 然後在建立ApplicationContext的時候,直接傳入多個配置檔案。

      ApplicationContext context = new ClassPathXmlApplicationContext("spring-dog.xml","spring-person.xml");
      
  • Spring模組化配置方式二

     <import resource="classpath:spring-dog.xml"></import>
    
    • 注意:
      同一個xml檔案中不能出現相同名稱的bean,如果出現會報錯
      多個xml檔案如果出現相同名稱的bean,不會報錯,但是後加載的會覆蓋前載入的bean,所以企業開發中盡 量保證bean的名稱是唯一的。

Spring整合JDBC實現使用者CRUD

整合思路分析

  • Spring提供了ioc容器,管理jdbc操作資料庫的過程中需要的資料庫連線物件,同時Spring提供了整合jdbc操作資料庫的工具類JdbcDaoSupport 和模板工具 JdbcTemplate,在JdbcTemplate中提供了大量的操作資料庫的方式供使用者使用。所以我們只需要獲取模板工具類然後呼叫方法就可以完成Jdbc的操作了。

pojo

/**
 * @author: ChengLong
 * @version: 11.0.2
 * @datetime: 2021/9/16 20:43
 */
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
    private Integer p_id;
    private String p_name;
}

dao

import com.offcn.pojo.Person;

/**
 * @author: ChengLong
 * @version: 11.0.2
 * @datetime: 2021/9/16 16:38
 */
public interface PersonDao {
    public int addPerson(Person person);
}

介面實現

import com.offcn.pojo.Person;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * @author: ChengLong
 * @version: 11.0.2
 * @datetime: 2021/9/16 16:45
 */
public class PersonDaoImpl implements PersonDao {
    //資料庫互動方法必須依賴一個物件 jdbcTemplate
    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public int addPerson(Person person){
        String sql = "insert into person(p_id,p_name) values(?,?)";
        int updata = jdbcTemplate.update(sql,person.getP_id(),person.getP_name());
        return updata;
    }
}

servicedao

import com.offcn.pojo.Person;

/**
 * @author: ChengLong
 * @version: 11.0.2
 * @datetime: 2021/9/16 20:48
 */
public interface PersonService {
    public boolean savePerson(Person person);
}

service

import com.offcn.dao.PersonDao;
import com.offcn.pojo.Person;

/**
 * @author: ChengLong
 * @version: 11.0.2
 * @datetime: 2021/9/16 20:48
 */
public class PersonServiceImpl implements PersonService {

    private PersonDao personDao;

    public void setPersonDao(PersonDao personDao) {
        this.personDao = personDao;
    }

    @Override
    public boolean savePerson(Person person) {
        return personDao.addPerson(person)>0;
    }
}

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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--管理一切java物件-->
    <bean id="service" class="com.offcn.service.PersonServiceImpl">
        <property name="personDao" ref="pdao"></property>
    </bean>
<!--    dao物件-->
    <bean id="pdao" class="com.offcn.dao.PersonDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate"></property>
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--        操作資料庫的工具類,在操作資料庫過程中使用資料庫連線-->
        <constructor-arg name="dataSource" ref="ds"></constructor-arg>
    </bean>

<!--    容器管理的資料來源物件-->
    <bean id="ds" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="username" value="root"></property>
        <property name="password" value="1s2h3a4o56789"></property>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://192.168.196.181:3306/0622db"></property>
    </bean>
</beans>

測試

import com.offcn.dao.PersonDao;
import com.offcn.pojo.Person;
import com.offcn.service.PersonService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author: ChengLong
 * @version: 11.0.2
 * @datetime: 2021/9/16 20:52
 */
public class SpringJdbc {

    @Test
    public void test1(){
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-core.xml");
        PersonDao personDao = (PersonDao) context.getBean("pdao");
        Person person = new Person();
        person.setP_id(12);
        person.setP_name("武松");
        PersonService personService = (PersonService) context.getBean("service");
        boolean b = personService.savePerson(person);
        if(b){

        }else{

        }
    }
}