摘要: 前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识。通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的。
总结如下:
Spring配置文件中关于事务配置总是由三个组成部分,分别是Data...
阅读全文
posted @
2009-04-05 16:38 The Matrix 阅读(330998) |
评论 (85) |
编辑 收藏
今天在Javaeye的新闻频道看到一个界面原型绘制工具,叫做“wireframesketcher”,下载试了试,感觉有如下几个好处:
1、使用方便,可以很容易的做tree和table,比visio中的tree和table好用
2、集成在eclipse中,对于开发人员来说用起来更直接
3、其界面原型文件为xml格式,可以使用比较工具比较
唯一的缺点:
不是免费开源的工具,但是现在可以申请免费的license
随便画了一个图,如下:
感兴趣的兄弟姐妹们可以到如下地址看看:
http://wireframesketcher.com/index.html
posted @
2009-03-28 21:55 The Matrix 阅读(4599) |
评论 (1) |
编辑 收藏
由于要写一个Spring的培训教材,要做Spring的事务样例,于是开始写样例,写好了一测,控制台有SQL输出,数据库却查询不到数据,查亚查亚,花了一个多小时,原来是获取的Service不是经过代理的Service,自然事务不起作用,数据库里就没有数据了,鄙视一下自己。
配置文件样例如下(已经修改了dao和service的命名,减少了写错的可能性,以后命名问题一定要注意):
<?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"
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.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<context:annotation-config />
<context:component-scan base-package="com.*" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
</bean>
<!-- 定义事务管理器(声明式的事务) -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 配置DAO -->
<bean id="generatorDaoTarget" class="com.*.spring.dao.GeneratorDaoImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="generatorDao"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!-- 配置事务管理器 -->
<property name="transactionManager"><ref bean="transactionManager" /></property>
<property name="target"><ref bean="generatorDaoTarget" /></property>
<property name="proxyInterfaces"><value>com.*.spring.dao.GeneratorDao</value></property>
<!-- 配置事务属性 -->
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="plantDaoTarget" class="com.*.spring.dao.PlantDaoImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="plantDao"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!-- 配置事务管理器 -->
<property name="transactionManager"><ref bean="transactionManager" /></property>
<property name="target"><ref bean="plantDaoTarget" /></property>
<property name="proxyInterfaces"><value>com.*.spring.dao.PlantDao</value></property>
<!-- 配置事务属性 -->
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!-- 配置Service -->
<bean id="plantGeneratorServiceTarget"
class="com.*.spring.service.PlantGeneratorServiceImpl">
<property name="plantDao">
<ref bean="plantDao" />
</property>
<property name="generatorDao">
<ref bean="generatorDao" />
</property>
</bean>
<bean id="plantGeneratorService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!-- 配置事务管理器 -->
<property name="transactionManager"><ref bean="transactionManager" /></property>
<property name="target"><ref bean="plantGeneratorServiceTarget" /></property>
<property name="proxyInterfaces"><value>com.*.spring.service.PlantGeneratorService</value></property>
<!-- 配置事务属性 -->
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 各属性的配置-->
<!-- 为true表示将Hibernate发送给数据库的sql显示出来 -->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">none</property>
<!-- SQL方言,这边设定的是MySQL -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!--连接数据库的Driver-->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<!--数据库连接url-->
<property name="connection.url">jdbc:mysql://localhost:3306/test</property>
<!--用户名-->
<property name="connection.username">root</property>
<!--密码-->
<property name="connection.password">123456</property>
<!-- 映射文件 -->
<mapping class="com.*.spring.domain.Generator" />
<mapping class="com.*.spring.domain.Plant" />
</session-factory>
</hibernate-configuration>
public interface GeneratorDao {
/**
* 获取所有机组数据
* @return
*/
public List<Generator> listGenerators();
/**
* 保存机组数据
* @param generator 机组数据
*/
public void save(Generator generator);
}
public class GeneratorDaoImpl extends HibernateDaoSupport implements GeneratorDao {
@SuppressWarnings("unchecked")
public List<Generator> listGenerators() {
return this.getSession().createQuery("from Generator").list();
}
public void save(Generator generator) {
this.getSession().save(generator);
}
}
posted @
2009-03-16 22:24 The Matrix 阅读(1543) |
评论 (0) |
编辑 收藏
给自己做的这个程序起了个名字叫EasyWork,代码可以从Google Code上下载,具体地址如下:
http://easywork.googlecode.com/svn/trunk/
由于时间关系,这个程序还存在不少问题,所以只能供大家参考,有问题不要骂我就行了:)
简要使用说明:
1、开发环境+运行环境:MyEclipse6.0,JDK1.5,Tomcat6.0.14,MySQL5.0
2、准备好上述环境后,使用下载代码sql目录中的easywork_init.sql脚本创建数据库表和初始数据。
3、将项目导入Eclipse后,运行Tomcat(此过程就不详细描述了)。
4、使用http://localhost/easywork/system/login.jsp访问登录页面,目前还没有做index.html,默认用户名/密码:admin/1。
存在问题如下:
1、任务管理功能还没有完全完成,日志记录还没有做。
2、超时或者没有登录访问页面时,只是报不能访问的异常,没有转入登录页面。
3、对资源类型(菜单、URL、字段、操作)的访问限制还没有做。
4、很多界面的输入信息校验没有做。
5、基本没有美工。
6、总而言之,目前这个项目中的代码只能做Struts2 + ExtJS如何使用的借鉴:)
posted @
2009-03-01 11:03 The Matrix 阅读(6272) |
评论 (28) |
编辑 收藏
很近没有更新BLog了,这一阵子忙着学习Struts2和ExtJS,使用这两者做了一个小程序,使用RBAC实现了基本的权限管理功能,还做了一个任务管理和日志记录,任务管理用于记录当前需要处理的事情,日志记录用于记录每天的工作情况。
用下来Struts2和ExtJS还是挺好用的。先贴几张图,后续再把学习过程中遇到的问题整理出来。
任务管理
添加组
添加权限
添加角色
posted @
2009-02-26 07:14 The Matrix 阅读(4306) |
评论 (15) |
编辑 收藏
由于前段时间使用JSF做了一个项目,不少使用JSF的兄弟们对JSF评价并不好,因此在学习的过程中一直在想,JSF究竟是不是应该继续学习继续研究使用下去,在看完Seam In Action的第三章后,这个星期又对Struts2简单学习了一下,终于决定结束JSF和JBoss Seam的学习了。
因为从JSF的学习和Struts2的学习对比中明显觉得JSF复杂,对于一个技术力量不是非常强的项目组来说,使用JSF当你遇到一些问题时,绝对是一件痛苦的事情。
从自己的实践中觉得JSF至少有两个致命伤:
1、觉得JSF貌似把简单的事情搞得复杂化了,在传统的MVC框架如Struts中,从request中获取param很容易,也可以将param封装为对象,在JSF中,希望将这一切都模型化,一切都以组件为中心,类似于Swing的架构,但是http的无状态以及web的本质,使得一般JSF只能将组件树存放在服务端,同时又不能象CS程序那样方便的查看组件的状态、属性等信息。对于通常情况来说,JSF将其封装的很好,不用我们开发者操心,但是当遇到一些问题时,对于开发者想去调试查看问题时,问题就显得很复杂了。
2、JSF的自定义组件感觉超复杂,难度应该比当年自定义JSP标签更要高,试想一下,如果哪个组件不合意了,想改一下,还是比较困难的,除非对JSF组件有相当的深入了解。
顺便把项目中遇到的一个RichFaces的缺点列出来:
RichFaces在生成组件的html时,大量使用了Div,曾经有过一个页面有1千多行(在一个table中),页面上还有一个RichFaces的下拉菜单,从而导致菜单响应非常之慢,后来只有将rich:datatable换为普通的html:table,就没有问题了。
再看看Seam In Action中总结的JSF的缺点:
1、在JSF中初次请求的处理流程太过简单,而后续请求则执行了完整的复杂的处理流程。在JSF中假设第一个调用应该是在页面被渲染后执行,但实际中有时我们需要在第一次请求时就执行某些操作。在JSF中缺少象Struts中的Controller。
2、所有的请求都是POST。浏览器处理POST请求是比较草率,当用户执行了一个JSF Action操作后,点击浏览器的刷新按钮时,浏览器会询问用户是否重新提交,这会令用户非常困惑。
3、仅仅拥有简单基础的页面导向机制。
4、过度复杂的生命周期。
JBossSeam宣称对于JSF存在的缺点都提供了解决方法,但是有一种更复杂的感觉。
在Seam中,生成选择的项目时,有EAR和WAR的选项,如果选择了EAR选项,那么Seam会生成四个项目,分别为war、ear、ejb、test四个类型的项目。有一次我将生成的项目从一个目录拷贝到另一个目录,切换了Eclipse的workspace,此时问题来了,ejb项目提示编译错误,提示无法找到某些class,找来找去找来找去......后来将项目关闭了一下,再打开错误提示就没有了。
由这个问题我忽然想到,使用Seam集成JSF、EJB是不是太重量级了,如果采用EJB作为替代普通的POJO,对于一个小型的项目组来说,一般的规模就是三至五个人(我个人的理解),开发人员本来就不多,还要面对Seam划分的四个项目,好像比较繁琐,当然采用war模式另当别论。
相比较而言,这个星期看了一些Struts2的资料,觉得Struts2的架构非常清晰,易于理解。
翻了很早之前的JavaEye上的一个帖子,提到JSF是面向开发工具的,如果能做到象VB那样,就大有前途了,4年过去了,不要提JSF的开发工具了,就是Java各个方面的GUI开发工具,又有哪个能和VB相比呢,看来选择JSF作为一个方向不是一个好选择........还是及早放弃吧,哎...
最后我觉得可以用这么一句话可以形容JSF,看起来很美,用起来不爽。
posted @
2008-12-25 23:35 The Matrix 阅读(2313) |
评论 (6) |
编辑 收藏
这个事情去年做过一次,不过没有留下记录,今天又要做一次,记录下来,呵呵
环境:
Spring版本为1.2,Tomcat为5.5.26,JDK为Jdk1.5.0_11。
1、下载Axis1.4,解压后将其jar文件添加到web项目的lib目录中。
2、配置Axis Servlet,在web.xml文件中加入如下信息:
<servlet>
<servlet-name>AxisServlet</servlet-name>
<servlet-class>
org.apache.axis.transport.http.AxisServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/servlet/AxisServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>*.jws</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
3、编写java类,样例如下。
接口:
public interface InterchangeDataService {
public String getMonthInterchange(String marketDate);
}
实现类:
public class InterchangeDataServiceImpl extends ServletEndpointSupport implements InterchangeDataService {
public InterchangeDataServiceImpl() {
}
public String getMonthInterchange(String marketDate) {
return "getMonthInterchange";
}
}
注意实现类需要继承ServletEndpointSupport类,该类是由Spring提供的。
4、配置service-config.wsdd。
<?xml version="1.0" encoding="utf-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder"/>
<handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/>
<service name="interchangeDataService" provider="java:RPC" style="rpc" use="literal">
<parameter name="wsdlTargetNamespace" value="urn:soap.axisspring"/>
<parameter name="className" value="com.ecgit.eccm.webservice.InterchangeDataServiceImpl"/>
<parameter name="allowedMethods" value="*"/>
</service>
<transport name="http">
<requestFlow>
<handler type="URLMapper"/>
<handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/>
</requestFlow>
<parameter name="qs:list" value="org.apache.axis.transport.http.QSListHandler"/>
<parameter name="qs:wsdl" value="org.apache.axis.transport.http.QSWSDLHandler"/>
<parameter name="qs:method" value="org.apache.axis.transport.http.QSMethodHandler"/>
</transport>
<transport name="local">
<responseFlow>
<handler type="LocalResponder"/>
</responseFlow>
</transport>
</deployment>
5、测试web service服务,代码如下。
至项目的WEB-INF目录下,执行如下命令:
Java -Djava.ext.dirs=lib org.apache.axis.wsdl.WSDL2Java http://localhost:8080/axis/services/interchangeDataService?WSDL
会在WEB-INF目录中生成四个JAVA文件,它们分别是:
- InterchangeDataServiceImpl.java 定义了Web服务接口,接口中的方法与InterchangeDataService中的方法一致。
- InterchangeDataServiceImplService.java 定义了用于获取Web服务接口的方法。
- InterchangeDataServiceImplServiceLocator.java 接口InterchangeDataServiceImplService的具体实现。
- InterchangeDataServiceImplSoapBindingStub.java Web服务客户端桩,通过该类与服务器交互。
最后编写一个Main方法,调用如下方法即可进行测试:
InterchangeDataServiceImplServiceLocator serviceLocator = new InterchangeDataServiceImplServiceLocator();
InterchangeDataServiceImpl service = serviceLocator.getinterchangeDataService();
String monthSchedule = service.getMonthInterchange("2008-05-30");
posted @
2008-12-19 17:16 The Matrix 阅读(3403) |
评论 (1) |
编辑 收藏
上次使用Seam自动生成了一个CRUD的例子,后来想还是自己白手起家做一个例子看看,于是开始动手。
首先使用JBossTools工具生成项目,在生成项目的向导中,如果项目类型选择ear,则会生成四个项目,分别对应war、ear、ejb、test,觉得这样太过繁琐,还是选择war类型,又想要不使用tomcat作为运行服务器吧,因为JBoss也不太熟悉。没想到这一试倒试出问题来了,如果完全使用向导生成项目,选择tomcat作为运行服务器,则项目根本无法运行起来,总是提示缺少这个jar,那个jar。好,又换回JBoss,没问题了。仔细看了一下,原来在自动生成项目的WebContent/WEB-INF/lib目录中,只有大概十几个jar,连Hibernate的jar都没有,而在JBoss的Server/default/lib目录下则什么jar都有,怪不得不出错。
第一个教训:还是先使用JBoss作为运行环境,等整个Seam都搞熟了,再配一个Tomcat的运行环境。
继续,将原来项目中的一个通用DAO和一个UserService拷贝过来,代码如下,启动服务器报错。分别为如下错误信息:
第二个错误解决:Caused by: java.lang.IllegalArgumentException: @PersistenceContext may only be used on session bean or message driven bean components: genericDao
既然提示@PersistenceContext只能用在SessionBean中,因为原来的代码是使用的Spring框架,想了好长时间,在WebContent/WEB-INF/component.xml中看到这么一段,那么是不是通过@In来注入entityManager呢,修改@PersistenceContext为@In,编辑器自动提示没有发现名称为em的Component(这点好像不错),于是再修改为@In("entityManager") ,重启服务器,该问题解决。
<persistence:managed-persistence-context name="entityManager" auto-create="true" entity-manager-factory="#{testEntityManagerFactory}"/>
第三个错误解决:Caused by org.jboss.seam.RequiredException with message: "@In attribute requires non-null value: userService.genericDao"
将UserService中的@In修改为@In(create = true, required = true)解决此问题。
解决上述几个问题后,自己的例子终于运行起来了 :-)
下一篇关于Seam In Action中对JSF的介绍及Seam如何增强JSF。
-------------------------------------------------------------------------------------------------
项目生成的代码被分为两个目录,分别为Action和Model目录,检查JBoss中项目部署的目录,发觉Action目录下的代码编译生成的class文件被存放至WEB-INF/dev目录下,Model目录下的代码编译生成的class文件被存放至WEB-INF/classes目录下,google了一下,发现在Seam Reference中提到这是Seam的增量式重部署,支持对JavaBean组件的增量重部署,可以加快编辑/编译/测试的速度。
代码如下:
public interface GenericDao {
public Object get(Class clazz, Serializable id);
public void save(Object object);
public void update(Object object);
public void remove(Class clazz, Serializable id);
public void remove(Object obj);
}
@Name("genericDao")
public class GenericDaoImpl implements GenericDao {
@PersistenceContext ----> @In("entityManager")
private EntityManager em;
public Object get(Class clazz, Serializable id) {
if (id == null) return null;
else return em.find(clazz, id);
}
}
public interface UserService {
public void findAllUsers();
}
@Name("userService")
public class UserServiceImpl implements UserService, SecurityUserService {
@In ----> @In(create = true, required = true)
protected GenericDao genericDao;
private List<User> resultList = null;
public List<User> getResultList() {
if (resultList == null) {
this.findAllUsers();
}
return resultList;
}
public void setResultList(List<User> resultList) {
this.resultList = resultList;
}
public void findAllUsers() {
String hql = "from User order by userCode";
resultList = this.genericDao.query(hql);
}
}
// 实体类
@Entity
@Table(name = "USER")
public class User implements IUser, Serializable {
// 用户编码
@Id
private String userCode;
// 用户姓名
private String userName;
}
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich"
template="layout/template.xhtml">
<ui:define name="body">
<rich:panel>
<f:facet name="header">User Search Results</f:facet>
<rich:dataTable id="userServiceTable"
var="user"
value="#{userService.resultList}">
<h:column>
<f:facet name="header">
<h:outputText value="UserCode"/>
</f:facet>
<h:outputText value="#{user.userCode}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="UserName"/>
</f:facet>
<h:outputText value="#{user.userName}"/>
</h:column>
</rich:dataTable>
</rich:panel>
</ui:define>
</ui:composition>
通过这个实践,小结一下:
1、发觉Seam确实简化了JSF开发,但由于它涉及的新东西相对较多,与传统的SSH走的路线不太一致,还是觉得其学习曲线比较陡峭,需要对Seam熟练掌握后(包括开发环境的搭建等)才能真正提高开发效率。
2、Seam提供了IOC的功能,有时需要跳出Spring,从一个新的角度去审视Seam。
posted @
2008-12-18 23:46 The Matrix 阅读(2156) |
评论 (0) |
编辑 收藏
这个星期的后半周主要搞了kettle的试验,做了两个例子出来,在后续工作中这两个例子应该也能派上用场,本来以为kettle的文档不多,后来单独下载了kettle的doc压缩包,发觉里面的内容还是不少的,真要将kettle搞熟的话,这些文档还是需要仔细研读一番的。另外kettle doc解压后文档目录挺奇怪的,都是数字命名的目录名,不知有啥具体含义。
下周的学习重点还是要转回到JBoss Seam中了 :-)
posted @
2008-12-14 22:13 The Matrix 阅读(1270) |
评论 (3) |
编辑 收藏
需求:
kettletest1数据库中有table_source数据表,结构如下:
- Id 主键
- t_id 数据时间
- part_id 实例ID
- yg 数据字段1
- wg 数据字段2
该表中的数据对于不同的实例ID,一分钟一条数据,t_id字段表示数据的时间,精确到分钟。
kettletest2数据库中有table_target数据表,结构如下:
- Id 主键
- marketdate 数据日期,格式为 yyyy-MM-dd
- pointtime 时间,格式为 HH:mm
- pointnumber 时间的数字表示,00:01表示为1,00:00表示为1440
- plantcode 实例Code
- yg 数据字段1
- wg 数据字段2
需定期将table_source表中的数据获取至table_target表中,并进行如下处理:
1、将t_id数据时间字段拆分为三个字段,分别为marketdate、pointtime、pointnumber。
a、marketdate取t_id的日期部分。
b、pointtime取t_id的时间部分。
c、pointnumber为时间的数字表示,等于hour*60+minute。
d、但当t_id的时间为某日的00:00时,需将其转化为24:00,并且marketdate需取日期的前一天。如t_id为2008-12-04 00:00,则marketdate为2008-12-03,pointtime为24:00,pointnumber为1440。
2、将part_id字段映射为plantcode字段,并根据如下规则进行转换:
part_id plantcode
3206 P01
3207 P02
3208 P03
测试中使用的数据库均为mysql数据库。
实战:
整个转换工作共分为三个步骤,如下图:
1、定义需获取的数据的日期
2、删除table_target表中已有数据,注意一定要将“执行SQl语句”面板中的“变量替换”要选上,否则SQL语句中的变量不会被替换,我刚开始没注意到这个地方,找问题找了半天。
3、获取table_source中的数据,并将其插入table_target表
3-1、获取table_source表的数据
3-2、值映射
3-3、字段选择
3-4、对t_id字段进行处理,增加了pointnumber字段。在这一步骤中发现kettle的一个bug,就是不能在JavaScript中使用str2date函数,错误的具体信息参见:http://jira.pentaho.com/browse/PDI-1827。这个问题也折腾了好长时间,刚开始怎么也想不通这个函数使用时怎么会报错呢,后来只好从字符串中截取年、月、日信息。
该步骤中还存在另外一个使人困惑的问题,就是点击“测试脚本”按钮,会报错,但是执行job和transformation时则不会报错。
3-5、增加pointnumber字段至输出结果中
3-6、插入数据至table_target表
3-4步骤中的JavaScript代码如下:
var pointTimeStr = pointtime.getString();
var pointnumber = 1;
if (pointTimeStr == "00:00") {
var marketDateStr = marketdate.getString();
var marketDateYear = substr(marketDateStr, 0, 4);
var marketDateMonth = str2num(substr(marketDateStr, 5, 2))-1;
var marketDateDay = substr(marketDateStr, 8, 2);
var date = new Date();
date.setYear(marketDateYear);
date.setMonth(marketDateMonth);
date.setDate(marketDateDay);
var temp1 = dateAdd(date, "d", -1);
marketdate.setValue(date2str(temp1, "yyyy-MM-dd"));
pointtime.setValue("24:00");
pointnumber = 1440;
} else {
var hourStr = pointTimeStr.substr(0, 2);
var hour = str2num(hourStr);
var minuteStr = pointTimeStr.substr(3, 5);
var minute = str2num(minuteStr);
pointnumber = hour * 60 + minute;
}
至此,整个转换工作完成,小结一下:
如果对kettle等etl工具比较熟悉的话,使用etl工具进行数据转换、抽取等事情还是比较方便的,比起写程序还是有优势的。但是这个转换过程中遇到的kettle的两个bug比较让人头疼,觉得kettle好像还不是很稳定。
posted @
2008-12-14 21:55 The Matrix 阅读(34298) |
评论 (5) |
编辑 收藏
这个实践其实不难,主要是有一个地方要注意,就是文件名通配符的写法,如果文件名格式为“TRANS_yyyymmdd.txt”,如TRANS_20081101.txt。如果想匹配所有以TRANS开头的文本文件,在kettle中要写成这样:TRANS_.*[0-9].txt。
最后在windows操作系统中配置定时任务就可以定期执行该Job了。
Job的图:
FTP配置信息:
posted @
2008-12-12 15:20 The Matrix 阅读(17025) |
评论 (0) |
编辑 收藏
一定要给SQL Server2000打上sp3a补丁,打上补丁后,使用telnet访问1433端口一切正常。
另外学了一个查询SQL Server版本的语句:select @@version
posted @
2008-12-12 12:07 The Matrix 阅读(1443) |
评论 (1) |
编辑 收藏
DATE_FORMAT(date,format)
根据format字符串格式化date值。下列修饰符可以被用在format字符串中: %M 月名字(January……December)
%W 星期名字(Sunday……Saturday)
%D 有英语前缀的月份的日期(1st, 2nd, 3rd, 等等。)
%Y 年, 数字, 4 位
%y 年, 数字, 2 位
%a 缩写的星期名字(Sun……Sat)
%d 月份中的天数, 数字(00……31)
%e 月份中的天数, 数字(0……31)
%m 月, 数字(01……12)
%c 月, 数字(1……12)
%b 缩写的月份名字(Jan……Dec)
%j 一年中的天数(001……366)
%H 小时(00……23)
%k 小时(0……23)
%h 小时(01……12)
%I 小时(01……12)
%l 小时(1……12)
%i 分钟, 数字(00……59)
%r 时间,12 小时(hh:mm:ss [AP]M)
%T 时间,24 小时(hh:mm:ss)
%S 秒(00……59)
%s 秒(00……59)
%p AM或PM
%w 一个星期中的天数(0=Sunday ……6=Saturday )
%U 星期(0……52), 这里星期天是星期的第一天
%u 星期(0……52), 这里星期一是星期的第一天
%% 一个文字“%”。
posted @
2008-12-10 09:18 The Matrix 阅读(731) |
评论 (0) |
编辑 收藏
看了Seam的例子,也看了Seam的简介,禁不住手痒,还是先做一个例子吧,遵照《seam_reference》第三章中的指导,使用JBossTool生成了自己的第一个例子,过程如下:
1、生成Sem web项目
2、输入项目的相关信息,如下图:
注意,如果是第一次使用Eclipse,需要配置Target Runtime和Target Server。
3、然后一路next,到最后一步时,如果是第一次使用,也要注意配置Seam Runtime和Connection Profile,如下图。最后点击finish按钮,即可创建Seam项目。
4、生成项目后,在Eclipse中共出现了四个项目,如下:
- seamfirst (web项目)
- seamfirst-ear (ear项目,集成web和ejb)
- seamfirst-jar (ejb项目)
- seamfirst-test (测试项目,进行单元测试)
此时运行JBossServer服务器,访问http://localhost:8080/seamfirst链接,出现如下图页面,此时Seam帮我们生成了一个框架,包含了基本的登录和退出功能,还有一个首页。
5、继续!使用Seam生成单表的CRUD操作。本步骤前提,有一个mysql数据库,数据库中有一个Customer表,该表有ID(int类型)、customername(varchar2类型)、customerdesc(varchar2类型)、createdate(date类型)、email(varchar2类型)五个字段。在seamfirst项目上点击右键,选择Seam Generate Entities菜单,弹出界面如下图:
单击finish按钮后,再运行JBoss Server服务器,访问http://localhost:8080/seamfirst,发觉菜单栏上多了一个Customer List菜单,单击此链接,即可进行Customer的添加、删除、修改、查询操作,虽然生成的界面不是很好看,也不是很符合我自己的操作习惯,但是功能倒是完备。
以后若是修改了Seam提供的代码自动生成的模板,然后再使用该功能,想必生成的页面就符合自己的项目要求了,记下一笔,先不管它。
生成的代码分析:
生成的代码主要有两部分,一部分为Java代码,一部分为页面代码。
Java代码包括如下三个类:
- Customer.java ---- 实体类,映射到数据库中的Customer表。
- CustomerHome.java ---- SessionBean,提供了Customer类的创建、更新、删除功能。继承了org.jboss.seam.framework.EntityHome类,EntityHome类中提供创建、更新、删除等基本功能。
- CustomerList.java ---- SessionBean,提供了Customer类的查询功能。继承了org.jboss.seam.framework.EntityQuery类,EntityQuery类中提供了查询功能。
CustomerHome和CustomerList类中都使用了@Name annotation,这样在页面中就可以直接访问Session Bean中的方法了,达到了Seam将表现层和业务层直接融合的目标。
页面代码包括如下文件:
- Customer.xhtml
- Customer.page.xml
- CustomerEdit.xhtml
- CustomerEdit.page.xml
- CustomerList.xhtml
- CustomerList.page.xml
刚开始看这段代码时,困惑我的有两个地方
- 一个是CustomerList.xhtml中rich:dataTable的value为"#{customerList.resultList}",customerList我明白指的是CustomerList SessionBean,但是我看遍了其代码,也没有发现有resultList属性,后来仔细一看,才发觉该属性在其父类EntityQuery中。
- 另一个是每一个xhtml文件都有一个对应的page.xml文件,想了半天也没整明白这是怎么回事,后来只好继续看Seam in Action的第三章,看着看着终于明白了,原来这是Seam对JSF的一个扩展,增强了JSF的功能,具体含义后面详细解释。
至此第一个使用JBossTools生成的Seam例子完成了,好像很简单 :-)
posted @
2008-12-09 22:40 The Matrix 阅读(2127) |
评论 (1) |
编辑 收藏
需求:Oracle的数据库文件都存放在C盘,由于数据文件越来越大,所以想把一些数据文件移至D盘
环境:Oracle9i
操作步骤:
- sqlplus /nolog
- connect / as sysdba;
- shutdown immediate;
- startup mount;
- alter database rename file 'c:\ora92\oradata\trans\trans.dbf' to 'd:\ora92\oradata\trans\trans.dbf';
- alter database open;
注意点:
附Oracle的几种启动方式
1、startup nomount
非安装启动,这种方式启动下可执行:重建控制文件、重建数据库。
读取init.ora文件,启动instance,即启动SGA和后台进程,这种启动只需要init.ora文件。
2、startup mount dbname
安装启动,这种方式启动下可执行:数据库日志归档、数据库介质恢复、使数据文件联机或脱机、重新定位数据文件、重做日志文件。
执行“nomount”,然后打开控制文件,确认数据文件和联机日志文件的位置,但此时不对数据文件和日志文件进行校验检查。
3、startup open dbname
先执行“nomount”,然后执行“mount”,再打开包括Redo log文件在内的所有数据库文件,这种方式下可访问数据库中的数据。
4、startup,等于以下三个命令
startup nomount
alter database mount
alter database open
posted @
2008-12-09 10:16 The Matrix 阅读(2751) |
评论 (1) |
编辑 收藏
用JBossTools生成项目,生成CRUD的代码,然后访问就报了如下异常:
Exception during request processing:
Caused by java.lang.IllegalStateException with message: "No phase id bound to current thread (make sure you do not have two SeamPhaseListener instances installed)"
org.jboss.seam.contexts.PageContext.getPhaseId(PageContext.java:163)
org.jboss.seam.contexts.PageContext.isBeforeInvokeApplicationPhase(PageContext.java:175)
org.jboss.seam.contexts.PageContext.getCurrentWritableMap(PageContext.java:91)
org.jboss.seam.contexts.PageContext.remove(PageContext.java:105)
org.jboss.seam.Component.newInstance(Component.java:2102)
org.jboss.seam.Component.getInstance(Component.java:1987)
org.jboss.seam.Component.getInstance(Component.java:1966)
org.jboss.seam.Component.getInstance(Component.java:1960)
org.jboss.seam.Component.getInstance(Component.java:1933)
org.jboss.seam.Component.getInstance(Component.java:1928)
org.jboss.seam.faces.FacesPage.instance(FacesPage.java:92)
org.jboss.seam.core.ConversationPropagation.restorePageContextConversationId(ConversationPropagation.java:84)
org.jboss.seam.core.ConversationPropagation.restoreConversationId(ConversationPropagation.java:57)
org.jboss.seam.jsf.SeamPhaseListener.afterRestoreView(SeamPhaseListener.java:389)
org.jboss.seam.jsf.SeamPhaseListener.afterServletPhase(SeamPhaseListener.java:228)
org.jboss.seam.jsf.SeamPhaseListener.afterPhase(SeamPhaseListener.java:194)
com.sun.faces.lifecycle.Phase.handleAfterPhase(Phase.java:175)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:114)
com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:104)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:38)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:177)
org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:267)
org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:380)
org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:507)
org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.debug.hot.HotDeployFilter.doFilter(HotDeployFilter.java:54)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:432)
org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
java.lang.Thread.run(Thread.java:619)
Google了一下,有人讲是JBoss4.2.3GA版本的BUG,赶紧下载了JBoss4.2.2GA,再测试一切正常!
不知还会不会有其它莫名的BUG了......
posted @
2008-12-07 22:03 The Matrix 阅读(1019) |
评论 (0) |
编辑 收藏
把环境配好之后,Seam的例子也运行起来了,看了seam_reference第一章中如下几个例子讲解:
- the registration example
- the messages example
- the todo list example
- the numberguess example
又在满江红的网站上找了seam_reference2.0的中文文档,主要看了《the contextual component model》一章,看完以后感觉Seam最核心的地方就是其contextual component model了,不过看完这一章以后只是对Seam有个大概的了解,对其具体的内容,细节还缺乏进一步的了解,对其优点、缺点也缺乏进一步的认识。
然后又找到了《Seam in Action》的电子书,看了一点之后还是觉得这本电子书写得好,内容组织的很好,不象seam_reference后面的章节仅仅是罗列seam的各项功能。
今天把Seam in Action的第一章草草看了一遍,将第一章讲述的内容总结如下:
1、什么是Seam
在Seam in Action中,没有将Seam称之为web framework,而是将其称为application stack。Seam将Java EE中的EJB3、JSF、JPA/Hibernate、JAAS等技术融合在一起,提供了更容易使用的方式,比如conversation、page flows、buisness precesses、rule-based security、JavaScript(Ajax) remoting、PDF rendering、email组合、charting、file uploads、Groovy integration等,用以简化web开发。
2、Seam的目标
简化web开发
3、Seam如何集成各类技术
Seam集成了JSF、JPA和POJO Component
在Seam中将EJB3.0中的Session Bean作为JSF的managed bean,直接将表现层和业务层衔接在一起,使得Session Bean可以直接访问web相关数据,比如request、session、application、JSF的FacesMessage、Component Tree等。而在不使用Seam时,一般都是使用JSF back bean来作为表现层和业务层之间的中介。
使用annotation中的@Name标注替代了JSF的faces-config.xml中关于managed bean的配置。
Seam不一定必须使用EJB和JPA,也可以使用POJO、Hibernate作为替代。如下图:
上下文相关的组件模型(Seam中的核心概念)
Seam提供了7种类型的上下文,其中属于Seam特有的两种上下文类型分别为:Conversation Context、Business process Context。
Seam提供了统一的组件注册、annotation、异常配置、方法拦截、统一的EL表达式等功能。其中Seam对其管理的组件拦截过程如下图:
4、Seam的核心竞争力
更好的JSF
增强的JSF
- Seam对JSF最被认可的改进就是消除了在配置文件中声明managed bean。
- Prerender page actions
- Managed request parameters (for a given page)
- Intelligent stateless and stateful navigation
- Transparent JSF data model and data model selection handling
- Fine-grained exception handling
- Page-level security (per view ID)
- 基于Annotation的表单验证
- Bookmarkable command links (solving the “everything is a POST” problem)
- Entity converter for pick lists
- Conversation controls
- Support for preventing lazy initialization exceptions and nontransactional data access in the view
消除了连接Bean(ELIMINATING CONNECTOR BEANS)
用一幅图可以很好的说明这句话的含义
引入了有状态的变量范围(INTRODUCING STATEFUL VARIABLE SCOPES)
扩展的Persistence Context
Spring中提供了The Session In View Filter,使得persistence manage可以在一个请求中存在,避免了常见的LazyInitializationException。在Seam中,扩展的Persistence Context可以跨越多个请求。其实扩展的Persistence Context是Conversation Context、Business Process Context的基础。
get rich quick
Seam提供了两种方式将Ajax集成到Seam应用中,一种是使用具有Ajax特性的JSF组件,如RichFaces和ICEFaces,另一种是可以在浏览器中使用JavaScript直接调用服务端的组件。
Seam还提供了另外一种意义上的Rich,即将PDF、mail等功能集成到Seam应用中。
提供了一个快速开发环境
代码自动生成
热部署
Seam调试页面
不部署即可以进行单元测试
从目前我个人的理解来看,Seam的作用与能力如下:
- Seam将EJB3与JSF整合在一起,消除了JSF与业务代码之间的间隙,直接将表现层与业务层衔接在一起
- Seam提出了Conversation Context的概念,将Stateful EJB引入到web开发中,直接与Conversation Context对应
- Seam提供了与Jbpm、itext、mail等一系列开源框架的整合,对于需要使用的相关功能的用户来说,提供了便利性
- 提供了开发工具的整合(Seam Gen与IDE),还可以自动生成部分代码
但由于Seam整合了如此多的框架,带来的一个最大的缺点:学习曲线陡峭,在SSH非常流行的今天,需要面对很多新技术(JSF、EJB3、JPA等),对于一个新手来说难度比较大,如果想使Seam被更多的开发人员使用,必须加强它的文档,目前的文档还是太少了。
posted @
2008-12-06 23:51 The Matrix 阅读(2274) |
评论 (0) |
编辑 收藏
今天早上在网上看到了kettle发布了最新的版本,忽然想起最近其实做了不少工作应该是ETL工具的拿手好戏,赶紧下载下来看看,看是否能够在实际的工作中应用起来。
顺便讲一下,为啥看到kettle会两眼发光。
最近写了好几个小程序,用于从一个ftp去获取数据,然后转发至另一个ftp去,或者是从一个数据库获取数据然后保存至本地的数据库中,使用的是jdk中的Timer实现的定时调度,本来也没什么问题,连续运行几个月都不会出错。
可是最近网络不是太好,周期性抽风,ping包时,每5分钟大概会丢7-8个包,从而导致程序也会假死,过一段时间后就不正常干活了,估计是因为用了数据库连接池的问题,要是每次发起数据库连接可能就不会有问题了,偷懒也不想改了,因为网络最终肯定是会修好的 :-) 但是想试试ETL工具,因为后面还有一些类似的东西要处理,不想写代码了,用别人的轮子感觉比较好,呵呵
首先下载了kettle的最新版,kettle3.1,解压后即可运行,一般的开发人员稍微摸索一下,看看例子简单的转换还是会做的,今天小试了一把,有几个注意点记下来。
- 使用资源库(repository)登录时,默认的用户名和密码是admin/admin
- 当job是存放在资源库(一般资源库都使用数据库)中时,使用Kitchen.bat执行job时,需使用如下的命令行:
Kitchen.bat /rep kettle /user admin /pass admin /job job名
- 当job没有存放在资源库而存放在文件系统时,使用Kitchen.bat执行job时,需使用如下的命令行:
Kitchen.bat /norep /file user-transfer-job.kjb
- 可以使用命令行执行job后,就可以使用windows或linux的任务调度来定时执行任务了
在一开始使用命令行方式执行job时,总是报如下的错误,琢磨了好长时间总算整明白正确的方式了。
Unexpected error during transformation metadata load
No repository defined!
下一步准备按照实际情况定制Job,做好了再写小结。
posted @
2008-12-04 22:48 The Matrix 阅读(10341) |
评论 (13) |
编辑 收藏
JBoss Envers目的是根据对实体的设置,提供记录执行数据变更历史的功能(数据变更版本)。Envers的配置非常简单,如果需要对某个实例进行历史数据版本记录,只需要在实例上配置@Versioned annotation即可。针对每个实体的版本的历史数据,Envers都会创建一个单独的数据表进行存储。
目前Envers支持Hibernate和Hibernate-entitymanager(JPA实现).
这个特点在需要对历史数据进行存档时很实用,而且目前Envers已经合并到Hibernate的新版本中去了,使用起来更方便,具体Hibernate哪个不太清楚。
留个印记..............
posted @
2008-12-04 09:04 The Matrix 阅读(284) |
评论 (0) |
编辑 收藏
准备深入学习JBossSeam,好好研究研究,具体学习路线基本遵循jboss-seam-2.1.1.CR1中的<<seam_reference.pdf>>。
学习JBossSeam之前最好对相关技术有一定的了解,比如:
然后下载相关的软件,如下:
- jboss-seam-2.1.1.CR1
- jboss-4.2.3.GA
- JBossTools-3.0.0.Beta1-R200810311334-ALL-win32(开发环境)
- eclipse-jee-ganymede-SR1-win32(开发环境)
- apache-ant-1.7.0
- jdk1.6.0_06
环境的配置都比较简单,基本都是解压即可,有如下注意事项:
- 在系统的环境变量中设置JAVA_HOME、ANT_HOME
- JBossTools解压后需拷贝至eclipse解压后的目录中。
- jboss-seam-2.1.1.CR1解压后,需设置其bulid目录下的default.build.properties文件中的jboss.home为JBOSS_HOME(假定为jboss-4.2.3GA的安装目录)。
上述配置好后,启动JBoss Server,然后至SEAM_HOME(假定为Seam的安装目录)/examples/registration目录下,运行ant explode命令,即可编译部署registration应用至JBoss Server中,最后访问:http://localhost:8080/seam-registration 即可体验Seam提供的第一个example程序 :-)
posted @
2008-12-03 23:03 The Matrix 阅读(926) |
评论 (0) |
编辑 收藏