SSH和Ajax的整合
一:准备工作
把Hibernate的jar包 ,spring的jar 包 ,Struts的jar包 ajax中的jar包比如dwr。
二:配置文件说明
Web.xml
<listener[U1] >
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/com/kettas/config/springBean.xml</param-value>
</context-param>
<servlet>
<servlet-name>action[U2] </servlet-name>
<servlet-class> org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>3</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>3</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>dwr[U3] </servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
struts-config.xml
<form-beans>
<form-bean name="dynaActionForm"
type="org.apache.struts.action.DynaActionForm">
<!-- admin formBean -->
<form-property name="loginName" type="java.lang.String" />
</form-bean>
</form-beans>
<global-exceptions />
<global-forwards />
<action-mappings>
<action path="/adminLogin" name="dynaActionForm" parameter="adminLogin"
type="org.springframework.web.struts.DelegatingActionProxy[U4] ">
<forward name="ok" path="/admin/admin.html" redirect="true" />
<forward name="error" path="/error.jsp" />
</action>
</action-mappings>
<!--message-resources
parameter="com.yourcompany.struts.ApplicationResources" /-->
<plug-in
className="org.springframework.web.struts.ContextLoaderPlugIn[U5] ">
<set-property property="contextConfigLocation"
value="/WEB-INF/classes/beans.xml" />
</plug-in>
Spring.xml
<bean id="sessionFactory"[U6] class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
</bean>
<bean id="template" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory"><ref local="sessionFactory" /></property>
</bean>
<!--Dao#####################################################################################-->
<bean id="daoSupport[U7] " class="com.kettas.upp02.dao.impl.DaoSupport">
<property name="sessionFactory"><ref bean="sessionFactory" /></property>
</bean>
<bean id="accountDao" class="com.kettas.upp02.dao.impl.AccountDaoImpl" parent="daoSupport">
</bean>
<!--Biz#####################################################################################-->
<bean id="accountBiz[U8] " class="com.kettas.upp02.biz.impl.AccountBizImpl">
<property name="accountDao"><ref bean="accountDao" /></property>
<property name="subAccountDao"> <ref bean="subAccountDao" /> </property>
</bean>
<!--BizProxy################################################################################-->
<!--
<bean id="accountBizProxy"[U9]
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="target" ref="accountBiz"></property>
<property name="transactionManager" ref="transactionManager"></property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
-->
<!-- ############################################################################ -->
<!-- transaction 切面注入事物-->
<bean id="transaction" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory"> <ref bean="sessionFactory" /></property>
</bean>
<!-- interceptor -->
<bean id="interceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager"><ref bean="transaction" /></property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<!-- BeanNameAutoProxyCreator -->[U10]
<bean id="auto" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list><value>*Biz</value></list>
</property>
<property name="interceptorNames">
<list><value>interceptor</value></list>
</property>
</bean>
<!-- AdminAction~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
<bean name="/adminLogin,/createAdmin[U11] ”
class="com.kettas.upp02.web.background.AdminAction">
<property name="adminBiz" ref="adminBiz" />
<property name="roleBiz" ref="roleBiz" />
<property name="powerBiz" ref="powerBiz" />
</bean>
dwr.xml的配置
<dwr>
<allow>
<create javascript="schoolBiz" creator="spring"[U12] scope="application">
<param name="beanName" value="schoolBiz"></param>
<!--<include method="getSchoolById" ></include>-->
</create>
</create>
<!-- 自己定义的实体 -->
<convert match="com.kettas.entity.School" converter="bean">
<!-- <param name="exclude" value="students"></param> 不会显示的属性,避免在加载时,类的关联属性无法加载 -->
</convert>
</allow>
</dwr>
总结
1,action中利用request.getParameter("*",x)可以获得jsp也没传过来的参数
2,jsp也没中加<%@taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>后
<bean:parameter id="cid" name="companyId" />获得参数,使用方法:${cid}
<bean:define id="c" name="company" ></bean:define>获得对象,使用同上
3,hibernate中:一对多关系中,hibernate默认是懒的初始化(lazy=true),这样当你查询一的一方时,它不会级联查询多的一方,这样单的一方就没办法使用保存在类中多的一方的属性
如果想使用就必须在多的一方中加上lazy=false,如:
<many-to-one name="company" column="company_id" lazy="false"></many-to-one>
当多的一方是通过外键指向单的一方主键时:默认的
4,jsp页面中实现国际化方法:
<%@taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
<html:messages id="error" name="errorMessages">
<font color="red">${error}</font>
</html:messages> 其中name为配置文件中写的
<%@taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<bean:message key="login.title"/> key中为配置文件写的
5,页面编码问题:
通常可以通过写过滤器来解决,但是写了过滤器之后,还可能出现页面乱码,url不支持中文传输,所有通常在传中文时最好用post方法(表单实现,get是用url实现),如果要用get也可以在tomcat中conf.server.xml文件中找到修改端口的地方加上URIEncoding="编码方式"即可。
6,级联删除:
如果想删除A表,但是B表的一个外键指向A表,关系维护在B表中,这时要向删除A表中的数据,首先要查出B表中指向A表的数据,然后把B表中的外键设为空,在删除A表中数据。
如果两个表都维护关系,写级联就OK
7,通过hibernate配置文件自动创建表:
(1)写好实体,和详细的xml影射文件
(2)在hibernate配置文件中添加
<!-- 此属性可以自动生成sql语句,自动创建表
<property name="hbm2ddl.auto">create</property>
-->
(3)然后在main方法中执行:ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
加载后即可生成sql语句。
8,利用PowerDesigner通过代码生成关系图:
file--->reverse engineer--->datebase--->弹出对话框
输入名字,选择数据库,单击确定
添加.sql文件后单击确定后可以生产图。
9,以下代码很有效:实现了分页查询所有对象的模板 // <T>定义泛型
public <T> List<T> selectAllObject(Class<T> clazz,Page page) {
String hql0 = "select count(*) from " + clazz.getSimpleName();
String hql = "from " + clazz.getSimpleName();
List<T> Objects = new ArrayList<T>();
// query()是分页实现方法
for(Object obj : this.query(hql0, null, hql, null, page)){
Objects.add((T) obj);
}
return Objects;
}
实现用对象或对象的属性实现分页查询:
/**实现HibernateCallback()方法所传的参数必须是final的,
*final T exampleEntity : 传过来的实体对象 final String propertyName :实体对象的属性名字
*final Object startData,final Object endData :通过时间查询时需要 final Page page :分页时需要
*/
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.Expression;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
protected <T> List<T> selectByExampleEntity(final T exampleEntity,final String propertyName,
final Object startData,final Object endData,final Page page) {
Object object = getHibernateTemplate().executeFind(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Example example = Example.create(exampleEntity); //通过实例创建Example
//通过session获得标准
Criteria criteria = session.createCriteria(exampleEntity.getClass());
//如果以下这3个参数都不为空的时候执行
//propertyName是两个时间对应的列的名字,两个时间是同一列的不同结果
if(propertyName != null && startDate != null && endDate != null){
Criterion c = Expression.between(propertyName, startDate, endDate);
criteria.add((Criterion) c);
}
criteria.add(example);
page.setOrderCount(new Long(criteria.list().size()));
criteria.setFirstResult((page.getPageNumber()-1)*page.getMax());
criteria.setMaxResults(page.getMax());
return criteria.list();
}
});
return (List<T>) object;
}
10, 在hibernate.hbm.xml文件配置中指定lazy="false"的话,固然可以在查询该对象的时候将其关系对象
一并查询出来,只是影响全局,或许我们只是想在某些情况下顺带查询关系对象,在不需要的时候则
浪费了查询时间以及内存空间。为了缩小影响范围,我们可以不指定lazy="false",只是在web.xml
文件中,配置一个spring提供的过滤器,如此便可在一次连接的范围内扩大事务,即使事务结束、Session
被关闭,再获取关系属性一样可行(school.getStudents() ... ),使用如下所示 :
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<!-- 对应spring.xml中的id -->
<param-value>sessionFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<!-- 指定要扩大事务的连接(一次请求) -->
<url-pattern>*.do</url-pattern>
</filter-mapping>
11,Oracle数据库:
当你修改了自己的计算机名称后,就会出现无法登陆Oracle主页等其它状况;
找到你数据库的安装目录:D:\..\oracle\product\10.2.0\server\NETWORK\ADMIN下边有两个文件
listener.ora和tnsnames.ora,打开它们并把其中的主机名(HOST)改为现在的主机名就OK
当两个表的列相同时(个数,名称,约束):
union连接两个select语句可以将两个表的数据加在一起(去掉重复),union all显示所有
eg: select id,name from student1 union (all) select id,name from student2 ;
12,日期和字符串之间相互转换:
Date d = new SimpleDateFormat("yyyy-mm-dd").parse("1234-25-30");
System.out.println(d);
String str = new SimpleDateFormat("yyyy-mm-dd").format(d);
System.out.print(str);
用监听器引入spring的配置文件,也可以在struts-config.xml中以<plug-in>方式注入
引入Struts的控制器,并且引入配置文件,并初始化属性
对dwr的映射
真正的实现类由Spring代理,故在spring.xml配置文件中有相关的注入,见下面的spring配置
注入spring的配置文件
外面的 hibernate.cfg.xml
定义一个dao父类,方便其他dao的继承
注入dao层的类
这种代理的方式注入事务很麻烦,下面有一种更简单的,自动注入方式
自动注入的方式,方便配置文件,有两个属性,beanNames和interceptorNames并且都可以注入多个类和切面
和struts的路径一样,下面的属性是biz层的注入。
表示是spring创建的。name="beanName"是固定的。schoolBiz就是spring注入的id值