日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringMVC + spring3.1.1 + hibernate4.1.0 集成及常见问题总结

發布時間:2024/4/17 javascript 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringMVC + spring3.1.1 + hibernate4.1.0 集成及常见问题总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://jinnianshilongnian.iteye.com/blog/1423971

下載地址

一 開發環境

1、動態web工程

2、部分依賴

?

java代碼: Java代碼 ?
  • hibernate-release-4.1.0.Final.zip ??
  • hibernate-validator-4.2.0.Final.jar ??
  • spring-framework-3.1.1.RELEASE-with-docs.zip ??
  • proxool-0.9.1.jar ??
  • log4j?1.2.16??
  • slf4j?-1.6.1??
  • mysql-connector-java-5.1.10.jar ??
  • hamcrest?1.3.0RC2 ??
  • ehcache?2.4.3??
  • hibernate-release-4.1.0.Final.zip hibernate-validator-4.2.0.Final.jar spring-framework-3.1.1.RELEASE-with-docs.zip proxool-0.9.1.jar log4j 1.2.16 slf4j -1.6.1 mysql-connector-java-5.1.10.jar hamcrest 1.3.0RC2 ehcache 2.4.3

    ?

    3、為了方便學習,暫沒有使用maven構建工程

    ?

    二 工程主要包括內容

    1、springMVC + spring3.1.1 + hibernate4.1.0集成

    2、通用DAO層 和 Service層

    3、二級緩存 Ehcache

    4、REST風格的表現層

    5、通用分頁(兩個版本)

    5.1、首頁 上一頁,下一頁 尾頁 跳轉

    5.2、上一頁 1 2 3 4 5 下一頁

    6、數據庫連接池采用proxool

    7、spring集成測試 ???

    8、表現層的 java validator框架驗證(采用hibernate-validator-4.2.0實現)

    9、視圖采用JSP,并進行組件化分離

    ?

    三 TODO LIST? 將本項目做成腳手架方便以后新項目查詢

    1、Service層進行AOP緩存(緩存使用Memcached實現)

    2、單元測試(把常見的樁測試、偽實現、模擬對象演示一遍 區別集成測試)

    3、監控功能

    后臺查詢hibernate二級緩存 hit/miss率功能??????

    ? ?后臺查詢當前服務器狀態功能(如 線程信息、服務器相關信息)

    4、spring RPC功能

    5、spring集成 quartz 進行任務調度

    6、spring集成 java mail進行郵件發送

    7、DAO層將各種常用框架集成進來(方便查詢)

    8、把工作中經常用的東西 融合進去,作為腳手架,方便以后查詢

    ?

    四 集成重點及常見問題

    1、spring-config.xml?配置文件:

    1.1、該配置文件只加載除表現層之外的所有bean,因此需要如下配置:

    ?

    java代碼: Java代碼 ?
  • <context:component-scan?base-package="cn.javass"> ??
  • ????<context:exclude-filter?type="annotation"?expression="org.springframework.stereotype.Controller"/> ??
  • </context:component-scan>??
  • <context:component-scan base-package="cn.javass"><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan>

    通過exclude-filter 把所有 @Controller注解的表現層控制器組件排除

    ?

    ?

    1.2、國際化消息文件配置

    ?

    java代碼: Java代碼 ?
  • <!--?國際化的消息資源文件?--> ??
  • ????<bean?id="messageSource"?class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> ??
  • ????????<property?name="basenames"> ??
  • ????????????<list> ??
  • ????????????????<!--?在web環境中一定要定位到classpath?否則默認到當前web應用下找??--> ??
  • ????????????????<value>classpath:messages</value> ??
  • ????????????</list> ??
  • ????????</property> ??
  • ????????<property?name="defaultEncoding"?value="UTF-8"/> ??
  • ????????<property?name="cacheSeconds"?value="60"/> ??
  • ????</bean>??
  • <!-- 國際化的消息資源文件 --><bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"><property name="basenames"><list><!-- 在web環境中一定要定位到classpath 否則默認到當前web應用下找 --><value>classpath:messages</value></list></property><property name="defaultEncoding" value="UTF-8"/><property name="cacheSeconds" value="60"/></bean>

    此處basenames內一定是 classpath:messages ,如果你寫出“messages”,將會到你的web應用的根下找 即你的messages.properties一定在 web應用/messages.propertis。

    ?

    1.3、hibernate的sessionFactory配置 需要使用org.springframework.orm.hibernate4.LocalSessionFactoryBean,其他都是類似的,具體看源代碼。

    ?

    1.4、<aop:aspectj-autoproxy expose-proxy="true"/> 實現@AspectJ注解的,默認使用AnnotationAwareAspectJAutoProxyCreator進行AOP代理,它是BeanPostProcessor的子類,在容器啟動時Bean初始化開始和結束時調用進行AOP代理的創建,因此只對當容器啟動時有效,使用時注意此處。

    ?

    1.5、聲明式容器管理事務

    建議使用聲明式容器管理事務,而不建議使用注解容器管理事務(雖然簡單),但太分布式了,采用聲明式容器管理事務一般只對service層進行處理。

    ?

    java代碼: Java代碼 ?
  • <tx:advice?id="txAdvice"?transaction-manager="txManager"> ??
  • ????<tx:attributes> ??
  • ????????<tx:method?name="save*"?propagation="REQUIRED"?/> ??
  • ????????<tx:method?name="add*"?propagation="REQUIRED"?/> ??
  • ????????<tx:method?name="create*"?propagation="REQUIRED"?/> ??
  • ????????<tx:method?name="insert*"?propagation="REQUIRED"?/> ??
  • ????????<tx:method?name="update*"?propagation="REQUIRED"?/> ??
  • ????????<tx:method?name="merge*"?propagation="REQUIRED"?/> ??
  • ????????<tx:method?name="del*"?propagation="REQUIRED"?/> ??
  • ????????<tx:method?name="remove*"?propagation="REQUIRED"?/> ??
  • ????????<tx:method?name="put*"?propagation="REQUIRED"?/> ??
  • ????????<tx:method?name="use*"?propagation="REQUIRED"/> ??
  • ????????<!--hibernate4必須配置為開啟事務?否則?getCurrentSession()獲取不到--> ??
  • ????????<tx:method?name="get*"?propagation="REQUIRED"?read-only="true"?/> ??
  • ????????<tx:method?name="count*"?propagation="REQUIRED"?read-only="true"?/> ??
  • ????????<tx:method?name="find*"?propagation="REQUIRED"?read-only="true"?/> ??
  • ????????<tx:method?name="list*"?propagation="REQUIRED"?read-only="true"?/> ??
  • ????????<tx:method?name="*"?read-only="true"?/> ??
  • ????</tx:attributes> ??
  • </tx:advice> ??
  • <aop:config?expose-proxy="true"> ??
  • ????<!--?只對業務邏輯層實施事務?--> ??
  • ????<aop:pointcut?id="txPointcut"?expression="execution(*?cn.javass..service..*.*(..))"?/> ??
  • ????<aop:advisor?advice-ref="txAdvice"?pointcut-ref="txPointcut"/> ??
  • </aop:config>??
  • <tx:advice id="txAdvice" transaction-manager="txManager"><tx:attributes><tx:method name="save*" propagation="REQUIRED" /><tx:method name="add*" propagation="REQUIRED" /><tx:method name="create*" propagation="REQUIRED" /><tx:method name="insert*" propagation="REQUIRED" /><tx:method name="update*" propagation="REQUIRED" /><tx:method name="merge*" propagation="REQUIRED" /><tx:method name="del*" propagation="REQUIRED" /><tx:method name="remove*" propagation="REQUIRED" /><tx:method name="put*" propagation="REQUIRED" /><tx:method name="use*" propagation="REQUIRED"/><!--hibernate4必須配置為開啟事務 否則 getCurrentSession()獲取不到--><tx:method name="get*" propagation="REQUIRED" read-only="true" /><tx:method name="count*" propagation="REQUIRED" read-only="true" /><tx:method name="find*" propagation="REQUIRED" read-only="true" /><tx:method name="list*" propagation="REQUIRED" read-only="true" /><tx:method name="*" read-only="true" /></tx:attributes></tx:advice><aop:config expose-proxy="true"><!-- 只對業務邏輯層實施事務 --><aop:pointcut id="txPointcut" expression="execution(* cn.javass..service..*.*(..))" /><aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/></aop:config>

    ?

    此處一定注意 使用 hibernate4,在不使用OpenSessionInView模式時,在使用getCurrentSession()時會有如下問題:

    ?

    當有一個方法list 傳播行為為Supports,當在另一個方法getPage()(無事務)調用list方法時會拋出org.hibernate.HibernateException: No Session found for current thread 異常。

    這是因為getCurrentSession()在沒有session的情況下不會自動創建一個,不知道這是不是Spring3.1實現的bug,歡迎大家討論下。

    ?

    因此最好的解決方案是使用REQUIRED的傳播行為。

    ?

    ?

    二、spring-servlet.xml:

    2.1、表現層配置文件,只應加裝表現層Bean,否則可能引起問題。

    ?

    java代碼: Java代碼 ?
  • <!--?開啟controller注解支持?--> ??
  • <!--?注:如果base-package=cn.javass?則注解事務不起作用--> ??
  • <context:component-scan?base-package="cn.javass.demo.web.controller"> ??
  • ????<context:include-filter?type="annotation"?expression="org.springframework.stereotype.Controller"/> ??
  • </context:component-scan>??
  • <!-- 開啟controller注解支持 --><!-- 注:如果base-package=cn.javass 則注解事務不起作用--><context:component-scan base-package="cn.javass.demo.web.controller"><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan>

    ?

    此處只應該加載表現層組件,如果此處還加載dao層或service層的bean會將之前容器加載的替換掉,而且此處不會進行AOP織入,所以會造成AOP失效問題(如事務不起作用),再回頭看我們的1.4討論的。

    ?

    ?

    2.2、<mvc:view-controller path="/"?view-name="forward:/index"/> 表示當訪問主頁時自動轉發到index控制器。

    ?

    ?

    2.3、靜態資源映射

    ?

    java代碼: Java代碼 ?
  • <!--?當在web.xml?中???DispatcherServlet使用?????<url-pattern>/</url-pattern>?映射時,能映射靜態資源?--> ??
  • <mvc:default-servlet-handler/> ??
  • <!--?靜態資源映射?--> ??
  • <mvc:resources?mapping="/images/**"?location="/WEB-INF/images/"?/> ??
  • <mvc:resources?mapping="/css/**"?location="/WEB-INF/css/"?/> ??
  • <mvc:resources?mapping="/js/**"?location="/WEB-INF/js/"?/>??
  • <!-- 當在web.xml 中 DispatcherServlet使用 <url-pattern>/</url-pattern> 映射時,能映射靜態資源 --><mvc:default-servlet-handler/><!-- 靜態資源映射 --><mvc:resources mapping="/images/**" location="/WEB-INF/images/" /><mvc:resources mapping="/css/**" location="/WEB-INF/css/" /><mvc:resources mapping="/js/**" location="/WEB-INF/js/" />

    以上是配置文件部分,接下來來看具體代碼。

    ?

    ?

    三、通用DAO層Hibernate4實現

    為了減少各模塊實現的代碼量,實際工作時都會有通用DAO層實現,以下是部分核心代碼:

    ?

    java代碼: Java代碼 ?
  • public?abstract?class?BaseHibernateDao<M?extends?java.io.Serializable,?PK?extends?java.io.Serializable>?implements?IBaseDao<M,?PK>?{ ??
  • ? ??
  • ????protected?static?final?Logger?LOGGER?=?LoggerFactory.getLogger(BaseHibernateDao.class); ??
  • ? ??
  • ????private?final?Class<M>?entityClass; ??
  • ????private?final?String?HQL_LIST_ALL; ??
  • ????private?final?String?HQL_COUNT_ALL; ??
  • ????private?final?String?HQL_OPTIMIZE_PRE_LIST_ALL; ??
  • ????private?final?String?HQL_OPTIMIZE_NEXT_LIST_ALL; ??
  • ????private?String?pkName?=?null; ??
  • ? ??
  • ????@SuppressWarnings("unchecked") ??
  • ????public?BaseHibernateDao()?{ ??
  • ????????this.entityClass?=?(Class<M>)?((ParameterizedType)?getClass().getGenericSuperclass()).getActualTypeArguments()[0]; ??
  • ????????Field[]?fields?=?this.entityClass.getDeclaredFields(); ??
  • ????????for(Field?f?:?fields)?{ ??
  • ????????????if(f.isAnnotationPresent(Id.class))?{ ??
  • ????????????????this.pkName?=?f.getName(); ??
  • ????????????} ??
  • ????????} ??
  • ??????? ??
  • ????????Assert.notNull(pkName); ??
  • ????????//TODO?@Entity?name?not?null ??
  • ????????HQL_LIST_ALL?=?"from?"?+?this.entityClass.getSimpleName()?+?"?order?by?"?+?pkName?+?"?desc"; ??
  • ????????HQL_OPTIMIZE_PRE_LIST_ALL?=?"from?"?+?this.entityClass.getSimpleName()?+?"?where?"?+?pkName?+?"?>???order?by?"?+?pkName?+?"?asc"; ??
  • ????????HQL_OPTIMIZE_NEXT_LIST_ALL?=?"from?"?+?this.entityClass.getSimpleName()?+?"?where?"?+?pkName?+?"?<???order?by?"?+?pkName?+?"?desc"; ??
  • ????????HQL_COUNT_ALL?=?"?select?count(*)?from?"?+?this.entityClass.getSimpleName(); ??
  • ????} ??
  • ??????? ??
  • ????@Autowired??
  • ????@Qualifier("sessionFactory") ??
  • ????private?SessionFactory?sessionFactory; ??
  • ? ??
  • ????public?Session?getSession()?{ ??
  • ????????//事務必須是開啟的,否則獲取不到 ??
  • ????????return?sessionFactory.getCurrentSession(); ??
  • ????} ??
  • …… ??
  • }??
  • public abstract class BaseHibernateDao<M extends java.io.Serializable, PK extends java.io.Serializable> implements IBaseDao<M, PK> {protected static final Logger LOGGER = LoggerFactory.getLogger(BaseHibernateDao.class);private final Class<M> entityClass;private final String HQL_LIST_ALL;private final String HQL_COUNT_ALL;private final String HQL_OPTIMIZE_PRE_LIST_ALL;private final String HQL_OPTIMIZE_NEXT_LIST_ALL;private String pkName = null;@SuppressWarnings("unchecked")public BaseHibernateDao() {this.entityClass = (Class<M>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];Field[] fields = this.entityClass.getDeclaredFields();for(Field f : fields) {if(f.isAnnotationPresent(Id.class)) {this.pkName = f.getName();}}Assert.notNull(pkName);//TODO @Entity name not nullHQL_LIST_ALL = "from " + this.entityClass.getSimpleName() + " order by " + pkName + " desc";HQL_OPTIMIZE_PRE_LIST_ALL = "from " + this.entityClass.getSimpleName() + " where " + pkName + " > ? order by " + pkName + " asc";HQL_OPTIMIZE_NEXT_LIST_ALL = "from " + this.entityClass.getSimpleName() + " where " + pkName + " < ? order by " + pkName + " desc";HQL_COUNT_ALL = " select count(*) from " + this.entityClass.getSimpleName();}@Autowired@Qualifier("sessionFactory")private SessionFactory sessionFactory;public Session getSession() {//事務必須是開啟的,否則獲取不到return sessionFactory.getCurrentSession();} …… }

    Spring3.1集成Hibernate4不再需要HibernateDaoSupport和HibernateTemplate了,直接使用原生API即可。

    ?

    ?

    四、通用Service層代碼?此處省略,看源代碼,有了通用代碼后CURD就不用再寫了。

    ?

    java代碼: Java代碼 ?
  • @Service("UserService") ??
  • public?class?UserServiceImpl?extends?BaseService<UserModel,?Integer>?implements?UserService?{ ??
  • ? ??
  • ????private?static?final?Logger?LOGGER?=?LoggerFactory.getLogger(UserServiceImpl.class); ??
  • ? ??
  • ????private?UserDao?userDao; ??
  • ? ??
  • ????@Autowired??
  • ????@Qualifier("UserDao") ??
  • ????@Override??
  • ????public?void?setBaseDao(IBaseDao<UserModel,?Integer>?userDao)?{ ??
  • ????????this.baseDao?=?userDao; ??
  • ????????this.userDao?=?(UserDao)?userDao; ??
  • ????} ??
  • ??? ??
  • ? ??
  • ? ??
  • ????@Override??
  • ????public?Page<UserModel>?query(int?pn,?int?pageSize,?UserQueryModel?command)?{ ??
  • ????????return?PageUtil.getPage(userDao.countQuery(command)?,pn,?userDao.query(pn,?pageSize,?command),?pageSize); ??
  • ????} ??
  • } ??
  • ???
  • @Service("UserService") public class UserServiceImpl extends BaseService<UserModel, Integer> implements UserService {private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);private UserDao userDao;@Autowired@Qualifier("UserDao")@Overridepublic void setBaseDao(IBaseDao<UserModel, Integer> userDao) {this.baseDao = userDao;this.userDao = (UserDao) userDao;}@Overridepublic Page<UserModel> query(int pn, int pageSize, UserQueryModel command) {return PageUtil.getPage(userDao.countQuery(command) ,pn, userDao.query(pn, pageSize, command), pageSize);} }

    ?

    ?

    ?

    五、表現層?Controller實現

    采用SpringMVC支持的REST風格實現,具體看代碼,此處我們使用了java Validator框架 來進行 表現層數據驗證

    ?

    在Model實現上加驗證注解

    ?

    ?

    java代碼: Java代碼 ?
  • @Pattern(regexp?=?"[A-Za-z0-9]{5,20}",?message?=?"{username.illegal}")?//java?validator驗證(用戶名字母數字組成,長度為5-10) ??
  • private?String?username; ??
  • ??
  • @NotEmpty(message?=?"{email.illegal}") ??
  • @Email(message?=?"{email.illegal}")?//錯誤消息會自動到MessageSource中查找 ??
  • private?String?email; ??
  • ??
  • @Pattern(regexp?=?"[A-Za-z0-9]{5,20}",?message?=?"{password.illegal}") ??
  • private?String?password; ??
  • ??
  • @DateFormat(?message="{register.date.error}")//自定義的驗證器 ??
  • private?Date?registerDate;??
  • @Pattern(regexp = "[A-Za-z0-9]{5,20}", message = "{username.illegal}") //java validator驗證(用戶名字母數字組成,長度為5-10)private String username;@NotEmpty(message = "{email.illegal}")@Email(message = "{email.illegal}") //錯誤消息會自動到MessageSource中查找private String email;@Pattern(regexp = "[A-Za-z0-9]{5,20}", message = "{password.illegal}")private String password;@DateFormat( message="{register.date.error}")//自定義的驗證器private Date registerDate;

    ?

    在Controller中相應方法的需要驗證的參數上加@Valid即可

    ?

    java代碼: Java代碼 ?
  • @RequestMapping(value?=?"/user/add",?method?=?{RequestMethod.POST}) ??
  • public?String?add(Model?model,?@ModelAttribute("command")?@Valid?UserModel?command,?BindingResult?result)??
  • @RequestMapping(value = "/user/add", method = {RequestMethod.POST})public String add(Model model, @ModelAttribute("command") @Valid UserModel command, BindingResult result)

    ?

    ?

    六、Spring集成測試

    使用Spring集成測試能很方便的進行Bean的測試,而且使用@TransactionConfiguration(transactionManager = "txManager", defaultRollback = true)能自動回滾事務,清理測試前后狀態。

    ?

    java代碼: Java代碼 ?
  • @RunWith(SpringJUnit4ClassRunner.class) ??
  • @ContextConfiguration(locations?=?{"classpath:spring-config.xml"}) ??
  • @Transactional??
  • @TransactionConfiguration(transactionManager?=?"txManager",?defaultRollback?=?true) ??
  • public?class?UserServiceTest?{ ??
  • ??? ??
  • ????AtomicInteger?counter?=?new?AtomicInteger(); ??
  • ??? ??
  • ????@Autowired??
  • ????private?UserService?userService; ??
  • ????……?? ??
  • }??
  • @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:spring-config.xml"}) @Transactional @TransactionConfiguration(transactionManager = "txManager", defaultRollback = true) public class UserServiceTest {AtomicInteger counter = new AtomicInteger();@Autowiredprivate UserService userService;…… }

    ?

    其他部分請直接看源碼,歡迎大家討論。

    ?

    ?

    原創內容,轉載請注明私塾在線【http://sishuok.com/forum/blogPost/list/2625.html】

    ?

    與50位技術專家面對面20年技術見證,附贈技術全景圖

    總結

    以上是生活随笔為你收集整理的SpringMVC + spring3.1.1 + hibernate4.1.0 集成及常见问题总结的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。