SSH框架學習心得
1 . Hibernate
學習心得:
hibernate是一個輕量級的封裝了jdbc的框架,主要使用xml和註解的方式來配置ORM。
如果要使用hibernate,首先要配置hibernate.cfg.xml.
<hibernate-configuration>
<session-factory>
<!-- 資料庫的連線配置 -->
<property name="connection.url">jdbc:mysql://localhost:3306/mlx?USESSL=false</property >
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<!--表結構的生成策略,create為不保留資料每次都生成新的表結構,
updata會保留資料 -->
<property name="hbm2ddl.auto">update</property>
<!--是否顯示sql語句-->
<property name="hibernate.show_sql">true</property>
<!--是否格式化sql語句 -->
<property name="format_sql">true</property>
<!-- 用於對映實體類 -->
<mapping resource="com/mlx/test2/Worker.hbm.xml"/>
<mapping resource="com/mlx/test2/Project.hbm.xml"/>
</session-factory>
</hibernate-configuration>
sessionfactory是用來獲得session的,其中session是用來對資料庫進行各種操作的。
使用方法是:
//載入hibernate.cfg.xml配置文件
Configuration configure = new Configuration().configure();
//用配置文件開啟session工廠,然後通過工廠獲得session物件
//這裡有兩種方法獲得session,第一個是沒有一級快取的,第二個是有一級快取的。
session = configure.buildSessionFactory().openSession();
//session=configure.buildSessionFactory().getCurrentSession();
//開啟一個事務,所有的操作必須開啟事務,提交以後方可以寫到資料庫中
transaction = session.beginTransaction();
在這裡,得有個實體類對應資料庫中的表,而對映的方式首先講第一種,xml的方式:
<hibernate-mapping>
<!--name必須為完整地包名 table為資料庫中對應的表-->
<class name="com.mlx.test.Grade" table="Grade" schema="mlx">
<!--id後的name物件類中的屬性,column中的name對應表中的欄位 -->
<id name="gid">
<column name="gid" sql-type="int(11)"/>
<!--主鍵生成策略 -->
<generator class="increment"/>
</id>
<property name="name">
<column name="name" sql-type="varchar(255)" not-null="true"/>
</property>
<!--一對多關係的配置 name為類中的list集合 table為類中list中屬性的型別
對應的表,cascade為級聯操作,意思就是當它有變化時,是否自動更新所對應表
中的資料,選擇all為所有的變化都更新,選擇detele為刪除時才更新
-->
<set name="studentSet" table="student" cascade="all">
<!--這裡的column對應的是 確定關聯的外來鍵列 也就是student表中的外來鍵欄位
-->
<key column="gid"></key>
<!--對應的是list集合泛型中的實現類 -->
<one-to-many class="com.mlx.test.Student"/>
</set>
<!--這裡只是做一下student表中的演示,name為實體類中的屬性,class為屬性對應的類,column為對應的外來鍵欄位 -->
<many-to-one name="grade" class="com.mlx.test.Grade" column="gid"/>
</class>
</hibernate-mapping>
以上是對映檔案,其中有一對多和多對一的關係,此處是班級的對映檔案,而下面的many-to-one為學生表中的配置,班級中有list< Student>集合用來標識學生,而學生表中有grade屬性用來標識班級。對於關係還有一個就是多對多的關係,多對多的關係也很常見,這裡使用工程和工人來舉例子,講解配置:
<hibernate-mapping>
<class name="com.mlx.test2.Project" table="Project">
<id name="pid" column="pid" type="java.lang.String">
<generator class="assigned"/>
</id>
<property name="name" column="name" type="java.lang.String"/>
<!--workers是project實體類中工人集合 table對應的表為第三方表
在多對多的關係中,一般採用第三方表來對應關係
-->
<set name="workers" table="prowork" cascade="all">
<!--這裡的column對應的是第三方表中對應的外來鍵欄位,不過這個欄位用的是
project的id,意思就是project類的主鍵
-->
<key column="rpid"></key>
<!--這裡的class對應的是實體類中集合所對用的型別,而且必須為完整包名
這裡的column對應的是第三方表中的欄位,且為工人的欄位
-->
<many-to-many class="com.mlx.test2.Worker" column="rwid"/>
</set>
</class>
</hibernate-mapping>
這裡在set標籤中還有一個inverse屬性,用於標識由哪一方來維護關係,設定為true後,就是由對方來維護關係,其實理解為關係的擁有者更為簡單。
2 . Struts2
我理解的struts2框架就像一個servlet,使用者發出請求到action,action根據需要返回字串,在result中根據返回的字串跳轉頁面。
這裡面關於請求引數的賦值問題,模型驅動:
手動例項化JavaBean,即:private User user = new User();
必須實現ModelDriven介面,實現getModel()的方法,在getModel()方法中返回user即可!!
1. 封裝複雜型別的引數(集合型別 Collection 、Map介面等)
2. 需求:頁面中有可能想批量新增一些資料,那麼現在就可以使用上述的技術了。把資料封裝到集合中
3. 把資料封裝到Collection中
因為Collection介面都會有下標值,所有頁面的寫法會有一些區別,注意:
< input type=”text” name=”products[0].name” />
在Action中的寫法,需要提供products的集合,並且提供get和set方法。
- 把資料封裝到Map中
Map集合是鍵值對的形式,頁面的寫法
< input type=”text” name=”map[‘one’].name” />
Action中提供map集合,並且提供get和set方法
動態方法呼叫:不能一個actio只有一個execute方法,所有有萬用字元的方法呼叫:
- 使用萬用字元的方式可以簡化配置檔案的程式碼編寫,而且擴充套件和維護比較容易。
- 具體例項如下:
- 頁面程式碼
< a href="${pageContext.request.contextPath}/order_add.action">新增訂單</ a>
< a href="${pageContext.request.contextPath}/order_delete.action">刪除訂單</a>
* 配置檔案程式碼
<action name="order_*" class="cn.itcast.demo2.OrderAction" method="{1}"></action>
* Action的程式碼
public String add(){
System.out.println("新增訂單");
return NONE;
}
public String delete(){
System.out.println("刪除訂單");
return NONE;
}
* 具體理解:在JSP頁面傳送請求,http://localhost/struts2_01/order_add.action,配置檔案中的order_*可以匹配該請求,*就相當於變成了add,method屬性的值使用{1}來代替,{1}就表示的是第一個*號的位置!!所以method的值就等於了add,那麼就找到Action類中的add方法,那麼add方法就執行了!
3 Spring框架
Spring框架最主要的三個功能:IOC(控制反轉),DI(依賴注入),AOP(面向切面程式設計),同時IOC和DI是一起使用的。
IOC控制反轉,意思就是將物件new的權力交給spring框架來做,我們只需要通過框架來獲得物件即可。
DI,依賴注入,當A中有B類的時候,在XML檔案中配置好以後,在A中可以直接得到B
AOP,對類的增強,即可以在不修改程式碼的情況下,對類進行增強。
<bean id="temp" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="data"/>
</bean>
在application.xml檔案中配置,如果有屬性可以在下面使用。ref的意思就是引用別的bean,或者value。
程式碼:
public void test1(){
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
Product bean = context.getBean("pro",Product.class);
bean.pro();
}
首先載入xml檔案,然後通過name/id和類型別來獲得物件,然後呼叫物件的方法
AOP:
1. Joinpoint(連線點) – 所謂連線點是指那些被攔截到的點。在spring中,這些點指的是方法,因為spring只支援方法型別的連線點
2. Pointcut(切入點) – 所謂切入點是指我們要對哪些Joinpoint進行攔截的定義
3. Advice(通知/增強) – 所謂通知是指攔截到Joinpoint之後所要做的事情就是通知.通知分為前置通知,後置通知,異常通知,最終通知,環繞通知(切面要完成的功能)
4. Introduction(引介) – 引介是一種特殊的通知在不修改類程式碼的前提下, Introduction可以在執行期為類動態地新增一些方法或Field
5. Target(目標物件) – 代理的目標物件
6. Weaving(織入) – 是指把增強應用到目標物件來建立新的代理物件的過程
7. Proxy(代理) – 一個類被AOP織入增強後,就產生一個結果代理類
8. Aspect(切面) – 是切入點和通知的結合,以後咱們自己來編寫和配置的
這裡得引入spring的約束頭資訊,並且在xsi:schemaLocation中,必須成對出現。例如:
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
這裡引入的就是aop和context(用註解)了。
這裡是切面配置的方法:
<!--
配置目標類
<bean id="pro" class="com.mlx.test.Product"></bean>
配置自定義的切面
<bean id="logaspect" class="com.mlx.test.MyAcept"></bean>
切面配置
<aop:config>
引入的切面名稱
<aop:aspect ref="logaspect">
定義通知型別和切點,method為定義通知的方法
<aop:around method="log" pointcut="execution(* com.mlx.test.*.*(..))"/>
</aop:aspect>
</aop:config>
-->
關於切面型別,這裡有這麼幾種:
1. 前置通知
* 在目標類的方法執行之前執行。
* 配置檔案資訊:
* 應用:可以對方法的引數來做校驗
最終通知
- 在目標類的方法執行之後執行,如果程式出現了異常,最終通知也會執行。
- 在配置檔案中編寫具體的配置:
- 應用:例如像釋放資源
後置通知
- 方法正常執行後的通知。
- 在配置檔案中編寫具體的配置:
- 應用:可以修改方法的返回值
異常丟擲通知
- 在丟擲異常後通知
- 在配置檔案中編寫具體的配置:
- 應用:包裝異常的資訊
環繞通知
- 方法的執行前後執行。
- 在配置檔案中編寫具體的配置:
- 要注意:目標的方法預設不執行,需要使用ProceedingJoinPoint對來讓目標物件的方法執行。
關於切點的表示式為:再配置切入點的時候,需要定義表示式,重點的格式如下:execution(public * *(..)),具體展開如下:
* 切入點表示式的格式如下:
* execution([修飾符] 返回值型別 包名.類名.方法名(引數))
* 修飾符可以省略不寫,不是必須要出現的。
* 返回值型別是不能省略不寫的,根據你的方法來編寫返回值。可以使用 * 代替。
* 包名例如:com.itheima.demo3.BookDaoImpl
* 首先com是不能省略不寫的,但是可以使用 * 代替
* 中間的包名可以使用 * 號代替
* 如果想省略中間的包名可以使用 ..
* 類名也可以使用 * 號代替,也有類似的寫法:*DaoImpl
* 方法也可以使用 * 號代替
* 引數如果是一個引數可以使用 * 號代替,如果想代表任意引數使用 ..
關於使用註解的方式來配置bean,首先要在xml檔案中開啟註解掃描:
<context:component-scan base-package="com.mlx.test" />
paceage屬性的意思就是掃描哪些包下的類
在java類中編寫註解:
@Component(value="pro")
public class Product {
public void pro(){
System.out.println("pro");
}
}
屬性注入的註解(說明:使用註解注入的方式,可以不用提供set方法)
* 如果是注入的普通型別,可以使用value註解
* @Value – 用於注入普通型別
* 如果注入的是物件型別,使用如下註解
* @Autowired -- 預設按型別進行自動裝配
* 如果想按名稱注入
* @Qualifier -- 強制使用名稱注入
* @Resource -- 相當於@Autowired和@Qualifier一起使用
* 強調:Java提供的註解
* 屬性使用name屬性
Bean的作用範圍註解
- 註解為@Scope(value=”prototype”),作用在類上。值如下:
- singleton – 單例,預設值
- prototype – 多例 在strtus中應該設定action為多例
- 註解為@Scope(value=”prototype”),作用在類上。值如下:
Bean的生命週期的配置(瞭解)
- 註解如下:
- @PostConstruct – 相當於init-method
- @PreDestroy – 相當於destroy-method
- 註解如下:
使用註解進行切面程式設計:
@Aspect
@Component
public class MyAcept {
@Around(value="execution(* com.mlx.test.*.*(..))")
public void log(ProceedingJoinPoint point){
System.out.println("記錄日誌1");
try {
point.proceed();
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("記錄日誌2");
}
}
在xml檔案中設定自動代理:
<aop:aspectj-autoproxy/>
在Sring中經常會使用到事務的方式來操作資料庫,最最常見的就是轉賬,必須要用到事務,這裡提供基於配置檔案面向切面的開啟事務方法和使用註解面向切面開啟事務方法:
技術分析之Spring框架的JDBC模板技術概述
- Spring框架中提供了很多持久層的模板類來簡化程式設計,使用模板類編寫程式會變的簡單
提供了JDBC模板,Spring框架提供的
- JdbcTemplate類
Spring框架可以整合Hibernate框架,也提供了模板類
- HibernateTemplate類
技術分析之使用Spring框架來管理模板類
- 剛才編寫的程式碼使用的是new的方式,應該把這些類交給Spring框架來管理。
- 修改的步驟如下
- 步驟一:Spring管理內建的連線池
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring_day03"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
* 步驟二:Spring管理模板類
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
- 步驟三:編寫測試程式
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo2 {
@Resource(name="jdbcTemplate")
private JdbcTemplate jdbcTemplate;
@Test
public void run2(){
jdbcTemplate.update("insert into t_account values (null,?,?)", "測試2",10000);
}
}
技術分析之Spring框架管理開源的連線池
管理DBCP連線池
先引入DBCP的2個jar包
- com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar
- com.springsource.org.apache.commons.pool-1.5.3.jar
編寫配置檔案
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring_day03"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
管理C3P0連線池
先引入C3P0的jar包
- com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar
編寫配置檔案
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql:///spring_day03"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
</bean>
技術分析之Spring框架的事務管理相關的類和API
- PlatformTransactionManager介面 – 平臺事務管理器.(真正管理事務的類)。該介面有具體的實現類,根據不同的持久層框架,需要選擇不同的實現類!
- TransactionDefinition介面 – 事務定義資訊.(事務的隔離級別,傳播行為,超時,只讀)
TransactionStatus介面 – 事務的狀態
總結:上述物件之間的關係:平臺事務管理器真正管理事務物件.根據事務定義的資訊TransactionDefinition 進行事務管理,在管理事務中產生一些狀態.將狀態記錄到TransactionStatus中
PlatformTransactionManager介面中實現類和常用的方法
介面的實現類
- 如果使用的Spring的JDBC模板或者MyBatis框架,需要選擇DataSourceTransactionManager實現類
- 如果使用的是Hibernate的框架,需要選擇HibernateTransactionManager實現類
該介面的常用方法
- void commit(TransactionStatus status)
- TransactionStatus getTransaction(TransactionDefinition definition)
- void rollback(TransactionStatus status)
TransactionDefinition
事務隔離級別的常量
- static int ISOLATION_DEFAULT – 採用資料庫的預設隔離級別
- static int ISOLATION_READ_UNCOMMITTED
- static int ISOLATION_READ_COMMITTED
- static int ISOLATION_REPEATABLE_READ
- static int ISOLATION_SERIALIZABLE
事務的傳播行為常量(不用設定,使用預設值)
先解釋什麼是事務的傳播行為:解決的是業務層之間的方法呼叫!!
PROPAGATION_REQUIRED(預設值) – A中有事務,使用A中的事務.如果沒有,B就會開啟一個新的事務,將A包含進來.(保證A,B在同一個事務中),預設值!!
- PROPAGATION_SUPPORTS – A中有事務,使用A中的事務.如果A中沒有事務.那麼B也不使用事務.
PROPAGATION_MANDATORY – A中有事務,使用A中的事務.如果A沒有事務.丟擲異常.
PROPAGATION_REQUIRES_NEW(記)– A中有事務,將A中的事務掛起.B建立一個新的事務.(保證A,B沒有在一個事務中)
- PROPAGATION_NOT_SUPPORTED – A中有事務,將A中的事務掛起.
PROPAGATION_NEVER – A中有事務,丟擲異常.
PROPAGATION_NESTED(記) – 巢狀事務.當A執行之後,就會在這個位置設定一個儲存點.如果B沒有問題.執行通過.如果B出現異常,執行客戶根據需求回滾(選擇回滾到儲存
另外注意,spring是面向介面程式設計,所有定義的都應該是介面,然後注入的是實現類。
技術分析之搭建事務管理轉賬案例的環境(強調:簡化開發,以後DAO可以繼承JdbcDaoSupport類)
步驟一:建立WEB工程,引入需要的jar包
- IOC的6個包
- AOP的4個包
- C3P0的1個包
- MySQL的驅動包
- JDBC目標2個包
- 整合JUnit測試包
步驟二:引入配置檔案
引入配置檔案
- 引入applicationContext.xm
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql:///spring_day03"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
</bean>
步驟三:建立對應的包結構和類
* com.itheima.demo1
* AccountService
* AccountServlceImpl
* AccountDao
* AccountDaoImpl
- 步驟四:引入Spring的配置檔案,將類配置到Spring中
<bean id="accountService" class="com.itheima.demo1.AccountServiceImpl">
</bean>
<bean id="accountDao" class="com.itheima.demo1.AccountDaoImpl">
</bean>
步驟五:在業務層注入DAO ,在DAO中注入JDBC模板(強調:簡化開發,以後DAO可以繼承JdbcDaoSuppor
<bean id="accountService" class="com.itheima.demo1.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
<bean id="accountDao" class="com.itheima.demo1.AccountDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
步驟六:編寫DAO和Service中
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
public void outMoney(String out, double money) {
this.getJdbcTemplate().update("update t_account set money = money = ? where name = ?", money,out);
}
public void inMoney(String in, double money) {
this.getJdbcTemplate().update("update t_account set money = money + ? where name = ?", money,in);
}
}
- 步驟七:編寫測試程式.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo1 {
@Resource(name="accountService")
private AccountService accountService;
@Test
public void run1(){
accountService.pay("mlx", "zy", 1000);
}
}
Spring框架的事務管理之基於AspectJ的XML方式(重點掌握)
步驟一:恢復轉賬開發環境
步驟二:引入AOP的開發包
步驟三:配置事務管理器
<!-- 配置事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
- 步驟四:配置事務增強
<!-- 配置事務增強 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--
name :繫結事務的方法名,可以使用萬用字元,可以配置多個。
propagation :傳播行為
isolation :隔離級別
read-only :是否只讀
timeout :超時資訊
rollback-for:發生哪些異常回滾.
no-rollback-for:發生哪些異常不回滾.
-->
<!-- 哪些方法加事務 -->
<tx:method name="pay" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
- 步驟五:配置AOP
!-- 配置AOP切面產生代理 -->
<aop:config>
<aop:advisor advice-ref="myAdvice" pointcut="execution(* com.itheima.demo2.AccountServiceImpl.pay(..))"/>
</aop:config>
注意:如果是自己編寫的切面,使用< aop:aspect>標籤,如果是系統製作的,使用< aop:advisor>標籤。
- 步驟六:編寫測試類
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class Demo2 {
@Resource(name="accountService")
private AccountService accountService;
@Test
public void run1(){
accountService.pay("冠希", "美美", 1000);
}
}
Spring框架的事務管理之基於AspectJ的註解方式(重點掌握,最簡單的方式)
步驟一:恢復轉賬的開發環境
步驟二:配置事務管理器
<!-- 配置事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
- 步驟三:開啟註解事務
<!-- 開啟註解事務 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
步驟四:在業務層上新增一個註解:@Transactional
編寫測試類
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext3.xml")
public class Demo3 {
@Resource(name="accountService")
private AccountService accountService;
@Test
public void run1(){
accountService.pay("冠希", "美美", 1000);
}
}
關於SSH框架整合問題,我學完再來寫!