ssh

基礎增強(反射)

枚舉(瞭解)

私有化有參和無參的構造方法,用於多選一html

enum Grade{java

         A("90-100"),B("80-90"),C("70-80"),D("60-70"),E("<60");mysql

        

         private String score;web

         private Grade(String score){正則表達式

                   this.score=score;算法

         }spring

         public String toString() {sql

                   return "Grade [score=" + score + "]";數據庫

         }express

}

等同於在普通類裏進行公有化的new對對象

public static Grade A = new Grade("90-100");

         public static Grade B = new Grade("80-90");

         public static Grade C = new Grade("70-80");

         public static Grade D = new Grade("60-70");

         public static Grade E = new Grade("<60");

反射(重點)

概念

java世界裏的萬物皆對象。

讀取類的過程:  由類加載器(ClassLoader)讀取class字節碼文件,把字節碼文件的信息讀取進內存,就會被構形成一個Class對象,利用Class對象去構造對象,調用方法,給屬性賦值或獲取屬性值等等操做,這個過程就是反射!!

不經過new獲取類對象

Class stu = Class.forName(輸入完整包名);   //推薦經常使用

Class stu = Student.class;   類名+class

Class stu = new Student().getClass();

Class對象,表明一個類

getName()    //獲取完整包名加類名

                   getSimpleName()  //獲取類名

                   getSuperClass()    //獲得普通父名

                   getGenericSuperClas()  //獲得泛型父名

                   getInterfaces()  //獲得普通類的接口名

                   getGenericIntefaces();    //獲得泛型接口

getDeclaredConstructor(輸入屬性名可多個)  //沒輸入就是獲得無參,有輸入就是獲得有參

getDeclareMethod(輸入get set方法,輸入類型+class)  //能夠拿到get 、set方法

getDeclareField(輸入成員屬性名)   //能夠獲得成員屬性

Constructor對象:表明一個構造方法

                            newInstance()   獲取構造對象

Method對象: 表明一個普通方法

                            invoke(obj,參數值)  調用方法

Filed對象:表明一個屬性         

                            set(obj,參數)  賦值

                            get(obj)   獲取值

Type         對象:全部類型的公共高級接口

GenericArrayType   數組類型子接口

ParameterizedType   參數類型子接口(經常使用)

TypeVariable<D>    變量的子接口

WildcardType   通用的子接口

泛型

用處:把運行時異常轉化爲編譯時異常,減小類型轉換。

泛型語法

                   泛型方法(*)

                            public <T> T method(T t){

 

                            }                          

                  

                   好處:爲了寫出通用方法

        

                   泛型類/泛型接口

 

                            public class Demo<T>{

 

                            }

 

                   好處:爲了減小泛型方法的聲明

 

?:  任意類型,爲了保證泛型語法的完整性

 

extends: 當前類型或者當前類型的子類   向下取

 

super: 當前類型或者當前類型的父類    向上取

 

組合使用:(List<? super Number> list)  

 

泛型+反射

getGenericSuperClass()   //獲取dao的泛型父列:BaseDao<Student>

 

應用:反射+泛型寫出通用代碼

 

//用於抽取業務dao的通用方法

//規則:表名稱和類名保存一致(大小寫不區別)

public class BaseDao<T> {

         private Class targetClass;//須要封裝的類型

         private String tableName;//須要查詢的表名稱

        

         //在BaseDao中如何接收泛型類?

         public BaseDao(){

                  //System.out.println(this.getClass());// this: StudentDao 或者TeacherDao

                  

                   Class clz = this.getClass();//當前運行的dao:StudentDao

                   Type type = clz.getGenericSuperclass();//獲取dao的泛型父列:BaseDao<Student>

                   ParameterizedType pt = (ParameterizedType)type;//類型轉換:轉換成參數化類型的子類

                   Type[] tps = pt.getActualTypeArguments();  // 取出參數化類型的參數:<Student>

                   targetClass = (Class)tps[0]; // 取出第一個參數: Student.class

                  

                   //表名

                   tableName = targetClass.getSimpleName().toLowerCase();

         }

        

        

         QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());

         public List<T> findAll(){

                   try {

                            return qr.query("select * from "+tableName+"", new BeanListHandler(targetClass));

                   } catch (SQLException e) {

                            e.printStackTrace();

                            throw new RuntimeException(e);

                   }

         }

        

         public T findById(int id){

                   try {

                            return (T)qr.query("select * from "+tableName+" where id=?", new BeanHandler(targetClass),id);

                   } catch (SQLException e) {

                            e.printStackTrace();

                            throw new RuntimeException(e);

                   }

         }

}

 

 

Struts2框架

struts2概念

         struts2是一個基於MVC思想的表現層框架!!!

         struts2的底層來源於另外一個表現層框架webwork  (xwork-core.jar)      

         struts2是struts1+webwork的整合框架

步驟1)struts2的jar包(最少)
commons-fileupload-1.3.1.jar  【上傳組件】

commons-io-2.2.jar      【上傳組件】

commons-lang3-3.2.jar    【字符串處理工具類】

freemarker-2.3.22.jar    【freemarker框架包】

javassist-3.11.0.GA.jar  【字節碼處理工具類】

ognl-3.0.6.1.jar          【ognl表達式的支持包】

struts2-core-2.3.24.3.jar  【struts2自身的支持包】

xwork-core-2.3.24.3.jar   【wbeworkd框架的支持包】

步驟2)在web.xml中配置struts2的過濾類

org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter(在導入包中)

配置內容:

<web-app version="2.5"

         xmlns="http://java.sun.com/xml/ns/javaee"

         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

         http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

        

  <display-name></display-name>        

  <filter>

       <filter-name>struts2</filter-name>

         <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>

  </filter>

  <filter-mapping>

       <filter-name>struts2</filter-name>

       <url-pattern>/*</url-pattern>

  </filter-mapping>

 </web-app>

步驟3)寫一個業務邏輯操做類

         Public class XXXX(){

                   Public String xxx(){

         (內容)

}

}

步驟4)寫一個struts.xml配置文件(核心)

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE struts PUBLIC

         "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"

         "http://struts.apache.org/dtds/struts-2.3.dtd">

         

<struts>

         <!-- struts-default:不要修改 /: 不要修改-->

                                                                         繼承包名須要加後綴分辨

         <package name="(任意名字)" extends="struts-default" namespace="/">  //包名

                                       能夠用通配符*或*_*

<action name="(任取:路徑訪問名)" class="(完整包名)" method="(方法名)"> //類名

                                            方法返回名一致          能夠多個方法

<result name="success" type="redirect">/index.jsp</result> //方法名

                   </action>

         </package>

        

</struts>

 

Struts2執行流程

項目啓動:

                   1)建立StrutsPrepareAndExecuteFilter核心過濾器對象

                   2)調用StrutsPrepareAndExecuteFilter的init方法

                             init_DefaultProperties();  讀取default.properties (常量文件)

                                                                 (or/apache/struts2/default.properties)

                             init_TraditionalXmlConfigurations() 讀取struts的核心xml配置文件

                                     struts-default.xml   struts2的默認配置文件 (業務功能的聲明)

                                     struts-plugin.xml   struts2的插件配置文件

                                     **struts.xml**      struts2的核心流程的配置文件(自行修改的)

每次發出請求(訪問資源):

                   1)調用StrutsPrepareAndExecuteFilter的doFilter方法

                   2)根據用戶的請求uri在struts.xml文件的內容匹配對應的action

                   3)建立一個action配置的class的類對象(Action類對象)

                   4)調用Action類對象的指定的method方法

                   5)返回一個視圖的字符串

                   6)根據視圖的字符串查找匹配的result

                   7)跳轉到具體的result的路徑

解讀struts-default.xml

業務功能聲明文件

<result-types>

                            經常使用的視圖類型:

                            dispatcher: 轉發頁面

                            redirect:重定向頁面

                            chain: 轉發到Action

                            redirectAction:重定向到Action   (內容寫另外一個Action的name屬性)

                            stream: 用於文件下載的  

                   </result-types>                 

攔截器(重要的概念)

在struts.xml配置中如何引用攔截器

<action name="demo" class="cn.itcast.interceptor.ActionDemo" method="admin">

                   <interceptor-ref name="(打包攔截器名)"></interceptor-ref> //引用打包後的攔截器

                   <result>/uploe.jsp</result>

</action>

//全局使用攔截器

<default-interceptor-ref name="(打包攔截器名)"></default-interceptor-ref>

                            攔截器效果相似於過濾器

 

                            攔截器 vs 過濾器

 

                            過濾器:是servlet的組件,用於過濾請求和響應

                            攔截器:是struts2的組件,只能用於攔截action

                   -->

                   <interceptors>

                            com.opensymphony.xwork2.interceptor.ParametersInterceptor:參數攔截器

                            org.apache.struts2.interceptor.FileUploadInterceptor:文件上傳攔截器

                            com.opensymphony.xwork2.interceptor.I18nInterceptor:國際化攔截器

                            .......

                   </interceptors>

建立攔截器類一個普通類繼承MethodFilterInterceptor也能夠繼承AbstractInterceptor類

public class HelloInterceptor extends MethodFilterInterceptor{

         //執行業務邏輯方法:doIntercept相似Filter的doFilter方法

         //ActionInvocation相似Filter的FilterChain

         @Override

         protected String doIntercept(ActionInvocation invocation) throws Exception {

                   System.out.println("1.執行攔截器的前面代碼");

                   /**

                    * 放行:

                    * 調用下一個攔截器,或者是目標的action

                    */

                   invocation.invoke();

                   System.out.println("3.執行攔截器的後面代碼");

                   return null;

         }

Struts.xml中配置攔截器(在package包中)

<interceptors>

 

<interceptor name="(自定義攔截器的名字)" class="(完整包名)"></interceptor> //引用攔截器

 

<interceptor-stack name="(輸入任意攔截器名字)">  //至關於打包攔截器

                            <!-- 引用攔截器 -->

         <interceptor-stackname="defaultStack"></interceptor-ref> //默認18個攔截器

<interceptor-ref name="(與自定義攔截器名字一致才能使用)"></interceptor-ref> 

</interceptor-stack>

 

<interceptors>

Struts2常量配置

Struts2項目啓動時加載default.properties常量文件
struts.i18n.encoding: struts2項目中設置的編碼

                                     請求:request.setCharacterEncoding("utf-8")

                                     響應: response.setContentType("text/html;charset=utf-8");

struts.multipart.parser: struts2使用的上傳組件 (默認jakarta:commons-fileUpload)

struts.multipart.saveDir: 文件上傳時緩存目錄

struts.multipart.maxSize: 文件上傳文件當前請求最大值

struts.action.extension    struts2的action訪問後綴配置

struts.devMode   是否打印對象信息

struts.enable.DynamicMethodInvocation: 是否開啓struts2的動態方法調用機制(默認關閉)

動態方法調用機制,用來簡化action的配置,可使用一個action配置來實現多個方法的調用注意:struts2不推薦開啓,由於存在必定的安全漏洞!測試代碼的時候能夠開啓使用!

修改(覆蓋)struts常量

在struts.xml配置文件中添加

<constant name=」 struts.i18n.encoding」 value=」utf-8」></constant>

<!-- 修改struts的UI模塊 -->

         <constant name="struts.ui.theme" value="simple"></constant> //設置爲簡單模式把所有el表達式替代成ognl表達式

配置全局視圖(包裏面,action外面)對當前包下面的全部action起做用的

<global-results>

         <result>/succ.jsp</result>

</global-results>

Acation讀取參數

1:在方法內私有化須要接收的數據提供get和set的方法,至關於getParameter()方法

private String savePath;

public void setSavePath(String savePath) {

                   this.savePath = savePath;

}

2:在方法內私有化對象提供get和set方法,jsp頁面數據前面必須帶對象(經常使用)

用戶名:<input type="text" name="type.name"></br>

  密碼:<input type="password" name="type.password"></br>

3:方法實現一個ModelDriven<對象名>接口,私有化對象必須new,而後讓方法等於對象

private Type types=new Type();

@Override

         public Type getModel() {

                   return types;   (返回私有對象)

         }

上傳圖片讀取

表單的3 個必要條件

1:<input type="file" name="attach"/>

2:<form enctype="multipart/form-data" method="post">  //post提交 重寫enctype

在方法裏寫出如下私有方法接收,提供get和set方法

private String savePath;  //文件傳輸的過去的地址

public String getSavePath() {

                   return savePath;

         }

public void setSavePath(String savePath) {

         this.savePath = savePath;

}

 

Struts.xml 配置

<param name="savePath">F:/金山打字通/</param>  //須要複製過去的地址

 

//1.接收上傳的文件

private File attach;            //<input type="file/>的name屬性名稱

//2.接收文件類型

private String attachContentType;  //名稱:name屬性+ContentType

//3.接收文件名稱

private String attachFileName;  //名稱:name屬性+FileName

 

文件上傳細節配置

<!-- 修改文件上傳攔截器參數 -->

                            <interceptor-ref name="fileUpload">   //默認的不能寫錯

                            <!-- 修改最大文件大小參數:1M -->

                            <param name="maximumSize">1048576</param>

                            <!-- 修改容許的文件類型 -->

                            <param name="allowedTypes">image/jpeg,image/x-png,image/bmp</param>

                            </interceptor-ref>

<!-- 必須放在後面,由於先修改了fileUpload文件上傳 攔截器的參數,再進行默認攔截器-->

下載文件

Struts.xml中如何配置文件(下載文件所有爲配置)

<action name="down" class="gz.itcast.a_down.DownAction" method="down">

                            <!-- 配置下載視圖 :stream-->

                            <result name={自定義名稱}" type="(屬性爲下載)stream">

                                     <!-- 修改視圖的參數 -->

                                     <!-- 下載的文件類型 :設置通用二進制類型-->

                                     <param name="contentType">application/octet-stream(所有格式)</param>

                                     <!-- 下載提示框 ${fileName}:讀取Action中的getFileName()方法 -->

                            <param name="contentDisposition">attachment;filename=${fileName}</param>

                                     <!-- 設置下載的緩存區大小 -->

                                     <param name="bufferSize">512(不改默認1024)</param>

                                     <!-- 須要下載的文件輸入流: Action中的getter方法名稱 -->

                                     <param name="inputName">fileStream(getInput方法)</param>                

                            </result>

                   </action>

Action中如何寫方法

public class DownAction extends ActionSupport{

         //private InputStream fileStream;

        

         private String fileName;

         //下載方法

         public String down(){

                   //返回下載視圖

                   return "down";

         }

        

         //給struts.xml的inputName配置

         public InputStream getFileStream() throws Exception{

                   File file = new File("E:/圖片/1-111119121254.jpg");

                   fileName = file.getName();

                   return new FileInputStream(file);

         }

        

         //經過getter方法把名稱輸出給struts.xml文件

         public String getFileName() throws Exception{

                   return URLEncoder.encode(fileName,"utf-8");   //若是圖片有中文名字

         }

}

 

國際化(瞭解)及自定義異常

struts2國際化

         原理

                   com.opensymphony.xwork2.interceptor.I18nInterceptor 國際化攔截器

                  

         步驟:

                   在struts.xml文件中配置國際化資源文件的路徑

 

                   <!-- 加載國際化資源文件 -->

         <constant name="struts.custom.i18n.resources" value="i18n.message"></constant>

 

                   在jsp頁面使用struts2標籤引用國際化文件內容

 

jsp頁面使用: <s:text name="user"/>       

action使用: getText("key")   (注意:前提Action繼承ActionSupport)

 

自定義異常

                                                                                                         包名只能用點

<constant name="struts.custom.i18n.resources" value="cn.itcast.list.message"></constant>

在struts.xml中「input」是報錯配置

<result name="input">/actionList.jsp</result>

傳輸數據給頁面

1:使用原生的域對象進行共享                

request,session,application

                  //獲得域對象

HttpServletRequest request = ServletActionContext.getRequest();

HttpSession session = request.getSession();

ServletContext application = ServletActionContext.getServletContext();

2:使用三種Map集合共享數據

RequestMap:從新封裝了HttpServletRequest

SessionMap: 從新封裝了HttpSession

ApplicationMap: 從新封裝了ServletContext

 

ActionContext類:工具類                      

                           

//先獲得ActionContext對象

//RequestMap

ActionContext ac = ActionContext.getContext();

Map requestMap = (Map)ac.get("request");

requestMap.put("r_prods", prods);

//System.out.println(requestMap.getClass());

                  

//SessionMap

Map sessionMap = ac.getSession();

sessionMap.put("s_prods", prods);

                  

//ApplicationMap

Map applicationMap = ac.getApplication();

applicationMap.put("a_prods", prods);

3:經過實現接口的方法使用三種Map集合(推薦)

私有化3個map<String,Object>參數

在Action類上面實現三個接口

RequestAware,   SessionAware,     ApplicationAware

寫出get 和set方法

public class BaseAction extends ActionSupport implements RequestAware,SessionAware,ApplicationAware{

   public Map<String, Object> requestMap;

   public Map<String, Object> sessionMap;

   public Map<String, Object> applicationMap;

 

值棧和ognl表達式

值棧

Struts2改變servlet+jsp

Action -> 把數據保存到*值棧*  -> jsp  -> 使用struts2標籤+ognl表達式

值棧是struts2存取數據的核心

值棧是一個對象,這個對象實現接口 ValueStack

                   實現類:OgnlValueStack

值棧分爲兩個部分:

1:對象棧(Object Stack): ArrayList集合

                            做用:存放struts2運行過程的action對象,國際化對象.....

2:映射棧(Context (Map) Stack): HashMap集合

                            做用:存在struts2運行過程的固定的映射數據

                            存放的映射數據:

                            key               value             

                            ===============================

                            request          RequestMap對象(封裝request域對象)

                            session          SessionMap對象(封裝session域對象)

                            application      ApplicationMap對象(封裝context域對象)

                            parameters       ParametersMap對象(封裝用戶參數數據)

                            attr             AttributeMap對象(封裝三個Map集合)

                                                        (request : RequestMap

                                                        session: SessionMap

                                                        application: ApplicationMap)

獲取值棧:

struts2框架在運行每一個Action的方法前都會建立一個值棧對象。把這個值棧對象放入ActionContext對象中。

                   運行Action的方法 -> 建立值棧對象 -> 放入到ActionContext對象中 -> 執行代碼

ActionContext ac = ActionContext.getContext();

ValueStack vs = ac.getValueStack();  //獲取值棧

操做值棧

                   push(Object o) :壓棧

                   pop(): 推棧

                  往Action添加一個屬性:提供一個getter方法

操做映射棧

ValueStack.getContext().put("key",Object) 往映射棧添加一個元素

                    操做requestMap

                   Map rm = (Map)ac.get("request");

                   rm.put("rm", p);

                   //2.3 往session元素(SessionMap)添加一個元素

                   Map sm = ac.getSession();

                   sm.put("sm", p);

                   //2.4 往application元素(ApplicationMap)添加一個元素

                   Map am = ac.getApplication();

                   am.put("am", p);

ognl表達式

ognl表達式須要藉助struts標籤:<s:property value="ognl表達式"/>

取對象棧: 不帶#號的ognl表達式

查詢對象棧的對象順序:

從棧的指定元素位置開始查詢對應,直到棧底(最後一個元素)爲止,把全部元素返回。

                                    

                            取某個對象: [0]   (取對象棧的第一個元素後面的元素)

                            取某個對象的屬性:[0].name    (注意:查詢getName()方法) 

                            name  默認就是從第一個元素開始查屬性

取映射棧: 帶#號的ognl表達式

                            取映射棧的request的元素:#request.product

                            取映射棧的session的元素:#session.product

                            取映射棧的application的元素:#application.product

                            取映射棧的paraemters的元素:#parameters.product

                            取映射棧的attr的元素:

                                     #attr.request

                                     #attr.session

                                     #attr.application

Struts標籤

Struts邏輯標籤

數據標籤:

                            <s:set/>   賦值到值棧中

                            <s:property/> 從值棧獲取數據

條件判斷:

                            <s:if>

                            <s:elseif>

                            <s:else>

循環:

                            <s:iterator>  //相似迭代器

Ui類標籤

用於簡化頁面的html輸出

                   表單標籤:

<s:form>   

<s:textfield/> //就是input輸入框 type=」text」

<s:password/>  //相似input輸入密碼type=」password」

 

<s:radio/>   

 

<s:checkbox/>    //存單個的多選框

 

//能夠存集合的多選框(以Map集合存儲進去,id鍵,對象爲值)

<s:checkbostlist list="#request.types" name="types" listKey="key" listValue="value.name" value="curTypes"/>

 

//下拉框

<s:select list="#request.types" listKey="key" listValue="value.name"  value="curTypes"/>

Action傳輸內容

private List curTypes;

         public List getCurTypes() {

                   curTypes = new ArrayList();

                   curTypes.add(2);

                   curTypes.add(3);

                   return curTypes;

         }

         public void setCurTypes(List curTypes) {

                   this.curTypes = curTypes;

         }

        

         //查詢

         public String query(){

                   Map<Integer,Types> types = new HashMap<Integer,Types>();

                   types.put(1,new Types(1,"圖書類"));

                   types.put(2,new Types(2,"男裝"));

                   types.put(3,new Types(3,"電器類"));

                   requestMap.put("types", types);

                  

                  

                   return "tags";

         }

表單驗證

步驟:

(瞭解)方法1:Action必須繼承actionSupport類,覆蓋重寫validate方法,裏面驗證信息和頁面數據一致

方法2:配置

把一個驗證文件(Action名稱-validation.xml)放在對應Action的目錄下

內容:

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.dtd">

<validators>

         <!-- struts2提供了一些經常使用的屬性驗證器

                   requiredstring: 必須填寫字符串

                   regex: 正則表達式

                   email: 郵箱格式驗證器

         -->

         <!-- field:須要驗證的字段 -->

         <field name="user.name">   //頁面數據

                   <!-- 屬性驗證器 -->

                   <field-validator type="requiredstring">

                            <!-- 錯誤發生時,錯誤提示 -->

                            <message>用戶名必須填寫2222</message> //input錯誤提示語句

                   </field-validator>

         </field>

 

         <field name="user.name">

                   <!-- 屬性驗證器 -->

                   <field-validator type="regex">

                            <param name="regexExpression">[a-zA-Z0-9]{4,16}</param> //正則

                            <!-- 錯誤發生時,錯誤提示 -->

                            <message>用戶名格式有誤:4-16位字母或者數字222</message>

                   </field-validator>

         </field>

        

         <field name="user.email">

                   <!-- 屬性驗證器 -->

                   <field-validator type="requiredstring">

                            <!-- 錯誤發生時,錯誤提示 -->

                            <message>郵箱必須填寫2222</message>

                   </field-validator>

         </field>

</validators>

注意

Xml配置文件的注意事項:

1)Action名稱-validation.xml對Action的全部方法生效!

2)若是須要局部驗證Action某個方法:Action名稱-方法訪問名-validation.xml

注意:若是有錯誤,則調用addFieldError放入錯誤信息,struts2會自動跳轉到input視圖

 

必須在struts.xml配置一個input的視圖(不然報錯)    

                   <action name="user_*" class="gz.itcast.a_validate.UserAction" method="{1}">

                            <result>/succ.jsp</result>

                            *<result name="input">/user.jsp</result>*

                   </action>

Jsp:頁面顯示錯誤信息

                   <s:fielderror></s:fielderror>

 

Hibernate框架

Orm 思想(對象關係映射)

關係領域(關係型數據)   對象領域(java)    

             一張表               一個類

             一個字段             類的一個屬性

            一條記錄              一個類的對象

啓動步驟

1:導包

1)hibernate的lib裏面的required目錄的10個jar

2)對應數據庫的驅動程序*

 

2:編寫hibernate的啓動配置文件(包括數據庫鏈接信息)

在src目錄創建一個hibernate.cfg.xml

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE hibernate-configuration PUBLIC

         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

         "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

 

<hibernate-configuration>

 

<session-factory>

<!-- 第一部分:數據庫鏈接信息 -->

<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/day31?useUnicode=true&amp;characterEncoding=utf-8</property>

<property name="hibernate.connection.username">root</property>

<property name="hibernate.connection.password">root</property>

                  

<!-- 2.第二部分:hibernate環境參數配置 -->

<!-- 數據庫方言 : hiberbate最終轉換成什麼數據庫的sql語句-->

<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>

        

<!-- 3.第三部分:映射文件信息 -->

<mapping resource="gz/itcast/entity/Student.hbm.xml"/>  //相似struts2配置

        

</session-factory>

</hibernate-configuration>

 

3:編寫實體類javabean(必須有無參構造)

 

4:建立關係型映射文件(一般把 對象.hbm.xml文件放在和實體類同目錄)

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

         "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

         "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

 

<hibernate-mapping>  //底下若是單類名就要加個package="(包名)"           表名

                   <class name="gz.itcast.entity.Student(完整類名,也能夠單類名)" table="t_student">

                            <!-- 主鍵配置 -->

                            <id name="id" column="sid">

                                     <!-- 主鍵維護策略 :

                                               assigned:程序分配id

                                     -->

                                     <generator class="assigned"></generator> 

                            </id>

                            <property name="name" column="sname"></property>

                            <property name="age" column="sage"></property>

                   </class>

</hibernate-mapping>   

                                                                                                               

 

5:代碼部分(主要獲取對象) 能夠寫一個hibernateUtil.java工具包

//1.獲取Session對象

                   //1.1 加載hibernate.cfg.xml文件

                   Configuration config = new Configuration().configure();

                  

                   //1.2 建立一個服務註冊器(4.0新特性)

StandardServiceRegistry serviceRegistry =

                                     new StandardServiceRegistryBuilder().applySettings(config.getProperties()).build();

                  

                   //1.3 建立SessionFactory對象

                   SessionFactory sessionFactory =config.buildSessionFactory(serviceRegistry);

                  

                   //1.4 獲取一個Session

                   Session session = sessionFactory.openSession();

                  

                   //注意:hibernate強制使用事務

                   //開啓事務

                   session.getTransaction().begin();

                  

                   執行操做xxxxx

                  

                   //提交事務

                   session.getTransaction().commit();

 

                   //發生錯誤回滾事務 try /catch

                   session.getTransaction().rollback();

 

                   注意關閉資源

                   session.close();

                   sessionFactory.close();

 

hibernate.cfg.xml配置

<hibernate-configuration>  

                   <session-factory>  -- 鏈接一個數據庫的項目信息

 

                            第一部分: 鏈接參數

                            <property name="hibernate.connection.driver_class"></property>

                            <property name="hibernate.connection.url"></property>

                            <property name="hibernate.connection.username"></property>

                            <property name="hibernate.connection.password"></property>        

 

                            第二部分:hibernate環境參數

hibernate.dialect: 數據庫方言。爲了hibernate適應不一樣的數據庫,方便生成不一樣數據庫                        例如:sql語句核心包: org.hibernate.dialect.MySQL5InnoDBDialect

 

                            <property name="(寫入底下語句)"></property>

                            hibernate.show_sql: 是否顯示執行sql語句(方便測試而已) //值:true

                            hibernate.format_sql: 是否格式化sql語句(方便測試而已) //值:true

                            hbm2ddl.auto: 是否須要hibernate維護數據庫。默認不維護

                                         值:create:  每次會自動建立表結構

                                         值:  update: 每次會更新(先對比)表結構

                                      

                            第三部分:對象關係映射文件

                            <mapping resource="(hibernate.hbm.xml 完整包名)"/>

*.hbm.xml解讀配置(核心)

第一種:配置文件注入

<hibernate-mapping>

                   package: 類所在的包

                   <class>   -- 表明須要映射一個類

                            name:  表明映射類名(若是沒有配置package,必須寫全名)

                            table: 表明須要映射到的表名

 

                            <id name="(實體ID)" column="(對應表單ID)">  表明主鍵配置

                                     <generator class="assigned">  主鍵維護策略

 

<property  name=」屬性名稱」 column=」字段名稱」 length=」字段長度」>  表明普通屬性映射

第二種:註解注入(經常使用)

Hibernate註解

概念:

hibernate註解是代替xml配置的另外一個參數配置方案

步驟:

1:在實體類指定位置上指定註解

2:在hibernate.cfg.xml加入映射類 <mapping class="gz.itcast.b_annotation.Product(實體類)"/>

常見註解:

@Entity          聲明當前類是一個映射類  (若是須要映射的類必須加)

         @Table(name="t_product", indexes={@Index(columnList="NAME", name="IDX_USER_NAME")}(增長索引值在查詢時會比較快))    聲明表名 (能夠省略不寫,表與實體屬性名一致)

@Table(name="OA_ID_USER(表名)", indexes={@Index(columnList="NAME", name="IDX_USER_NAME")})

         @Id     聲明主鍵

+@GeneratedValue(strategy=GenerationType.AUTO)(能夠選擇誰負責增加AUTO表明自動選擇)    聲明註解維護策略    默認數據庫生成id值

 

@Column(name="p_id",length=」指定字段長度」)    聲明字段名   

 

         @OneToMany(cascade={CascadeType.ALL},mappedBy="user")  一對多

        

@ManyToOne(fetch=FetchType.LAZY(是否延遲加載,必須填), targetEntity=User.class(關聯的實現化類))  多對一

         +@JoinColumn(name="MODIFIER(取外鍵列的列名)", referencedColumnName="USER_ID(引用主表的那個主鍵列名)", foreignKey=@ForeignKey(name="FK_DEPT_MODIFIER")(更改外鍵約束名,不寫的話自動生成))

         @JoinColumn(name="MODIFIER", referencedColumnName="USER_ID",

         foreignKey=@ForeignKey(name="FK_DEPT_MODIFIER"))

 

@ManyToMany(fetch=FetchType.LAZY(懶加載), targetEntity=Role.class(須要引用的實習化類), mappedBy="users(中間表由角色來維護,沒加表明本身維護)")  多對多

   +@JoinTable(name="OA_ID_USER_ROLE(多對多須要生成外表,外表的名字)", joinColumns=@JoinColumn(name="ROLE_ID(沒有加mappedBy的列名)", referencedColumnName="ID(須要關聯的主鍵id)"),                                                 inverseJoinColumns=@JoinColumn(name="USER_ID(加了mappedBy的列名)", referencedColumnName="USER_ID(須要關聯的主鍵id)"))

 

@JoinTable(name="OA_ID_USER_ROLE", joinColumns=@JoinColumn(name="ROLE_ID", referencedColumnName="ID"),                inverseJoinColumns=@JoinColumn(name="USER_ID", referencedColumnName="USER_ID"))

                 

@OneToOne  一對一

        

         @Temporal(TemporalType.TIMESTAMP)指定數據庫爲時間格式,TIMESTAMP(年月日時分秒)

Session對象基本CRUD操做

1:保存save

session.save(放入存儲的對象)

2:修改數據get拿set直接改

Product p = (Product)session.get(Product.class, 2);   //對象.class和對應ID號

修改數據

p.setName("iphone6s");

3:查詢get數據

Product p = (Product)session.get(Product.class, 1);   //get一調用就執行

 

Product p = (Product)session.load(Product.class, 1);  //調用不執行,須要才執行

Hql語句

List<Product> list = session.createQuery("from Product p").list();

                   for (Product product : list) {

                            System.out.println(product);}

4:刪除delete

Product p = new Product();

         p.setId(1);

         session.delete(p);

        

方式二:(推薦)

Product p = (Product)session.get(Product.class, 1);

if(p!=null){

         session.delete(p);

         }

主鍵維護策略

<generator class="assigned"></generator>

開發者:

                   assigned    開發者自覺給

         數據庫:(類型必須是int或Integer)

                   identity  利用自增加策略,只能用在mysql或者sql server

                   sequence  利用序列增加策略,只能在oracle或者db2

                   *native (推薦)自動根據具體的數據庫增加策略,選擇最優的一個

         hibernate:

                   *increment:hibernate的自增加策略   (每次先查表的最大id值,而後+1)(int)

                   uuid:  hibernate提供的uuid算法策略   (String)

hibernate.hbm.xml映射不一樣類型

         type="integer"

 

                            hibernate類型         java類型      

         *整數        int/integer       java.lang.Integer

         *小數         double         java.lang.Double            

         *字符                   string         java.lang.String

         *日期                   date          java.util.Date

         字符文件       text          java.lang.String

         字節文件      binary                 byte[]

集合映射

Set集合映射

<set name="實體類set名" table="對應表名">

                            <!-- 外鍵 -->

                            <key column="uid"></key> //外鍵的id

                            <!-- 集合裏面元素的字段 -->

                            <element column="address" type="string"></element> //string小寫

                   </set>

List集合映射

<list name="實體類set名" table="對應表名">

                            <!-- 外鍵 -->

                            <key column="uid"></key>

                            <!-- 排序索引自動 -->

                            <index column="任意名"></index>

                            <element column="任意名" type="string"></element>

                   </list>

Map集合映射

<map name="實體類set名" table="對應表名">

                            <!-- 外鍵 -->

                            <key column="uid"></key>

                            <!-- map的key字段 key值,map主鍵 -->

                            <map-key type="string" column="任意名"></map-key>

                            <!-- map的value字段 -->

                            <element column="任意名" type="string"></element>

                   </map>

對象關係映射

一對多單向

例子

對象:這個對象有其餘對象信息        這個沒有

                   class User{                class Address{

                            int id;                                 int id;

                            String name;                 String name;

                            int age;                String zipcode;

                            *Set<Address>*                  String phone;

                                                                  String address;

                   }       

Hibernate.hbm.xml配置映射

         <!-- set對象集合(一對多) -->

                   <set name="實體類set集合名字">

                            <!-- 外鍵 -->

                            <key column="uid"></key>

                            <!-- set集合元素:Address對象 -->

<one-to-many class="gz.itcast.c_one2many_single.Address(完整全名)" />//一對多關鍵語句

                   </set>

級聯映射  在set里加個cascade="all " 所有自動更新

<set name="實體類set集合名字" cascade="all ">

save-update:  當保存/更新會員(User)的數據時,同時保存/更新起關聯的收貨地址

delete : 當刪除會員(User)的數據時,同時刪除起關聯的收貨地址(Address)對象

all: save-update + delete

多對一單向

對象: 這沒有外面實體信息           關聯了外面實體信息

                   class User{                  class Address{

                            int id;                                  int id;

                            String name;               String name;

                            int age;                 String zipcode;

                                                              String phone;

                                                                   String address;

                                                                   *User user;*  

                   }

Hibernate.hbm.xml配置映射

<many-to-one name="實體名user" class="gz.itcast.many2one_single.User(完整包名)"

                            column="uid(另個實體id值)" cascade="all" (自動)></many-to-one>

一對多及多對多雙向

一對多(多對一)雙向

                   <!-- 一對多集合映射 -->

                   <set name="(set實體名) " cascade="all" inverse =」true」>

                            <!-- 外鍵 -->

                            <key column="(外鍵字段)"></key>

                   <one-to-many class="gz.itcast.a_many2one_double.Address(對多的對象)"/>

                   </set>

                   <!-- 多對一配置

                            column: 值和一對多的key保持一致!!

                    -->

                   <many-to-one name="user(一對多的對象)"

                                     class="gz.itcast.a_many2one_double.User(對一的對象)"

                                     column="uid(一對多的Key值)"

                                     cascade="all"/>

多對多雙向(至關於從新創建一個關係表)

inverse: 是否須要反轉關係的維護權

 

                   false: 不反轉,由當前方維護

                   true:須要反轉,由對方維護

 

         hibernate在一對多的關心中,默認由一方維護(inserse="false"),爲了提升效率(節省了update語句),能夠把一方的insevse設置爲true,把維護權給多方。   

Student

<set name="(set實體名) " table="student_teacher(創建的關係表)" cascade="all" inverse="true">

                            <!-- 當前方在關係表的外鍵 -->

                            <key column="sid(當前表首字+id,關係表裏的字段)"></key>

                            <!-- set元素

                                     class: set集合的元素的類型

                                     column: set元素的表在關係表的外鍵

                             -->

<many-to-many class="gz.itcast.b_many2many_double.Teacher(關聯的表)" column="tid(關聯表的key值)"></many-to-many>

                   </set>

Teacher

<set name="(set實體名)" table="(關係表一致)">

                            <key column="tid(關係表裏的id字段)"></key>

<many-to-many class="gz.itcast.b_many2many_double.Student(關聯的表)" column="sid(關聯表的key值)"></many-to-many>

                   </set>

一對一雙向

                   <!-- 一對一的主鍵關聯配置:一對一配置

                            constrained: 是否把主鍵設置爲外鍵

                                     false:否

                                     true: 是

                    -->

例如:一人對一身份證

<one-to-one name="idcard"

                            class="gz.itcast.c_one2one_double.IdCard"

                            cascade="all"/>

                   <!-- 一對一的主鍵關聯配置:一對一配置

                            constrained: 是否把主鍵設置爲外鍵

                                     false:否

                                     true: 是

                    -->

                   <one-to-one

                      name="person"

                      class="gz.itcast.c_one2one_double.Person"

                      constrained="true"></one-to-one>

hibernate查詢(hql語句)

全表查詢返回list集合      from (對象名)

 

指定字段查詢 默認狀況下,返回一個List<Object[]>須要遍歷兩次才能拿數據,能夠封裝成List<Employee>,在Employee裏有參構造(有參的值寫須要返回封裝的對象屬性)

select e.(對象屬性),e.(對象屬性) from (對象名) e(自定義別名)

 

條件查詢返回list

from (對象名) e(自定義別名) where e.(對象屬性)=? and e.(對象屬性)=?

設置屬性?

q.setParameter(0, "李_");

q.setParameter(1, 6500.0);

 

from (對象名) e(自定義別名) where e.(對象屬性) like ?         //like模糊查詢

q.setParameter(0, "%李%");   //%表示省略先後

 

查詢排序返回list    排序: order by    asc: 升序  desc : 降序

from (對象名) e(自定義別名) order by e.(對象屬性) asc   

 

聚合查詢返回一個對象(max,min avg,count...

select max(e.對象屬性) from (對象名) e(自定義別名)

 

統計查詢能夠設置約束條件(變成分頁查詢)返回int

select count(e) from (對象名) e(自定義別名)

設置分頁

                            q.setFirstResult(0);    //起始位置

                            q.setMaxResults(3);   //查詢條數

 

分組查詢 (group by)

select e.(對象屬性1),count(*) from (對象名) e(自定義對象別名) where e.(對象屬性1) is not null and e.(對象屬性1)<>'' group by e.(對象屬性1)

 

分組後篩選(having)

select e.(對象屬性1),count(*) from (對象名) e(自定義對象別名) where e.(對象屬性1) is not null and e.(對象屬性1)<>'' group by e.(對象屬性1) having count(*)>2(條件)

 

多表查詢  內鏈接(inner join)  外右鏈接(right outer join)

(內鏈接)select e.name,e.dept.deptName from (對象名) e(自定義對象別名) inner join e.dept

(外右鏈接) select e.dept.deptName,e.name from (對象名) e(自定義對象別名) right outer join e.dept

原生sql查詢

         SQLQuery sq = session.createSQLQuery("select * from employee");  //原來sql語句表名

                   //封裝成什麼對象

                   sq.addEntity(Employee.class);

                  

                   List<Employee> list = sq.list();

         注意:若是該查詢須要比較高的性能要求,可使用sql查詢

細節

一級緩存

概念

一級緩存,也稱之爲Session級別的緩存,在Session對象內部設計的一個緩存,只能在Session範圍內使用。

默認狀況下,一級緩存是打開和使用,咱們不能關閉它。

操做一級緩存

1:session.flush()  同步一級緩存的數據 (常常跟第3一塊兒用,刷完內存裏東西,而後刪除內存對象)

2:session.evict(obj)  從一級緩存清除某個對象

3:session.clear()  清空一級緩存的全部對象

Hibernate對象狀態

臨時狀態

例如: Student stu=new Student()   新new對象

不在一級緩存中

數據庫找不到對應記錄

持久對象

例如:Admin admin = session.get(Admin.class, 1); 從session中直接取出來的數據

在一級對象中

數據庫找獲得對應記錄

遊離對象

例如:Student s = (Student) session.get(Student.class, 1); // s:持久對象  session.evict(s);//刪除一級緩存裏的數據

不在一級緩存中

遊離對象的數據和數據庫的數據保持一致,可是不能用於任何修改操做

刪除對象

例如:Student s = (Student) session.get(Student.class, 3); // s:持久對象 session.delete(s);

不在一級緩存中

數據庫數據不一致

延遲加載

get和load的區別

get

(1)Get方法執行後當即查詢數據庫數據,返回數據庫數據(真實對象)

(2)get方法若是查詢數據庫沒有對應數據時,返回null

Load

(1)     load方法執行以後,沒有查詢數據庫(返回的是一個代理對象),而是在使用對象的屬性數據

(2)     load方法若是查詢數據庫沒有對應數據時,返回ObjectNotFound異常

延遲加載

<!-- lazy: 延遲加載。默認狀況下就是延遲加載 -->

                   <set name="addresses" cascade="all" lazy="true">

                            <key column="sid"></key>

                            <one-to-many class="gz.itcast.d_lazy.Address"/>

                   </set>

二級緩存

步驟1:導入二級緩存的jar

ehcache-core-2.4.3.jar

hibernate-ehcache-4.3.8.Final.jar

slf4j-api-1.7.2.jar

slf4j-log4j12-1.7.2.jar

步驟2:配置開啓二級緩存(hibernate.cfg.xml).

<!-- 啓用二級緩存 -->

         <property name="hibernate.cache.use_second_level_cache">true</property>

         <!-- 引入二級緩存插件(提供者) -->

         <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>

         <mapping xxxx/> //須要引用的二級緩存必須放在mapping後面

         <!-- 把指定類使用二級緩存 -->(可使用註解在實體類上寫入@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)

 

<class-cache usage="read-write" region="itCache" class="gz.itcast.d_lazy.Address(須要二級緩存的實體)"/>

步驟3:提供配置文件.

src/ehcache.xml

配置查詢緩存(效果不大)

-- 提升查詢速度.(二級緩存的基礎之上).

      緩存的是查詢語句.

 

   -- 配置開啓查詢緩存(hibernate.cfg.xml).

      <!-- 配置開啓查詢緩存 -->

      <property name="hibernate.cache.use_query_cache">true</property>

 

   -- 指定哪些查詢語句作緩存.

      getSession().createQuery(hql).setCacheable(true);

鏈接池插件(c3p0)

1: 導入c3p0插件包 optional\ehcache\(hibernate的lib包中)

         c3p0-0.9.2.1.jar

         hibernate-c3p0-4.3.8.Final.jar

         mchange-commons-java-0.2.3.4.jar

2: 在hibernate.cfg.xml配置

<!-- 使用c3p0插件 -->

         <property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>

         <property name="connection.url">jdbc:mysql://localhost:3306/day34?useUnicode=true&amp;characterEncoding=utf-8</property>

         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>

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

         <property name="connection.password">root</property>

         <!-- 初始鏈接數 -->

         <property name="c3p0.min_size">5</property>

         <!-- 最大鏈接數 -->

         <property name="c3p0.max_size">20</property>

         <!-- 等待時間 -->

         <property name="c3p0.timeout">3000</property>

 

 

 

Spring框架

概念

spring是一個JavaEE應用程序的一站式(full-stack)框架,是一個輕量級的*IOC*和*AOP*的容器框架,主要用於解決應用中javabean對象的生命週期管理和對象之間的依賴關係問題,還能夠整合其餘如struts2,hibernate等框架,簡化這些框架的使用。

Spring的         IOC

設計一個beanFactory(實例工廠)解決項目管理問題

Spring IOC開發步驟

1:導入jar包

commons-logging-1.1.1.jar

                   spring-beans-4.2.0.RELEASE.jar

                   spring-context-4.2.0.RELEASE.jar

                   spring-core-4.2.0.RELEASE.jar

                   spring-expression-4.2.0.RELEASE.jar

2:編寫一個類

public class UserDao {

         public void save(){

                   System.out.println("userDao.save()....");

         }

}

3:在src目錄裏創建一個applicationContext.xml  (或者beans.xml或者sprirng.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">

<!-- 使用springIOC工廠建立一個對象 -->

          <bean id="userDao" class="gz.itcast.a_hello.UserDao"></bean>

</beans>

4:獲取對象

//使用類路徑方式讀取spring的xml文件

                   ApplicationContext ac =

                  new ClassPathXmlApplicationContext("/gz/itcast/a_hello/applicationContext.xml");

                  

                   //2.從springIOC工廠中獲取一個對象

                   UserDao userDao = (UserDao)ac.getBean("userDao");

 

等同於UserDao user =new UserDao

SpringIOC的簡介

springIOC,主要解決的是對象管理問題,以及對象之間的依賴關係問題!!!!

 

         IOC, Inversion Of Control 控制反轉    (解決對象建立問題)

                   沒有IOC:new Student() 直接獲取一個對象 依賴性太強,耦合性太大

                   有IOC: getBean("xxx")  把對象的控制器託管給BeanFactory(springIOC)

 

         DI,dependency injection 依賴注入     (解決對象之間的依賴關係問題)

                   沒有DI: IUserDao usrDao = new UserDao()

                   有DI: IUserDao userDao;                         

                            public void setUserDao(IUserDao userDao){

                                     this.userDao = userDao;

                            }

對象建立問題(IOC)

使用無參構造方法建立對象

         <bean id="userDao1" class="gz.itcast.a_hello.UserDao"></bean>

         注意:

                   在給對象提供了有參的構造方法的同時,不要忘記補上一個無參構造方法

使用有參構造方法建立對象

                    <!-- 使用有參構造方法建立對象 -->

            <bean id="userDao" class="gz.itcast.b_bean.UserDao">

                        <constructor-arg index="0" value="狗娃"></constructor-arg>

                        <constructor-arg index="1" value="20"></constructor-arg>

            </bean>    

使用工廠類建立對象

                   成員方法

                            <!-- 使用工廠類的成員方法來建立對象 -->

            <!-- 1.1 建立工廠類對象 -->

            <bean id="factory" class="gz.itcast.b_bean.ObjectFactory"></bean>

            <!-- 1.2 調用工廠類的成員方法 -->

            <bean id="userDao2" factory-bean="factory" factory-method="getInstance"></bean>

//工廠類

public class ObjectFactory {

         //成員方法

         public UserDao getInstance(){

                   return new UserDao("張三",22);

         }

}

                   靜態方法

 <!-- 使用工廠類的靜態方法來建立對象 -->

<bean id="userDao3" class="gz.itcast.b_bean.ObjectFactory" factory-method="getStaitcInstance"></bean>

         //工廠類

public class ObjectFactory {

//靜態方法

         public static UserDao getStaitcInstance(){

                   return new UserDao("李四",24);

         }

}

單例和多例問題

scope

         single: 單例

         prototype:多例

          <bean id="userDao4" class="gz.itcast.b_bean.UserDao" scope="prototype"></bean>

是否延遲建立對象

lazy-init  是否須要延遲建立對象,默認fales,改爲true就是延遲建立

default-lazy-init="true": 設置全局的延遲建立bean

注意:lazy-init只對單例(singleton)起做用

依賴注入

1:構造方法注入

<bean id="user" class="gz.itcast.c_di.User">

                 <constructor-arg index="0" value="狗娃"></constructor-arg>

</bean>

構建有參構造

public User(String name){

                   System.out.println("name="+name);

         }

2:使用set方法注入數據(推薦)

類裏面提供set方法

<bean id="user" class="gz.itcast.c_di.User">

                 <!-- name: set方法名稱 例如setAge()的set方法名稱:age-->

                 <property name="age" value="20"></property>

</bean>

注入不一樣的數據類型:

                   *String類型:<value>

                   *int類型: <value>

                   *double類型: <value>

                   數組類型:

                            <array>

                                    <value>廣州天河</value>

                                    <value>廣州番禺</value>

                                    <value>廣州越秀</value>

                          </array>

                   List類型:

                            <list>

                                    <value>AAA</value>

                                    <value>BBB</value>

                                    <value>CCC</value>

                          </list>

                   Map類型:

                            <map>

                                    <entry key="key1" value="value1"/>

                                    <entry key="key2" value="value2"/>

                                    <entry key="key3" value="value3"/>

                          </map>

                   *Properties類型:

                            <props>

                                    <prop key="pro1">value1</prop>

                                    <prop key="pro2">value2</prop>

                                    <prop key="pro3">value3</prop>

                          </props>                  

                   *引用類型:

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

SpringIOC註解(重點)

1:導入spring的aop的jar

                   spring-aop-4.2.0.RELEASE.jar

2:applicationContext.xml引入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

        http://www.springframework.org/schema/beans/spring-beans.xsd

        http://www.springframework.org/schema/context

        http://www.springframework.org/schema/context/spring-context.xsd

        ">

3:使用context的標籤去掃描註解目錄

<context:component-scan base-package="gz.itcast.d_annotation"></context:component-scan>

4:註解用法

//@Component("user")等價於 <bean id="user" class="gz..xxxx.User"/>

@Controller("user")

public class User {

@Resource(name="addr")  //name輸入對象@Component的值

private Address addr;

// 相似於<property name="addr" ref="addr"/>,不一樣於property注入的是,@Resource使用的是 暴力反射直接注入屬性

<!-- 開啓annotation實現字段注入  @Resource -->

     <context:annotation-config/>

 

     @Resource // byType

     @Resource(name="jobDao") // byName

     private JobDao jobDao;

經常使用的註解:

         @Component("xxx")   在springIOC工廠中建立一個對象(底下3個效果等同,爲了區分)

                   @Resource("xxx")  在當前對象中注入springIOC工廠中的一個對象

        

                   @Repository   做用同@Component; 在持久層使用

                   @Service      做用同@Component; 在業務邏輯層使用

                   @Controller    做用同@Component; 在控制層使用

 

SpringAop

springAOP概念

AOP,Aspect Object Programing 面向切面編程,主要是用於分離核心業務代碼 和 服務代碼(重複代碼)

三種代理方式

1:靜態代理 (關鍵:手寫代理類,要求:必須實現接口)

寫一個方法類接口

public interface IUserDao {

         public void save();

         public void update();

}

 

public class UserDaoProxy implements IUserDao{

         private IUserDao userDao;

         //綁定目標對象

         public void bind(IUserDao userDao){

                   this.userDao = userDao;

         }

         @Override

         public void save() {

                   System.out.println("開啓事務");   //代理類實現接口後能夠修改屬性

                   //執行核心業務:

                   userDao.save();

                   System.out.println("提交事務");

         }

         @Override

         public void update() {

                   System.out.println("開啓事務");

                   //執行核心業務:

                   userDao.update();

                   System.out.println("提交事務");

         }

}

2:jdk動態代理

//能夠生成任意對象的代理類對象的工具

public class ProxyFactory {

         private Object target;

         //綁定被代理對象

         public void bind(Object target){

                   this.target = target;

         }

        

         //生成一個被代理對象的代理類對象

         public Object getProxyInstance(){

                   return Proxy.newProxyInstance(

                                     ProxyFactory.class.getClassLoader(),  // 指定類加載器,隨意指定   

                                     target.getClass().getInterfaces(), // 指定代理類實現的接口(一般和被代理對象相同的接口)

                                     new InvocationHandler() { //new一個內部類,指定代理後的處理程序

         @Override      //生成的代理對象          //當前方法的參數

         public Object invoke(Object proxy, Method method, Object[] args) // invoke()執行處理程序

                                                                 throws Throwable {

                                                        System.out.println("當前執行的方法:"+method.getName());

                                                        //目標: 在每一個業務方式執行事務代理

                                                        System.out.println("開啓事務");

                                                        //執行核心業務方法

                                                        Object result = method.invoke(target, args);

                                                        System.out.println("提交事務");

                                                        return result;

                                               }

                                     }

                                     );  // 指定代理後的處理程序 (代理後要怎麼作???);

         }

}

3: CGLIB子類代理方式

關鍵:不須要實現接口,直接生成目標對象的子類代理

         步驟:

         導入cglib的jar包

                   spring-core包

                   spring-aop包

         編寫生成子類對象的程序

//生成子類代理對象的工廠類

public class ProxyFactoryCGLIB implements MethodInterceptor{

         private Object target;

         //綁定目標對象

         public void bind(Object target){

                   this.target = target;

         }

         //生成目標的子類代理對象

         public Object getProxyInstance(){

                   //1.建立工具類

                   Enhancer en = new Enhancer();

                   //2.指定父類

                   en.setSuperclass(target.getClass());

                   //3.指定回調函數(底層實現須要類加載器)

                   en.setCallback(this);

                   //4.建立子類代理對象

                   return en.create();

         }

         /**

          * proxy: 子類代理對象

          * method: 當前調用的方法

          * value: 當前調用的方法的參數

          * mp: 當前方法的代理對象

          */

         @Override

         public Object intercept(Object proxy, Method method, Object[] value,

                            MethodProxy mp) throws Throwable {

                   System.out.println("開啓事務");

                  

                   //調用核心業務:

                   Object result = method.invoke(target, value);

                  

                   System.out.println("提交事務");

                   return result;

         }

}

SpringAOP實現

SpringAOP底層使用CGLIB子類代理方式實現

SpringAOP關鍵詞

         鏈接點(jointPoint):須要關注的核心業務方法( save()  update() )

         切入點(pointcut):須要切入服務代碼的業務方法 ( save())

                   注意:

                   1)切入點必定是鏈接點

                   2)鏈接點不必定是切入點

         通知(advice):

                   須要在切入點上面執行的代碼邏輯

         *切面(aspect/advisor):

                   切入點+通知   :  在某些方法(切入點)執行通知代碼

導入jar

                   spring-core

                   spring-aop

1:編寫目標對象(專一核心業務)

public class UserDao {

                   public void save(){

                            System.out.println("保存數據");

                   }

                   public void update(){

                            System.out.println("更新數據");

                   }

}

2:編寫切面類,裏面寫不一樣類型的通知

public class MyAspect {

         //定義通知

         /**

          * 前置通知(在業務方法前面切入)

          * 後置通知(在業務方法後面切入)

          * 環繞通知(在業務方法先後切入))

          */

         public void before(){

                   System.out.println("執行前置通知");

         }         

}

3:配置切面

       <!-- 建立目標對象 -->

     <bean id="userDaoID" class="gz.itcast.dao.UserDao"></bean>

     <!-- 建立切面對象-->

     <bean id="myAspect" class="gz.itcast.dao.MyAspect"></bean>

     <!-- 定義切面配置 -->

     <aop:config>

                <!-- 定義一個切面 -->

                <aop:aspect ref="myAspect(切面類id)">

                       <!-- 通知 -->

                                <!-- 前置通知 -->

                         <!-- 切入點 -->

                       <aop:pointcut id="myptID(自定義ID)" expression="execution(*(通配方法修飾符,方法返回值) gz.itcast.dao.UserDao.*(通配任意方法名)(..)(兩個點省略所有參數))" />

                                <!-- 切面類中的方法名稱 -->

                <aop:before method="before(插入的方法)" pointcut-ref="myptID(寫入切面ID)"/>

                </aop:aspect>

     </aop:config>

Spring整合hibernate事務

<!-- 建立一個spring提供Hibernate的事務管理器 : 用於管理每次操做的事務代碼-->

         <bean id="hbmTxID" class="org.springframework.orm.hibernate4.HibernateTransactionManager">

                   <!-- 必須注入SessionFactory -->

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

         </bean>

        

         <!-- 事務通知 : 環繞通知-->

         <!--

                  id: 事務通知的標記

                   transaction-manager: 事務管理器

          -->

         <tx:advice id="txID" transaction-manager="hbmTxID">

                   <!-- 事務屬性 -->

                   <tx:attributes>

                            <!-- propagation: 事務傳播屬性

                                     REQUIRED: 若是上一個方法有事務,則加入上個方法的事務,若是沒有,則新建一個事務。 一般更新方法設置爲這個屬性

                                     SUPPORTS:若是上個方法有事務,則加入事務,若是沒有,則不加入事務。一般查詢方法設置這個屬性

                             -->

                   <tx:method name="set*" read-only="true"/> : 表明沒開啓事務,只能作查詢.

           <tx:method name="set*" read-only="false"/> : 表明開啓了事務,CURD均可以作.

                            <tx:method name="save" propagation=" SUPPORTS "/>//能夠指定方法

                            <tx:method name="*" propagation=" REQUIRED "/>//通配所有方法

                   </tx:attributes>

         </tx:advice>

   <!-- 配置切面 -->

   <aop:config>

               <!-- 切入點 -->

               <aop:pointcut id="myptID" expression="execution(* gz.itcast.dao.UserDao.save(..))" />

               <!-- 切面 -->

               <aop:advisor advice-ref="txID" pointcut-ref="myptID"/>

   </aop:config>   

注意事項:

1:若是使用了spring的事務管理,則在Dao中自行獲取Session時,必須使用getCurrentSession()方法

2:也能夠是spring提供的HibernateTemplate工具類模板

在Dao中寫用private HibernateTemplate ht;替換private SessionFactory sf;

<bean id="hbmTempID" class="org.springframework.orm.hibernate4.HibernateTemplate">

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

         </bean>

                   常見方法:

                   ht.save()

                   ht.update()

                   ht.get()

                   ht.find("hql",Object... value); 至關於createQuery(「hql」).setParameter(0,value)

                   ht.execute();   使用回session對象

(重點)步驟

1.事務管理器: HibernateTarnsactinManager

2.通知: tx:advice

3.切入點: point-cut

4.切面: <advisor advice-ref="通知" pointcur-ref="切入點"/>

String整合Struts2

在web.xml啓動struts2和spring容器

<!-- 啓動struts2 -->

<filter>

<filter-name>struts2</filter-name>

<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>

</filter>

         <filter-mapping>

                   <filter-name>struts2</filter-name>

                   <url-pattern>/*</url-pattern>

         </filter-mapping>

        

<!-- 啓動spring容器 :ContextLoaderListener用於啓動spring的容器-->//至關於監視器

<listener>

         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

關鍵: 建立struts2中使用到的Action對象

<?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

        http://www.springframework.org/schema/beans/spring-beans.xsd

        http://www.springframework.org/schema/context

        http://www.springframework.org/schema/context/spring-context.xsd

        ">

         <!-- 建立struts2的Action對象

                   scope="prototype": action必須是多例的

          -->

<bean id="userActionID(兩邊要一致)" class="gz.itcast.action.UserAction" scope="prototype">

                   <property name="userService" ref="userServiceID"/>

         </bean>  

</beans>

在struts.xml文件引用spring容器的對象

<package name="user" namespace="/" extends="struts-default">

                   <action name="user_*" class=" userActionID(兩邊要一致)" method="{1}">

                            <result>/succ.jsp</result>

                   </action>

</package>

Spring記錄日誌 

第一種

1:寫一個類與數據庫對應值一致:

 

2:寫一個util工具類,記錄進入用戶的操做。

//系統日誌工具類

public class LogUtil {

         //注入日誌業務類

         private ISystemlogService systemlogService;

         public void setSystemlogService(ISystemlogService systemlogService) {

                   this.systemlogService = systemlogService;

         }

         //寫日誌

         public void writeLog(JoinPoint jp){ //JoinPoint:鏈接點

                   Object target = jp.getTarget();//目標對象

                   String calledClassName = target.getClass().getName();//目標類的類名

                   String calledMethodName = jp.getSignature().getName();//調用的方法名

                   String func = calledClassName+":"+calledMethodName;//操做名稱

                  

                   if(target instanceof ISystemlogService){//遇到日誌業務,則退出

                            return;

                   }

                   Systemlog log = new Systemlog(); //建立記錄對象

                  //操做者:當前登陸的用戶

                   Employee operator = (Employee)ActionContext.getContext().getSession().get("loginInfo");

                  

                   log.setOperator(operator);

                   log.setOptTime(new Date());          

                   log.setFunc(func);

                   //獲取ip

                   String ip = ServletActionContext.getRequest().getRemoteHost();

                   log.setIp(ip);

                   systemlogService.save(log); //調用service保存方法

         }

}

3:spring的aop配置

<!— 須要插入的類配置 -->

          <bean id="logUtil" class="gz.itcast.crm.util.LogUtil">

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

          </bean>

<!-- 系統日誌切面 -->

          <aop:config>

                 <aop:aspect ref="logUtil">

                          <!-- 切入點 -->

                          <aop:pointcut id="logpt" expression="execution(* gz.itcast.crm.service.impl.*.*(..))" />

                          <!-- 通知 -->

                          <aop:after method="writeLog" pointcut-ref="logpt"/>

                 </aop:aspect>

          </aop:config>

第二種

aop日誌切面.

   -- 記錄業務層方法執行的速度(效率).

   -- 記錄業務層方法的異常信息.

 

    commons-logging-xxx.jar: 只是在控制檯輸出日誌信息.

    private Log logger = LogFactory.getLog(LogAdvice.class);

提供日誌文件來記錄日誌.

log4j框架:

     logging for java : apache組織.

 

     log4j-1.2.17.jar

 

     /** 定義日誌記錄器對象 */

     private Logger logger = Logger.getLogger(LogAdvice.class);

            logger.info(message);

         logger.debug(message);

         logger.error(message);

    

     log4j.properties: 屬性文件://設置存儲路徑

     第一個部分:

       log4j.rootLogger = info,a,b

       log4j.rootLogger = [日誌級別],輸出端1,輸出端2

 

     第二個部分:

       log4j.logger.com.opensymphony.xwork2=error

       log4j.logger.包名=日誌級別

 

 

     第三個部分(輸出端):

       org.apache.log4j.ConsoleAppender:將日誌信息輸出到控制檯.

       org.apache.log4j.DailyRollingFileAppender:

         將日誌信息輸出到一個日誌文件,而且天天輸出到一個新的日誌文件.

 

 

6. slf4j框架:

     simple logging fade for java : java的日誌門面(日誌規範).

 

 

<!-- 日誌切面 -->

 <bean id="logAdvice" class="cn.itcast.oa.core.aop.LogAdvice"/>

    

     <!-- 切面(aop) -->

     <aop:config>

       <!-- 配置切入點 (切業務層) -->

       <aop:pointcut expression="execution(* cn.itcast.oa.*.*.service.impl.*.*(..))" id="pointcut"/>

       <!-- 事務切面將上面的聲明式事務配置 txAdvice 運用到   哪一個切入點pointcut  -->

       <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>

      

       <!-- 配置日誌切入 -->

     <aop:aspect ref="logAdvice">

          切入方法

     <aop:around method="around" pointcut-ref="pointcut"/>

          配置異常後切入

<aop:after-throwing method="error" pointcut-ref="pointcut" throwing="e"/>

       </aop:aspect>

     </aop:config>

相關文章
相關標籤/搜索