前のセクション「SSH Framework Online Mallプロジェクトの最初の戦い:Struts2、Hibernate4.3、Spring4.2の統合」では、 Struts2、Hibernate、Springの開発環境を構築し、それらをうまく統合しました。このセクションでは、主にいくつかの基本的な追加、削除、変更、検索、およびサービスの抽出、DAO、およびアクションを完了します。
1。サービスレイヤーの抽出
前のセクションでは、サービスレイヤーに保存メソッドと更新メソッドを書きました。ここでは、このパートのコードを改善し、サービスレイヤーでコードを抽出し始めます。
1.1カテゴリサービスレイヤーを改善します
データベースの操作は、追加、削除、変更、およびチェックすることにすぎません。まず、カテゴリサービスレイヤーのインターフェイスと実装を改善しましょう。
// categoryServiceインターフェイスパブリックインターフェイスカテゴリサービスbaseService <category> {public void save(category category); // public void Update(カテゴリカテゴリ)を挿入します。 // public void delete(int id)を更新します。 // publicカテゴリget(int id); //カテゴリのパブリックリストを取得<Category> Query(); //すべてのカテゴリを取得}カテゴリサービスインターフェイスの特定の実装:
パブリッククラスカテゴリServiceImplは、BaseServiceImpl <Category>を実装していますcategoryService {private SessionFactory Factory; // springはpublic void setsessionFactory(SessionFactory Factory){this.sessionFactory = sessionFactory; } protected session getSession(){//現在のスレッドからセッションを取得しない場合は、新しいセッションを作成します。 } @Override public void save(category category){getsession()。save(category); } @Override public void update(category category){getsession()。update(category); } @Override public void delete(int id){ /*最初の方法には欠点があります。つまり、削除する前に一度照会する必要があります。オブジェクトobj = getsession()。get(category.class、id); if(obj!= null){getsession()。delete(obj); }*/ string hql = "id =:id"; getSession()。createquery(hql)// .setinteger( "id"、id)// .executeUpdate(); } @Override public category get(int id){return(category)getsession()。get(category.class、id); } @Override public List <Category> query(){string hql = "from category"; return getsession()。create query(hql).list(); }} 1.2サービスレイヤー抽出実装
カテゴリサービスを完了した後、サービスレイヤーの基本的な実装を抽出します。アイデアは次のとおりです。ベースインターフェイスBaseServiceとBaseServiceImplを抽出し、後で開発する場合、新しいサービスが必要な場合は2つのステップのみを実行する必要があります。次に、新しい実装クラスを定義しますxxxServiceImplはbaseServiceImplを継承し、xxxServiceインターフェイスを実装します。これにより、プロジェクトの維持が容易になります。
上記のカテゴリサービスインターフェイスに基づいて、まずBaseServiceインターフェイスを作成しましょう。
// BASIC INTERFACE BASESERVICE、汎用パブリックインターフェイスBaseService <T> {public void Save(t);を使用します。パブリックボイドアップデート(T T); public void delete(int id); public t get(int id);パブリックリスト<t> query(); }次に、BaseService Interfaceの実装クラスBaseServiceImplを作成します。
/ ** * @description todo(パブリックモジュールの抽出) * @author eson_15 * */ @suppresswarnings( "unchecked")public class baseserviceimpl <t> baseService <t> {private class clazz; //現在の操作のタイプは、Clazzに保存されています。つまり、一般的なT Private SessionFactory Factoryです。 public BaseServiceImpl(){//次の3つの印刷情報を削除できます。 System.out.println( "これは、現在コンストラクターを呼び出すオブジェクトを表します" + this)です。 system.out.println( "現在のオブジェクトの親クラス情報を取得します" + this.getclass()。getSuperclass()); system.out.println( "現在のこのオブジェクトの親クラス情報を取得します(汎用情報を含む)" + this.getClass()。getGenericSuperClass()); // generic parameterizedType type =(parameterizedType)this.getClass()。getGenericSuperClass();のパラメータータイプを取得します。 clazz =(class)type.getActualTypearguments()[0]; } public void setSessionFactory(sessionFactory sessionfactory){this.sessionFactory = sessionFactory; } protected session getSession(){//現在のスレッドからセッションを取得しない場合は、新しいセッションを作成します。 } @Override public void save(t t){getsession()。save(t); } @Override public void update(t t){getsession()。update(t); } @Override public void delete(int id){system.out.println(clazz.getSimplename()); string hql = "delete" + clazz.getsimplename() + "as c where c.id =:id"; getSession()。createquery(hql)// .setinteger( "id"、id)// .executeUpdate(); } @override public t get(int id){return(t)getsession()。get(clazz、id); } @Override public List <t> query(){string hql = "from" + clazz.getSimplename(); return getsession()。create query(hql).list(); }}抽出が完了した後、CategoryServiceインターフェイスとCategoryServiceImpl実装クラスを書き換えることができます。次のように:
// categoryserviceインターフェイス継承BaseServiceインターフェイスパブリックインターフェイスcategoryservice extends baseService <category> { / * * CategoryService自体が必要とする新しいメソッドを追加するだけです。パブリックメソッドはすでにBaseService * /} / ** * @description todo(モジュール自体のビジネスロジック) * @author eson_15 * * * / public class categoryserviceimplは、BaseSeServiceimpl <カテゴリ>を実装しています{ / * *カテゴリ環境インターフェイスに新しく追加された方法を実装するだけです。パブリックメソッドはbaseserviceimpl */}に実装されていますコードからわかるように、新しく追加されたサービスは、BaseServiceインターフェイスを継承し、サービスに必要なビジネスロジックをインターフェイスに追加するだけです。新しく追加されたServiceImplは、BaseServiceImplを継承し、新しく追加されたビジネスロジックを実装するだけで必要です。
ただし、重要なポイントを忘れないでください。春の構成ファイルBeans.xmlで豆を変更することです。
<! - ジェネリッククラスをインスタンス化できないため、Lazy-Initプロパティを追加します - > <Bean Id = "BaseService" lazy-init = "true"> <property name = "sessionfactory" ref = "sessionfactory"/> </bean id = "categoryservice" parent = "baseservice"/>>
元のCategoryServiceでプロパティを殺し、親プロパティを追加して、BaseServiceの継承を示します。次に、BaseServiceを構成し、SessionFactoryをBaseServiceに設定します。さらに、BaseServiceは一般的なクラスであり、一般的なクラスをインスタンス化することはできないため、LazyInitプロパティをTrueに設定することが1つあります。この時点で、サービス層の抽出が行われます。
2.サービスレイヤーにアカウントを追加します
サービスレイヤーが抽出されたばかりなので、アカウントサービスを作成するのは非常に簡単です。
最初にaccountserviceインターフェイスを書き込み、baseServiceを継承します。
Public Interface AccountServiceはBaseService <Account> {// BaseServiceのジェネリックがアカウントになることに注意してください / * * AccountService自体が必要とする新しい方法を追加するだけで、パブリックメソッドはすでにBaseService * /}にあります。次に、accountServiceImpl実装クラスを書き込み、BaseServiceImpl実装クラスを継承し、AccountServiceインターフェイスを実装します。
パブリッククラスaccountServiceImpl拡張baseServiceImpl <account> accountservice { / * * accountserviceインターフェイスに新しく追加されたメソッドを実装するだけです。パブリックメソッドはBaseServiceImpl *///ログイン関数の管理に実装されており、後で改善されます}最後に、次の構成をBeans.xmlファイルに追加します。
<bean id = "accountservice" parent = "baseservice" />
このようにして、新しいサービスが書かれています。将来サービスを追加する必要がある場合は、このプロセスに従ってください。これは非常に便利です。
3。アクション抽出
3.1ドメイン内のアクションにデータを保存する(リクエスト、セッション、アプリケーションなど)
アクションでは、ActionContext.getContext()を介してActionContextオブジェクトを直接取得し、オブジェクトを介して対応するドメインオブジェクトを取得できることを知っています。 xxxawareインターフェイスを実装して、対応するドメインオブジェクトを挿入することもできます。まずこれらの2つの方法を見てみましょう。
パブリッククラスのカテゴリアクションは、アクションサポートを拡張し、requestaware、sessionaware、applicationaware {private category category;プライベートカテゴリサービスカテゴリサービス。 public void setCategoryService(CategoryService CategoryService){this.categoryService = categoryService; } public String update(){System.out.println( "----更新----"); categoryservice.update(category); 「インデックス」を返します。 } public string save(){system.out.println( "---- save ----"); 「インデックス」を返します。 } public string query(){//ソリューション1、対応するマップを使用して元の内蔵オブジェクトを置き換えると、jspに依存関係がありませんが、コードの量は比較的大きい// actioncontext.getContext()。 //リクエストフィールドにそれを配置します// actionContext.getContext() //セッションフィールドに置く// actionContext.getContext()。getApplication()。put( "categoryList"、categoryservice.query()); //アプリケーションドメインに配置する//ソリューション2、対応するインターフェイス(RequestAware、SessionAware、ApplicationAware)を実装し、対応するマップをrequest.put( "categorylist"、categoryservice.query()); session.put( "categorylist"、categoryservice.query()); Application.put( "CategoryList"、categoryservice.query()); 「インデックス」を返します。 } public category getCategory(){return category; } public void setCategory(カテゴリカテゴリ){this.category = category; }プライベートマップ<文字列、オブジェクト>リクエスト;プライベートマップ<文字列、オブジェクト>セッション;プライベートマップ<文字列、オブジェクト>アプリケーション; @Override public void setApplication(map <string、object> application){this.application = application; } @Override public void setSession(map <string、object> session){this.session = session; } @Override public void setRequest(map <string、object> request){this.request = request; }}前のセクションの3つの主要なフレームワークを統合するのは、まだカテゴリ作用クラスです。この方法にクエリ方法を追加しました。この方法では、クエリの結果をリクエストドメイン、セッションドメイン、アプリケーションドメインに保存します。最初の方法は、ActionContextを使用してそれを実装することです。インターフェイスは必要ありませんが、コードは大きいです。 2番目の方法では、RequestAware、SessionAware、およびApplicationAwareインターフェイス、およびインターフェイスインジェクションリクエスト、セッション、およびアプリケーションを実装する3つの抽象的なメソッドを実装し、それを対応するメンバー変数に割り当てて、クエリ結果をクエリメソッドのドメインに保存できるようにします。このコードボリュームは最初の方法よりも大きいようです...しかし、最初に抽出して読み取ることができます。
index.jspに新しいクエリ接続を追加して、クエリの結果を表示できるかどうかをテストします。
<%@ページ言語= "java" import = "java.util。*" pageencoding = "utf-8"%> <%@ taglib uri = "http://java.sun.com/jsp/jstl/core"プレフィックス= "c"%> < <html> <head> <title> my jsp 'index.jsp'開始ページ</title> </head> <body> <a href = "$ {pagecontext.category_update.action?category.id=2&category.type=gg href = "category_save.action">アクセス保存</a> <a href = "category_query.action">すべてのカテゴリ</a> <br/> <c:foreachアイテム= "$ {requestscope.categorylist}" var = "category"> $ {category.id} | $ {category.type} | $ {category.hot} <br/> </c:foreach> <c:foreachアイテム= "$ {sessionscope.categorylist}" var = "category"> $ {category.id} | $ {category.type} | $ {category.hot} <br/> </c:foreach> <c:foreachアイテム= "$ {applicationscope.categorylist}" var = "category"> $ {category.id} | $ {category.type} | $ {category.hot} <br/> </c:foreach> </body> </html> 3.2抽出ベースアション
現在述べたように、2番目の方法ではコードボリュームが大きくなりますが、これらのドメインに関連する操作を特異的に処理するためのベースオーションを抽出できます。
Public Class BaseActionは、ActionSupportを実装し、RequestAware、SessionAware、ApplicationAware {Protected Map <String、Object> request;保護されたマップ<文字列、オブジェクト>セッション;保護されたマップ<文字列、オブジェクト>アプリケーション; @Override public void setApplication(map <string、object> application){this.application = application; } @Override public void setSession(map <string、object> session){this.session = session; } @Override public void setRequest(map <string、object> request){this.request = request; }}次に、これらのドメインオブジェクトを使用してデータを保存する必要がある場合、ベースアクションを直接継承し、リクエスト、セッション、アプリケーションオブジェクトを直接使用できます。したがって、変更されたカテゴリは次のとおりです。
パブリッククラスのカテゴリ作用は、BaseActionを拡張します{プライベートカテゴリカテゴリ; <pre name = "code"> private categoryservice categoryservice; public void setCategoryService(CategoryService CategoryService){this.categoryService = categoryService; } public String update(){system.out.println( "--- update -----"); categoryservice.update(category); 「インデックス」を返します。 } public string save(){system.out.println( "---- save -----"); return "index"; } public string query(){request.put( "categorylist"、categoryservice.query()); session.put( "categorylist"、categoryservice.query()); Application.put( "CategoryList"、categoryservice.query()); 「インデックス」を返します。 } public category getCategory(){return category; } public void setCategory(カテゴリカテゴリ){this.category = category; }}リクエスト、セッション、およびアプリケーションフィールドを使用する必要があるすべてのアクションは、直接継承されるだけで、非常に便利です。
3.3パラメーターを取得する(モデル駆動型)
上記のカテゴリ作用のクラスを見てみましょう。 POJOであるメンバー変数カテゴリがあります。この変数を定義し、セットと取得方法を書き込むことは、JSPページをURLに接続されたパラメーターを介して渡すためのものです。パラメーターは、ID、タイプなどのカテゴリオブジェクトの属性ですが、URLのパラメーターはカテゴリ、カテゴリ、タイプなどとして記述する必要があります。このようにして、Strutsはこのカテゴリオブジェクトに直接この書き込みパラメーターを自動的に挿入し、このカテゴリオブジェクトを直接使用できますが、これは少しカムソームです。 ModelDrivenを使用して、問題をより簡単に解決できます。
パブリッククラスのカテゴリ作用は、ベースアションを実装して拡張されています。モデル駆動型<カテゴリ> {プライベートカテゴリカテゴリ。 //モデル駆動型インターフェイスを使用して、getModel()メソッドを実装する必要があります。このメソッドは、返されたアイテムをstack @overrideパブリックカテゴリgetModel(){category = new Category();戻りカテゴリ。 } <pre name = "code"> private categoryservice categoryservice; public void setCategoryService(CategoryService CategoryService){this.categoryService = categoryService; } public String update(){System.out.println( "----更新----"); categoryservice.update(category); 「インデックス」を返します。 } public string save(){system.out.println( "---- save ----"); 「インデックス」を返します。 } public string query(){request.put( "categorylist"、categoryservice.query()); session.put( "categorylist"、categoryservice.query()); Application.put( "CategoryList"、categoryservice.query()); 「インデックス」を返します。 }}このようにして、フロントデスクJSPページにcategory.idのような退屈なパラメーターを含める必要はありません。 JSPページのモデル駆動型部分を見てください:
<%@ページ言語= "java" import = "java.util。*" pageencoding = "utf-8"%> <%@ taglib uri = "http://java.sun.com/jsp/jstl/core"プレフィックス= "c"%> < <html> <head> <title> my jsp 'index.jsp'開始ページ</title> </head> <body> <a href = "$ {pagecontext.category_update.action?category.id=2&category.type=gg href = "category_save.action?id = 1&type = haha&hot = true"> test modeldriven </a> <a href = "category_query.action">クエリすべてのカテゴリ</a> <br/> <c:foreachアイテム= "$ {requestscope.categoryList}" $ {category.type} | $ {category.hot} <br/> </c:foreach> <c:foreachアイテム= "$ {sessionscope.categorylist}" var = "category"> $ {category.id} | $ {category.type} | $ {category.hot} <br/> </c:foreach> <c:foreachアイテム= "$ {applicationscope.categorylist}" var = "category"> $ {category.id} | $ {category.type} | $ {category.hot} <br/> </c:foreach> </body> </html>テスト結果は、Catgoryを取得できることであり、すべてのID、タイプ、およびホット属性が適切に割り当てられていることです。モデル駆動型インターフェイスを実装することで、URLにパラメーターを簡単に運ぶことができることがわかります。実際には、GetModelメソッドを実装し、使用する新しいオブジェクトを返すだけです。この時点で、ストラットには間違いなく多くのモデルが得られる必要があると考えるのは簡単であるため、この部分をベースアクションに抽出する必要があります。
3.4抽出モデル駆動型の抽出
まず、次のように、モデル駆動型部品のコードをベースアションに追加します。
//モデル駆動型を必要とする多くの異なるモデルがあるため、一般的なパブリッククラスのベースアクト<T>拡張actionsupport explention requestaware、sessionaware、applicationaware、modeldriven <t> {protected map <string、object> request;を使用します。保護されたマップ<文字列、オブジェクト>セッション;保護されたマップ<文字列、オブジェクト>アプリケーション;保護されたTモデル。 @Override public void setApplication(map <string、object> application){this.application = application; } @Override public void setSession(map <string、object> session){this.session = session; } @Override public void setRequest(map <string、object> request){this.request = request; } @Override public t getModel(){//ここで、新しいA対応するインスタンスを渡すことにより、parameterizedType type =(parameterizedType)this.getClass()。getGenericSuperclass(); class clazz =(class)type.getactualTypearguments()[0]; try {model =(t)clazz.newinstance(); } catch(Exception e){新しいruntimeException(e); } return Model; }}抽出後、カテゴリのコードが減少して減少します。
//継承BaseActionを継承し、一般的なパブリッククラスのカテゴリを追加するBaseAction <Category> {private categoryservice categoryservice; public void setCategoryService(CategoryService CategoryService){this.categoryService = categoryService; } public String update(){System.out.println( "----更新----"); categoryservice.update(model); //モデルを使用する「インデックス」を直接返す; } public string save(){system.out.println( "---- save ----"); System.out.println(モデル); //モデルを直接使用して「インデックス」を返します。 } public string query(){request.put( "categorylist"、categoryservice.query()); session.put( "categorylist"、categoryservice.query()); Application.put( "CategoryList"、categoryservice.query()); 「インデックス」を返します。 }}この時点で、それについて気分が良くない別のことがあります。これは、常にカテゴリに存在していたメンバー変数カテゴリセルビースです。 Categoryactionはカテゴリサービスオブジェクトにメソッドを使用するため、このオブジェクトを作成し、設定されたメソッドを挿入する必要があります。これは不利な点につながります。多くのアクションがCategoryServiceを使用する必要がある場合、オブジェクトとセットメソッドをアクションで作成する必要があります。さらに、アクションでいくつかの異なるサービスオブジェクトが使用されている場合、それらのすべてを作成する必要があります。これは非常に複雑になります。
3.5ベースアションにサービスを抽出します
上記の問題に応じて、プロジェクト内のすべてのサービスオブジェクトを抽出してベースアクションに抽出して作成します。このようにして、他のアクションが基盤を継承した後、使用するサービスを使用することができます。
// BaseActionでコンテンツを分類しましたPublic Class BaseAction <T> ActionSupport Impltement RequestAware、SessionAware、ApplicationAware、ModelDriven <T> {// Service Objectected CategoryService CategoryService;保護されたアカウントサービスアカウントサービス。 public void setCategoryService(CategoryService CategoryService){this.categoryService = categoryService; } public void setAccountService(AccountService)AccountService){this.accountService = AccountService; } //ドメインオブジェクト保護されたマップ<string、object> request;保護されたマップ<文字列、オブジェクト>セッション;保護されたマップ<文字列、オブジェクト>アプリケーション; @Override public void setApplication(map <string、object> application){this.application = application; } @Override public void setSession(map <string、object> session){this.session = session; } @Override public void setRequest(map <string、object> request){this.request = request; } //モデル駆動の保護されたTモデル。 @Override public t getModel(){parameterizedType type =(parameterizedType)this.getClass()。getGenericsUperClass(); class clazz =(class)type.getactualTypearguments()[0]; try {model =(t)clazz.newinstance(); } catch(Exception e){新しいruntimeException(e); } return Model; }}これにより、カテゴリがよりリフレッシュされます。パブリッククラスカテゴリアクションはBaseAction <Category> {public String update(){system.out.println( "---- update ----"); categoryservice.update(model); 「インデックス」を返します。 } public string save(){system.out.println( "--- save ----"); System.out.println(モデル); 「インデックス」を返します。 } public string query(){request.put( "categorylist"、categoryservice.query()); session.put( "categorylist"、categoryservice.query()); Application.put( "CategoryList"、categoryservice.query()); 「インデックス」を返します。 }}一部の人々は、非常に多くのサービスオブジェクトがベースアクションに注入された場合、冗長ではないでしょうか?これは真実ではありません。なぜなら、たとえそれがベースアクションで書かれていなくても、スプリングコンテナがこのオブジェクトを作成するため、これは重要ではありません。それどころか、サービスオブジェクトはベースアクションに配置され、他のアクションの開発により便利です。さらに、BaseActionはstruts.xmlファイルに割り当てる必要はありません。JSPはベースアションを要求しないため、他のアクションが継承するためだけです。
忘れるべきもう一つ:それは、beans.xmlの構成を変更することです:
<! - プロトタイプタイプの場合、開始時に自動的に使用すると作成されます - > <bean id = "baseAction" scope = "prototype"> <プロパティ名= "categoryservice" ref = "categoryservice"> </<property name = "accountservice" ref = "ref =" councearservice> parent = "BaseAction"/>
新しいBaseAction Beanを追加し、プロジェクト内のすべてのサービスオブジェクトをプロパティとして一致させ、元のカテゴリでプロパティを殺します。
将来的には、新しいXXXACTIONを書きたい場合は、ベースアクションを直接継承できます。 xxxactionでサービスが使用されている場合は、直接使用できます。 beans.xmlファイルのxxxactionに対応するBeanを追加し、struts.xmlファイルでジャンプを構成する必要があります。
4. XMLを注釈に変更します
プロジェクトが大きくなり、より大きくなるにつれて、Beans.xmlにますます多くの構成があり、多くの構成が冗長であることがわかります。開発を容易にするために、XMLの構成を注釈に変更します。まず、beans.xmlの構成を見てみましょう。
これらは、環境を構築して抽出したときに書いた豆です。これらは注釈に変換する必要があります。それらをピースごとに交換しましょう。最初にサービス部品を交換します。これには、ベースサービス、カテゴリサービス、アカウントサービスの3つの部分があります。次のように交換してください:
次に、Beans.xmlの対応する部分を殺します。次に、主に基本、カテゴリ、アカウントのアクション部分を変更し、次のように置き換えます。
次に、beans.xmlのアクションパーツの構成を殺し、最後に次の構成をBeans.xmlファイルに追加すると、注釈を使用できます。
<コンテキスト:component-scanベースパッケージ= "cn.it.shop .."/>
一部の人々は、注釈を使用するときにサービスと行動が異なるのはなぜですか? @Serviceはサービスで使用され、@Controllerはアクションで使用されますか?実際、それは同じであり、それらを異なる豆の層と区別するためだけに、読みやすくします。
ソースコードのダウンロードプロジェクト全体のアドレス://www.vevb.com/article/86099.htm
元のアドレス:http://blog.csdn.net/eson_15/article/details/51297698
上記は、SSHフレームワークオンラインモールプロジェクトの2回目の戦いのコンテンツ全体です。私はそれがすべての人の学習に役立つことを願っています、そして、私は誰もがwulin.comをもっとサポートすることを願っています。