记得是去年Java EE 5发布初期时,就兴致昂然的读了document,并且按照相关的refrence的说明,对jsf、ejb3.0、jpa等进行了应用,当时也是我自己先动手试验,部署时那个顺利啊。但是当我真正运用时,通过我打出来监控日志,发现jsf初始时对数据表进行的查询方式和消耗,使我完全回退了jsf的应用,当时在公司得出结论:
1、JSF成熟以后再用;
2、EJB3.0由于jboss和Sun Application Server的不统一,并且其他商用级服务器并不支持因此。暂缓使用;
3、唯一我们可以考虑采纳的是JPA,但是公司技术人员对原有的SSH的配置方式已经非常熟悉,没有必要为了“缩短开发周期”这个理论优点来改我们“已经实现好了的框架和系统”。
以上三点结论呈述后,当时使公司已有的一个使用JSF项目(那位项目经理力推JSF,并且能力值得赞许)也退出JSF的项目,使用公司成熟的Struts 1.2+Spring 1.2+Hibernate3.0。
这一次与上次相同了,我研究了几天了吧,搭建了Struts 2.0+Spring 2.0+Hibernate 3.3的应用,其中Hibernate 3.3应用的是JPA,Spring的结合方式也是使用JpaTransactionManager,具体的一些配置文件罗列如下:
xml 代码
- <!---->xml version="1.0" encoding="UTF-8"?>
- <persistence xmlns="http://java.sun.com/xml/ns/persistence"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
- http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
-
- <persistence-unit name="studioUnit" transaction-type="RESOURCE_LOCAL">
- <provider>org.hibernate.ejb.HibernatePersistenceprovider>
- <jta-data-source>java:comp/env/jdbc/oraclejta-data-source>
- <class>com.****.****.entity.WapConfigclass>
- <properties>
- <property name="hibernate.dialect"
- value="org.hibernate.dialect.Oracle9Dialect" />
- <property name="hibernate.show_sql" value="true" />
- <property name="hibernate.format_sql" value="true" />
- properties>
- persistence-unit>
-
- persistence>
以下是spring 2.0的配置:
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"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
-
- <bean
- class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
- <bean id="entityManagerFactory"
- class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
- <property name="loadTimeWeaver">
- <bean
- class="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver" />
- property>
- bean>
- <bean id="transactionManager"
- class="org.springframework.orm.jpa.JpaTransactionManager">
- <property name="entityManagerFactory"
- ref="entityManagerFactory" />
- bean>
- <tx:annotation-driven transaction-manager="transactionManager" />
-
- <bean id="wapConfigDao"
- class="com.***.***.dao.impl.JpaWapConfigDAOImpl">
- <property name="entityManagerFactory">
- <ref bean="entityManagerFactory" />
- property>
- bean>
- <bean id="wapConfigAction" scope="prototype"
- class="com.***.***.action.WapConfigAction">
- <constructor-arg ref="wapConfigDao" />
- bean>
-
- beans>
以下是struts.xml文件:
xml 代码
- <!---->xml version="1.0" encoding="UTF-8" ?>
-
- <!---->
- "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
- "http://struts.apache.org/dtds/struts-2.0.dtd">
-
-
- <struts>
-
-
- <constant name="struts.devMode" value="true" />
-
- <constant name="struts.objectFactory" value="spring" />
-
- <package name="default" extends="struts-default">
- <action name="list" method="execute" class="wapConfigAction">
- <result>/list.jspresult>
- <result name="input">/list.jspresult>
- action>
- <action name="remove" class="wapConfigAction" method="remove">
- <result>/list.jspresult>
- <result name="input">/list.jspresult>
- action>
-
- <action name="save" class="wapConfigAction" method="save">
- <result>/list.jspresult>
- <result name="input">/list.jspresult>
- action>
- package>
-
- struts>
-
-
-
以下是tiles.xml 文件
xml 代码
- <!---->xml version="1.0" encoding="GBK" ?>
- <!---->
- "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
- "http://struts.apache.org/dtds/tiles-config_2_0.dtd">
-
- <tiles-definitions>
-
- <!---->name="showcase.index" template="/tiles/layout.jsp">
- <put-attribute name="title" value="测试用标题"/>
- <put-attribute name="header" value="/tiles/header.jsp"/>
- <put-attribute name="body" value="/tiles/body.jsp"/>
- definition>
-
- <definition name="showcase.freemarker" template="/tiles/layout.jsp">
- <put-attribute name="title" value="Tiles/Freemarker Showcase"/>
- <put-attribute name="header" value="/tiles/header.jsp"/>
- <put-attribute name="body" value="/tiles/body.ftl"/>
- definition-->
-
- tiles-definitions>
以下是通用的一段dao代码的片段,采用的是spring的jpatemplate,所以没有声明PersistenceContext:
java 代码
- package com.***.common.spring.impl;
-
- import java.util.List;
-
- import org.apache.log4j.Logger;
- import org.springframework.orm.jpa.support.JpaDaoSupport;
- import org.springframework.transaction.annotation.Transactional;
-
- import com.**.common.jpa.BaseEntity;
- import com.**.common.spring.BaseDao;
-
- @Transactional
- public class JpaDaoImpl extends JpaDaoSupport implements BaseDao {
- private Logger log = Logger.getLogger(getClass());
-
-
-
-
-
-
-
-
-
- private Class claz;
- public JpaDaoImpl(Class z){
- super();
- claz = z;
- }
- public List find(String sql) {
- }
-
- public void saveOrUpdate(BaseEntity obj){
- if ( obj.id == null )
-
- getJpaTemplate().persist(obj);
- else
-
- getJpaTemplate().merge(obj);
- }
-
- public void remove(BaseEntity obj) {
- if (obj != null)
-
- getJpaTemplate().remove(obj);
- }
-
-
-
-
-
-
-
-
-
-
- public void remove(Long id, String table) {
- getJpaTemplate().getEntityManager().createNativeQuery(
- "DELETE FROM " + table + " WHERE ID=" + id).executeUpdate();
- }
-
- public BaseEntity get(Long id) {
- return (BaseEntity)getJpaTemplate().find(claz, id);
- }
-
- }
WapConfig这个实体的主要声明代码如下:
java 代码
-
- @Id
- @Column(name = "ID", unique = true, nullable = false, insertable = true, updatable = true, precision = 6, scale = 0)
- private Long id;
-
- @Column(name = "KEY", unique = false, nullable = false, insertable = true, updatable = true, length = 100)
- private String key;
-
- @Column(name = "VALUE", unique = false, nullable = true, insertable = true, updatable = true, length = 100)
- private String value;
-
- @Column(name = "MEM", unique = false, nullable = true, insertable = true, updatable = true, length = 500)
- private String mem;
写出来时,是平淡无奇,可以说以上这样的配置与代码是我完整的配置,直到最后tiles的配置,能够正常跑了——注意,是在JPA不读数据的情况下能正常跑的。
说能跑,也不是那么顺利的能跑的,碰到很多问题,都通过官方文档和在网络搜寻同行人员的经验,得到了解决,单说这最后一个变态的情况,当我代码读JPA实体时,如调用上面的代码:
java 代码
- List wapConfigs = dao.find(" FROM WapConfig";
本想可以得出一个结果集,即使是空值,但实际结果是能过控制台得知,发到Oracle的查询语句变成了这样的:
sql 代码
- SELECT __wapConfig0.ID as ID,
- __wapConfig0.__amber_0.ID as __amber_0.ID,
- __wapConfig0.__amber_0.KEY as __amber_0.KEY,
- __wapConfig0.__amber_0.VALUE as __amber_0.VALUE,
- __wapConfig0.__amber_0.MEM as __amber_0.MEM,
- __wapConfig0.KEY as KEY,
- __wapConfig0.VALUE as VALUE,
- __wapConfig0.MEM as MEM
- FROM
- WapConfig __wapConfig0
注意看,我的实体根本是没有__amber_0.**这样的字段的,说不清这个字段究竟是哪里冒出来的。兼于前面坎坎坷坷的碰到很多问题,我尝试解决未果后,思考的问题就不再局限在技术层面了。
首先Struts 2单说他的taglig、OGNL、Action、Spring支持的改进,Hibernate JPA的支持,Spring对JPA的支持,都是非常的诱人的,特别对我这种技术型的人员,有很强的攻克他的欲望。就这个各个组件扔出来的思路和方向对我们来说都是很有利的,我相信各个组件成熟后,我将来一定采用这个更优秀的框架。
但是现在,我大致发现一些我认为存在的问题:
1、Struts2对tiles的支持目前我认为做得没有struts1好,而这对于团队开发、技术与美工的协作来说,是相当受重视的优点的一部份;
3、Struts 2.0.6GA的说明文档不够齐全,也就是说他还可能存在完善的方面;
2、Hibernate对JPA支持方面不是很稳定;至少从已知问题来说,这个结论可能是由于我不继续深究下去而得出的错误结论。
就目前来看,我认为最稳定的部份还是spring2。
脱开技术层面来看问题,公司400人左右都习惯于现有的的研发平台的使用方法,如果新框架存在这样那样的对“配置依赖性相当脆弱”的情况,新技术的采用会对各方面不可避免的带来新的培训成本和高技术风险,并且更为关键的是现有人员都对SSH烂熟于胸了。这个熟练应该暂时可以抵消Struts2和Hibernate JPA的优势,至少在目前新框架不稳定的情况下。
我的结论是:新技术不急着采用,我们不急着做新技术的急先锋,也没必要做第一个吃螃蟹的人。可以等社会上已经出相关书籍,已经有相关的培训课程安排后我们再同步推出更新的SSH2框架,那时,我们现有的技术人员本身有机会在工作之外通过书籍、实践获得新知识,我们再安排新框架的培训,相信会让现有技术人员低成本较快过渡到新框架去。再者,社会上可以招聘到对新技术方案了解的人。
分享到:
相关推荐
**新技术应用** 指的是该项目可能采用了最新的Java技术或框架,例如Spring Boot、MyBatis、Thymeleaf等,以提高开发效率和系统的性能。Spring Boot简化了Spring应用的初始设置和配置,MyBatis提供了一种更轻量级的...
采用SSH框架开发的系统。采用SSH框架开发的系统。
- **步骤1**: 在SSH2机器上的用户主目录下创建`.ssh2`子目录,如果该目录已存在,则直接进入该目录。 - **步骤2**: 生成或修改`authorization`文件,添加OpenSSH转换后的公钥信息: ``` echo "Key id_rsa_SSH2....
SSH2框架,全称为Spring、Struts2和Hibernate2的集成框架,是Java Web开发中的一个常见组合。这个实例源码使用的是Spring 3.2、Struts2 2.3.4和Hibernate 4.2这三个框架的较新版本,提供了一个基础的用户登录和用户...
ssh2完整项目ssh2完整项目ssh2完整项目ssh2完整项目ssh2完整项目ssh2完整项目ssh2完整项目ssh2完整项目ssh2完整项目ssh2完整项目ssh2完整项目ssh2完整项目ssh2完整项目ssh2完整项目ssh2完整项目ssh2完整项目ssh2完整...
在IT行业中,s2sh和ssh2是两种常见的技术,它们在不同的领域发挥着重要的作用。s2sh通常指的是Struts2、Spring和Hibernate这三个开源框架的集成,而ssh2则通常指的是Secure Shell(SSH)的第二版,用于提供安全的...
SSH2(Secure Shell 2)是一种网络协议,用于在不安全的网络上提供安全的远程登录和其他服务。在Java开发中,SSH2通常指的是通过Java实现的SSH2库,允许开发者构建支持SSH2协议的应用程序,例如进行远程系统管理、...
这个“SSH2入门项目”显然是为初学者设计的,旨在帮助他们理解和应用SSH2技术。SSH2是SSH协议的第二版,提供了加密、身份验证和数据完整性检查,广泛用于网络管理、文件传输以及远程命令执行。 SSH2的核心功能包括...
7. **性能优化**:为了提高效率,SSH2实现可能会采用各种性能优化技术,例如缓存、并行处理等。 通过研究这个“ssh2项目源码”,开发者不仅可以了解SSH2协议的细节,还可以学习到如何在实际项目中实现和应用这些...
标题“ssh2_for_php5.6”所指的是一种在PHP 5.6环境中使用SSH2(Secure Shell Version 2)协议进行远程操作和管理的技术。SSH2是一种网络协议,常用于安全地执行命令、传输文件和管理远程服务器。在这个上下文中,...
《Trilead SSH2 for Java:深度解析与实践指南》 在Java开发中,安全通信是不可或缺的一部分,尤其是在远程操作、文件传输等场景下。Trilead SSH2库为Java开发者提供了一套强大的SSH(Secure Shell)实现,使得在...
3. **密钥交换**:SSH2采用了Diffie-Hellman(DH)或ECDH(Elliptic Curve Diffie-Hellman)等密钥交换算法,确保即使中间人能截取通信,也无法解密数据。 4. **通道 multiplexing**:SSH2支持多通道复用,即在一个...
**Node.js SSH2 模块详解** 在 IT 领域,Node.js 是一个非常流行的 JavaScript 运行环境,它允许开发者使用 JavaScript 进行后端开发。在 Node.js 的生态系统中,`ssh2` 是一个强大的库,它提供了一个SSH2协议的...
在这个实例中,我们将探讨如何使用SSH2协议实现远程服务器的安全登录,以及相关的技术要点。 首先,SSH2是SSH协议的第二版,它在安全性上进行了增强,提供了数据加密、密钥交换和身份验证等核心功能。SSH2Login的...
在本项目中,"Node.js-WebSSH2基于Web的SSH2客户端使用xterm.js、socket.io和ssh2实现",我们关注的是构建一个在浏览器环境中运行的SSH2客户端。这个客户端允许用户通过Web界面安全地连接到远程服务器执行命令,从而...
SSH2是一种网络协议,提供安全的网络服务,比如在不安全的网络环境中进行加密通信。 描述中提到的"ssh2BaseJar 空项目三大框架空项目"可能是指一个基于SSH2的Java项目模板,它包含了用于搭建Java应用的三个主要框架...
描述中的"oracle与ssh2技术的整合,简洁易懂"意味着这份资料可能详细介绍了如何将这两种技术结合在一起,为用户提供了一个简单明了的学习路径。这通常涉及到配置SSH2客户端(如OpenSSH或PuTTY),设置服务器上的SSH...
libssh2是一个开源的C语言实现的SSH协议库,支持SSH1和SSH2两种协议。它为开发者提供了丰富的API,用于实现SSH连接、身份验证、通道管理和会话操作等功能。在Windows上使用libssh2,可以构建跨平台的SSH客户端软件,...
ssh ssh shhs ssh ssh shhs ssh ssh shhs ssh ssh shhs ssh ssh shhs ssh ssh shhs ssh ssh shhs ssh ssh shhs ssh ssh shhs ssh ssh shhs ssh ssh shhs ssh ssh shhs ssh ssh shhs ssh ssh shhs ssh ssh shhs ssh ...