天天看點

SSH三大架構知識點 Hibernate其他

Hibernate

****************************************************************************************************

Hibernate工作原理流程?

原理: 1.讀取并解析配置檔案 2.讀取并解析映射資訊,建立SessionFactory 3.打開Session 4.建立事務Transation 5.持久化操作 6.送出事務 7.關閉Session 8.關閉SesstionFactory

為什麼要用Hibernate

為什麼要用: 1. 對JDBC通路資料庫的代碼做了封裝,大大簡化了資料通路層繁瑣的重複性代碼。 2.hibernate是一個基于JDBC的主流持久化架構,是一個優秀的ORM(對象關系映射)實作。他很大程度的簡化DAO層的編碼工作 3. hibernate使用Java反射機制,而不是位元組碼增強程式來實作透明性。 4. hibernate的性能非常好,因為它是個輕量級架構。映射的靈活性很出色。它支援各種關系資料庫,從一對一到多對多的各種複雜關系。

使用Hibernate之前要配置什麼

.使用Hibernate時,先要配置hibernate.cfg.xml檔案,其中配置資料庫連接配接資訊和方言等,還要為每個實體配置相應的hbm.xml檔案,hibernate.cfg.xml檔案中需要登記每個hbm.xml檔案。

使用Hibernate的基本流程是:

配置Configuration對象、産生SessionFactory、建立session對象,啟動事務,完成CRUD操作,送出事務,關閉session。

相對于SQL,HQL查詢語言有什麼特點,什麼是方言? 

答:sql是關系資料庫查詢語言,面對的資料庫;而hql是Hibernate這樣的資料庫持久化架構提供的内置查詢語言,雖然他們的目的都是為了從資料庫查詢需要的資料,但sql操作的是資料庫表和字段,而作為面向對象的hql操作的則是持久化類及其屬性,

****************************************************************************************************

Hibernate架構,對象有三種狀态,分别是什麼,怎樣區分? 

答:Hibernate三種狀态的區分,以及save,update,saveOrUpdHibernate的對象有3種狀态,

分别為:瞬時态(Transient)、持久态(Persistent)、脫管态(Detached)。

1.瞬時對象在記憶體孤立存在,它是攜帶資訊的載體,不和資料庫的資料有任何關聯關系,在Hibernate中,可通過session的save()或saveOrUpdate()方法将瞬時對象與資料庫相關聯,并将資料對應的插入資料庫中,此時該瞬時對象轉變成持久化對象。 

2.持久對象具有如下特點: 1. 和session執行個體關聯; 2. 在資料庫中有與之關聯的記錄。 3. 比瞬時對象多了一個資料庫記錄辨別值。

3.托管态,也叫遊離态等,持久化對象脫離了Session的對象。如Session緩存被清空的對象。特點:已經持久化,但不在Session緩存中。處于此狀态的對象叫遊離對象。

****************************************************************************************************

Hibernate中什麼是延遲加載,延遲的作用是什麼? 

答:延遲加載機制是為了避免一些無謂的性能開銷而提出來的,所謂延遲加載就是當在真正需要資料的時候,才真正執行資料加載操作。在Hibernate中提供了對實體對象的延遲加載以及對集合的延遲加載,另外在Hibernate3中還提供了對屬性的延遲加載。

hibernate進行多表查詢每個表中各取幾個字段,也就是說查詢出來的結果集沒有一個實體類與之對應如何解決;

解決方案一,按照Object[]資料取出資料,然後自己組bean

解決方案二,對每個表的bean寫構造函數,比如表一要查出field1,field2兩個字段,那麼有一個構造函數就是Bean(type1filed1,type2

field2),然後在hql裡面就可以直接生成這個bean了。

第一個:查詢出來的list 轉換為一個數組   

也就是說 Object[]  objects=(Object[]) list    --  你查詢出來的list 集合

for(object  item :objects  ){}進行自行封裝處理 

第二個說白了就是寫個構造函數讓他自己封裝省了自己處理過程了 

但是如果是查詢出來的多張表資料  還是得按第一種方式自己處理的。。。

介紹一下Hibernate的二級緩存

(1)緩存就是把以前從資料庫中查詢出來和使用過的對象儲存在記憶體中(一個資料結構中),這個資料結構通常是或類似Hashmap,當以後要使用某個對象時,先查詢緩存中是否有這個對象,如果有則使用緩存中的對象,如果沒有則去查詢資料庫,并将查詢出來的對象儲存在緩存中,以便下次使用。

(2)Hibernate的Session就是一種緩存,我們通常将之稱為Hibernate的一級緩存,當想使用session從資料庫中查詢出一個對象時,Session也是先從自己内部檢視是否存在這個對象,存在則直接傳回,不存在才去通路資料庫,并将查詢的結果儲存在自己内部。由于Session代表一次會話過程,一個Session與一個資料庫連接配接相關連,是以Session最好不要長時間保持打開,通常僅用于一個事務當中,在事務結束時就應關閉。并且Session是線程不安全的,被多個線程共享時容易出現問題。通常隻有那種全局意義上的緩存才是真正的緩存應用,才有較大的緩存價值,是以,Hibernate的Session這一級緩存的緩存作用并不明顯,應用價值不大。Hibernate的二級緩存就是要為Hibernate配置一種全局緩存,讓多個線程和多個事務都可以共享這個緩存。我們希望的是一個人使用過,其他人也可以使用,session沒有這種效果。

(3)二級緩存是獨立于Hibernate的軟體部件,屬于第三方的産品,多個廠商群組織都提供有緩存産品,例如,EHCache和OSCache等等。在Hibernate中使用二級緩存,首先就要在hibernate.cfg.xml配置檔案中配置使用哪個廠家的緩存産品,接着需要配置該緩存産品自己的配置檔案,最後要配置Hibernate中的哪些實體對象要納入到二級緩存的管理中。明白了二級緩存原理和有了這個思路後,很容易配置起Hibernate的二級緩存。擴充知識:一個SessionFactory可以關聯一個二級緩存,也即一個二級緩存隻能負責緩存一個資料庫中的資料,當使用Hibernate的二級緩存後,注意不要有其他的應用或SessionFactory來更改目前資料庫中的資料,這樣緩存的資料就會與資料庫中的實際資料不一緻。

簡述 Hibernate 和 JDBC 的優缺點? 如何書寫一個 one to many 配置檔案.

Hibernate就是封裝了JDBC,他可以寫一條hql語句,可以再不同資料庫中使用,不用修改hql語句,但是關聯查詢效率低。
JDBC是基礎的連結資料庫的架構,效率高,但是mysql、oracle、sql service等不同的資料庫要寫不同的sql語句。
one to many比如Class和Student吧就是一個班級對應多個學生

在Class類中追加集合屬性 Set<Student> students;
在Class的配置檔案中追加(Class.hbm.xml)
<!-- 追加集合屬性的配置 -->
                               <!-- 設定集合屬性 -->
                               <set name="students" lazy="false" fetch="join" cascade="all" inverse="true">
                                              <!-- 設定關聯字段 -->
                                              <key column="classId" />
                                              <!-- 設定關聯關系 -->
                                              <one-to-many class="Studnet" />
                               </set>
将Studnet中的classId屬性去掉換成 Class class;
在Student的配置檔案中(Student.hbm.xml)
<many-to-one name="class" column="classId" lazy="false" fetch="join"
                                              class="Class">
                               </many-to-one>      

三大架構各起的作用 

struts 在 SSH 架構中起控制的作用 , 其核心是 (控制器)Controller, 即ActionServlet, 而 ActionServlet 的核心就是 Struts-config.xml. 主要控制邏輯關系的處理 .    hibernate 是資料持久化層 , 是一種新的對象、關系的映射工具 , 提供了從 Java 類到資料表的映射,也提供了資料查詢和恢複等機制 , 大大減少資料通路的複雜度。把對資料庫的直接操作 , 轉換為對持久對象的操作 .   

spring 是一個輕量級的控制反轉 (IoC) 和面向切面 (AOP) 的容器架構 , 面向接口的程式設計 , 由容器控制程式之間的(依賴)關系,而非傳統實作中,由程式代碼直接操控。這也就是所謂“ 控制反轉 ” 的概念所在:(依賴)控制權由應用代碼中轉到了外部容器,控制權的轉移,是所謂反轉。依賴注入,即元件之間的依賴關系由容器在運作期決定,形象的來說,即由容器動态的将某種依賴關系注入到元件之中  起到的主要作用是解耦

****************************************************************************************************

整合SSH

把hibernate的配置寫到spring的配置中,用spring管理和調用hibernate的工廠和session等。

struts的話,通常有2中。一種是用spring中的一個工廠類代替struts的工廠類去生成action,并且用spring管理。 另一種是,struts 用自己的工廠生成action,但是由spring管理。這樣耦合低一些。

大概就是這樣,hibernate負責它最擅長的資料庫管理。 struts頁面的請求處理調用相應的底層資料庫等。spring負責管理他們兩個。

****************************************************************************************************

整合SSH的三種方法

方法一:直接獲得ApplicationContext對象

這種方法通過spring擷取與Hibernate相關聯的對象。

關鍵是在Action類中獲得ApplicationContext對象,然後通過getBean方法獲得JavaBean對象。

(1)在hibernate.cfg.xml檔案中配置session-factory

   <session-factory>

      <property name="connection.url">

          jdbc:MySQL://localhost/test?characterEncoding=UTF8

      </property>

      <property name="dialect">

          org.hibernate.dialect.MySQLDialect

      </property>

      <propertyname="connection.username">root</property>

      <propertyname="connection.password">123</property>

      <property name="show_sql">true</property>

      <propertyname="hibernate.hbm2ddl.auto">update</property>

      <property name="connection.driver_class">

          com.mysql.jdbc.Driver

       </property>     

<!—資料庫的實體類映射檔案-->

       <mapping resource="User.hbm.xml" />

   </session-factory>

(2)在applicationContext.xml檔案中對hibernate相關聯的對象使用依賴注入,使用Spring的HibernateTemplate類來對Hibernate的Session進行操作

   <bean id="sessionFactory"       class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

      <property name="configLocation"value="classpath:hibernate.cfg.xml">

      </property>

   </bean>

   <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">

      <property name="sessionFactory"ref="sessionFactory" />

   </bean>

   <!-- 事務攔截器bean需要依賴注入一個事務管理器 -->

   <bean id="transactionManager"

      class="org.springframework.orm.hibernate3.HibernateTransactionManager">

      <property name="sessionFactory">

          <ref bean="sessionFactory" />

      </property>

   </bean>

   <!-- 設定事務傳播特性,對應于AOP中的 <tx:advice />  -->

   <bean id="transactionInterceptor"

      class="org.springframework.transaction.interceptor.TransactionInterceptor">

      <property name="transactionManager">

          <ref bean="transactionManager" />

      </property>

      <property name="transactionAttributes">

          <props>

              <propkey="get*">PROPAGATION_REQUIRED, readOnly

              </prop>

              <propkey="*">PROPAGATION_REQUIRED</prop>

          </props>

      </property>

   </bean>  

    <!-- 定義BeanNameAutoProxyCreator,配置哪些類和哪些方法使用事務對應于AOP中的 <aop:pointcut/> -->  

   <bean

      class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">

      <!-- 指定對滿足哪些bean name的bean自動生成業務代理 -->

      <property name="beanNames">

          <!-- 下面是所有需要自動建立事務代理的bean-->  

          <list>

              <value>userDAO</value>            

          </list>

          <!-- 此處可增加其他需要自動建立事務代理的bean-->

      </property>

      <property name="interceptorNames">

          <!--  下面定義BeanNameAutoProxyCreator所需的事務攔截器-->  

          <list>

             <value>transactionInterceptor</value>

               <!-- 此處可增加其他新的Interceptor-->

          </list>

      </property>

   </bean>  

      <!--配置資料通路層對象-->

   <bean id="userDAO"class="com.dao.UserDAOImpl">

      <constructor-arg>

          <ref bean="hibernateTemplate" />

      </constructor-arg>

   </bean>

      <!--配置業務邏輯層對象-->

   <bean id="userService"class="com.service.UserServiceImpl">

      <constructor-arg>

          <ref bean="userDAO" />

      </constructor-arg>

   </bean>

(3)配置struts.xml檔案

      <action name="loginAction"class="com.test.LoginAction">

          <result name="result">/WEB-INF/result.jsp

          </result>       

      </action>

(4)在Action中擷取userService并使用

          ApplicationContext applicationContext =             WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());

          UserService userService = (UserServiceImpl) applicationContext.getBean("userService");

          userService.addUser(user);

第一種方法的缺點:将Action類魚Spring的裝配JavaBean綁定的過緊,增加了其耦合度,不适合裝配檔案有變化的情況。

方法二:由Spring建立Action類的對象

在方法一的基礎之上需要做如下幾步修改

(1)在Action方法中增加setUserService的方法,把UserService交給spring處理

private UserService userService;

public void setUserService(UserServiceuserService) {

   this.userService = userService;

}

(2)在application.xml檔案中對action進行配置

<bean id=”loginAction”class=”com.test.LoginAction” scope=”prototype”>

   <property name=” userService”>

       <ref bean=” userService”>

   </property>

</bean>

(3)在struts.xml檔案中配置action

<action name=”LoginAction”class=”loginAction”/>

<!—注意這裡class指向的是上面配置的bean對象-->

第二種方法的缺點:雖然使用了Spring的IOC特性,對Action和ApplicationContext對象進行了解耦,但配置一個Action需要同時維護兩份檔案:struts.xml和application.xml,比較難維護。

方法三:直接使用Spring的自動裝配JavaBean的特性進行整合

       在方法一的配置基礎上進行如下修改

(1)編寫UserAction類,在UserAction中添加setUserService方法,讓spring自動裝配

private UserService userService;

public void setUserService(UserServiceuserService) {

   this.userService = userService;

}

(2)直接在Struts中配置LoginAction

<action name=”LoginAction”class=”com.test.LoginAction”/>

由于已經在application.xml檔案中裝配了userService屬性,這樣spring就可以自動裝配LoginAction中的UserService了。

*****************************************************************************************************************************

其他

j2ee常用的設計模式?說明工廠模式。

總共23種,分為三大類:建立型,結構型,行為型

我隻記得其中常用的6、7種,分别是:

建立型(工廠、工廠方法、抽象工廠、單例)

結構型(包裝、擴充卡,組合,代理)

行為(觀察者,模版,政策)

然後再針對你熟悉的模式談談你的了解即可。

工廠模式:

工廠模式是一種經常被使用到的模式,根據工廠模式實作的類可以根據提供的資料生成一組類中某一個類的執行個體,通常這一組類有一個公共的抽象父類并且實作了相同的方法,但是這些方法針對不同的資料進行了不同的操作。首先需要定義一個基類,該類的子類通過不同的方法實作了基類中的方法。然後需要定義一個工廠類,工廠類可以根據條件生成不同的子類執行個體。當得到子類的執行個體後,開發人員可以調用基類中的方法而不必考慮到底傳回的是哪一個子類的執行個體。

單例模式

在它的核心結構中隻包含一個被稱為單例類的特殊類。通過單例模式可以保證系統中一個類隻有一個執行個體而且該執行個體易于外界通路,進而友善對執行個體個數的控制并節約系統資源。如果希望在系統中某個類的對象隻能存在一個,單例模式是最好的解決方案。

轉載于:https://www.cnblogs.com/liuzhenping/p/7726314.html