您的位置:首页 > 其它

ssh项目开发总结

2018-03-08 21:20 295 查看
一:Hibernate、HibernateTemplate
1、        Hibernate 的 save返回值 类型为 Serializable接口,该结果的值就是你插入到数据库后新记录的主键值。如果你的主键是数值,可以按如下方法:
Serializable result =this.getSession().save(t);
Integer integer = (Integer)result;  返回值大于0表示操作成功
2、    HibernateDaoSupport 中注入 sessionFactory:  
@Repository
public class TestDaoImpl extends HibernateDaoSupport implements TestDao{
报错:'sessionFactory' or 'hibernateTemplate' is required 。说明继承HibernateDaoSupport对象后并没有并没有自动注入sessionFactory。
   
两种解决方式:
***在spring的配置文件的头部,写上:default-autowire="byName">或者byType  如果是byName,SessionFactory的bean名字必须是sessionFactory.
***在Dao层上加入:

    /** 由于在HibernateDaoSupport中的setSessionFacroty类型为final,故需要改变方法名 */
    @Autowired
    publicvoid setSessionFactoryOverride(SessionFactory sessionFactory)
    {
        super.setSessionFactory(sessionFactory);
    }  
 
3、     Hibernate中使用annotation注解实体类@Entity报一下错误:  
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Admin is not mapped [from Admin as a where a.loginName='zhangsan' and a.loginPwd='zhangsan']
 
   
错误原因:@Entity(name="t_admin"),实体类与数据库表对应关系映射错误,用@Entity注解要用默认表格式(即类名对应数据库表名,字段名对应属性名,不能自定义),若要自定义要用@Table ,即@Entity @Table(name="t_admin")
 
4、cascade级联属性:cascade属性的可能值有
    all:所有情况下均进行关联操作,即save-update和delete
    none:所有情况下均不进行关联操作。这是默认值。
    save-update: 在执行save/update/saveOrUpdate时进行关联操作。
    delete:在执行delete 时进行关联操作。CascadeType.PERSIST:级联新增(又称级联保存):对order对象保存时也对items里的对象也会保存。对应EntityManager的presist方法。CascadeType.MERGE:级联合并(级联更新):若items属性修改了那么order对象保存时同时修改items里的对象。对应EntityManager的merge方法。CascadeType.REMOVE:级联删除:对order对象删除也对items里的对象也会删除。对应EntityManager的remove方法。CascadeType.REFRESH:级联刷新:获取order对象里也同时也重新获取最新的items时的对象。对应EntityManager的refresh(object)方法有效。即会重新查询数据库里的最新数据。CascadeType.ALL:以上四种都是。
 
一般情况:
@ManyToOne( cascade = {CascadeType.PERSIST,CascadeType.MERGE} )
@ManyToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE},
fetch=FetchType.LAZY)
@OneToMany(cascade= {CascadeType.ALL},fetch=FetchType.LAZY)
5、Fetch属性:
FetchType.LAZY:延迟加载 ,关联表需要用时才加载
FetchType.EAGER:急加载 ,发出SQL语句,立即加载关联表
6、懒加载问题:
方法一:设置属性fetch为eager。
方法二:在web.xml中配置: 要加在struts2核心转发器之前

    <filter> 
        <filter-name>OpenSessionInViewFilter</filter-name> 
        <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class> 
    </filter> 
    <filter-mapping> 
        <filter-name>OpenSessionInViewFilter</filter-name> 
        <url-pattern>/*</url-pattern> 
    </filter-mapping> 
 
 
二:Struts2
1、       通配符问题:
在使用通配符的时候可能遇到这样的问题:

Struts has detected an unhandled exception:
Message:There is no Action mapped for namespace [/] and action name [user_login] associated with context path [/shop].
 
   
***在struts2.3之前的版本修改:在struts2的核心jar包 struts-core中的default.properties中(路径:/org/apache/struts2/default.properties)

struts.enable.DynamicMethodInvocation = true
 
 
如果是方法动态方法调用的话(action名+ ! +Method名) 的值要改为true。
使用通配符则改为false 。
***在struts2.5版本之后要加:

     <action name="*Admin" class="com.dw.action.AdminAction" method="{1}Admin">
      <resultname="addSuccess">/{1}Success.jsp</result>
       <result name="addFail">/{1}Fail.jsp</result>
       <allowed-methods>addAdmin,deleteAdmin</allowed-methods>
     </action>
   
加入:<allowed-methods>addAdmin,deleteAdmin</allowed-methods>
其中addAdmin为Action中的方法名,多个方法之间用‘,’隔开。
2、       修改struts2请求中的默认后缀  .action 为 .do:
如果想在web.xml中修改后缀为.do的形式是不可行的,因为该形式表示以.do为后缀的url会被struts2框架捕获

  <filter-mapping>
   <filter-name>struts2</filter-name>
   <url-pattern>*.do</url-pattern>
  </filter-mapping>
   
***解决方法之一是:在struts.xml文件添加:

<constant name="struts.action.extension" value="do"/>
 
3、struts2集成struts-menu:
(1)由于struts2没有struts-config.xml配置文件,所以需要在web.xml中添加监听器:

    <listener> 
        <listener-class>net.sf.navigator.menu.MenuContextListener</listener-class> 
    </listener> 
 
      (2)在lib文件夹下添加jar包struts-menu-2-4-3.jar
(3)在WEB-INF文件夹下添加menu-config.xml配置文件,内容如:

<?xml version="1.0" encoding="UTF-8"?>
<MenuConfig>
      <Displayers>
        <Displayer name="DropDown"
                   type="net.sf.navigator.displayer.DropDownMenuDisplayer"/>                                 
      </Displayers>
      <Menus>
          <Menu name="AdminMenu" title=" 后台管理" description="后台管理" width="80">
             <Item name="menu1" title=" 商品分类管理" image="images/icon1.gif" location="Admin/adminCate.do?method=browseCate"/>
             <Item name="menu2" title=" 商品管理" image="images/icon2.gif" location="Admin/adminMer.do?method=browseMer"/>
             <Item name="menu3" title=" 特价商品管理" image="images/icon2.gif" location="Admin/adminMer.do?method=browseSMer"/>
             <Item name="menu4" title=" 订单管理" image="images/icon11.gif" location="Admin/adminOrder.do?method=browseOrder"/>
             <Item name="menu5" title=" 会员管理" image="images/icon6.gif" location="Admin/adminMember.do?method=browseMember"/>                                             
             <Item name="menu6" title=" 系统用户管理" image="images/icon10.gif" location="Admin/admin.do?method=browseAdmin"/>
             <Item name="menu7" title=" 安全退出" image="images/icon12.gif" location="Admin/login.do?method=logout"/>            
          </Menu>  
      </Menus>
</MenuConfig>
 
     4、web.xml中的加载顺序问题:
     Content-param -> listener -> filter-> servlet
 
5、从jsp页面到action出现中文乱码:
     ***情况一:在pageEncoding = utf-8的情况下,form表单请求方式改为post
6、从jsp页面到action获得日期格式为:Thu Mar 0700:00:00 CST 2019是java.util.Date类型,先将它转换为yyyy-MM-dd HH:mm:ss格式存入数据库:

Date date = new Date();
SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
String s1 = sdf.format(date);  //将Thu Mar 07 00:00:00 CST 2019转换为yyyy-MM-dd格式
Date t1 = null;
t1 = sdf.parse(s1);//将yyyy-MM-dd格式转换为Thu Mar 07 00:00:00 CST 2019格式
 
 
 7、防止页面刷新表单数据重复提交:通过sturts2提供的token令牌机制。
1)在struts.xml中配置基于action的拦截器:
       <!--添加token拦截器,防止页面刷新表单重复提交--> 
        <interceptor-refname="token">
          <param name="includeMethods">addWordMember</param>  <!-- 指定需要拦截的方法 -->
        </interceptor-ref> 
          <!--默认拦截器必须添加--> 
        <interceptor-refname="defaultStack"/>
        <result name="invalid.token" type="redirectAction">browseWordMember.do</result> 
2)在jsp页面的表单域内添加<s:token>即可

三:Spring
1、       Spring框架 做带回滚操作的Juit单元测试:多数情况下我们希望用Junit做单元测试不破坏数据库现场,就需要用到  回滚操作
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations= {"classpath:beans.xml"})
@TestExecutionListeners(listeners= {
       DependencyInjectionTestExecutionListener.class
})
@TransactionConfiguration(transactionManager="txManager",defaultRollback=true)
publicclass AdminDaoTest extends AbstractTransactionalJUnit4SpringContextTests {
    @Autowired
    private AdminDao adminDao;
    @Test
    publicvoid addAdmin() {
       Admin admin = new Admin();
       admin.setAdminName("zhangsan");
        admin.setLoginPwd("123456");
       adminDao.addAdmin(admin);
    }
   
第一步:首先导入Juit测试的相关jar包,另外导入Spring包下的spring-text.jar包
第二步:创建一个测试类,此类继承AbstractTransactionalJUnit4SpringTestContextTests(类名相当长) 
          第三步:在类上注解@RunWith(SpringJUnit4ClassRunner.class),该注解的参数类是spring-test中的类,表示用spring主导,用以驱动此次测试
          第四步:第二个注解@ContextConfiguration(locations={"classpath:beans.xml"}),用以定位bean的资源文件,也就是减少getBean的操作。其中locations加了s表示为数组类型,因此{}不可省;如果不加s当然不用写。
         第五步:第三个注解@TestExecutionListeners(listeners={
DependencyInjectionTestExecutionListener.class,
})  ,测试执行监听器,配置一系列的监听。
         第六步:@TransactionConfiguration(transactionManager="txManager",defaultRollback=true)  ,事物配置,其中txManage为beans.xml中的事物bean的id,默认defaultRollback为true表示执行回滚操作。  至此配置完成
2、使用Spring事物管理可能出现  出现只读而不能写异常,如: 

org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
   
错误原因可能有多种:
原因一:Spring 和 Hibernate整合的时候用到了HibernateTemplate,该类中封装了sessionFactory,其中的session是通过getCurrentSession()来获取的,使用此方法需要和事物相关联,故在beans.xml中添加:

   <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
      <property name="sessionFactory" ref="sessionFactory"/>
   </bean>
   <tx:annotation-driven transaction-manager="txManager"/>
 
 四:SSH项目的基础总结:
1、       pageContext.request.contextPath  :
2、Integer.intValue():将Integer类型转换为int类型的值。 3、JS中使用虚拟表单的形式提交POST请求:

      var url = "browseMer.do";
      var key = document.all.qKey.value;
 
      var temp = document.createElement("form");
      temp.action = url;
      temp.method = "post";
     
      var element1=document.createElement("input");
      element1.name='cateId';
      element1.value=document.all.category.value;
      temp.appendChild(element1);
           document.body.appendChild(temp);
      temp.submit();
   
4、  jsp中的<%= %>
举例如下:
<% String username="abc";%>
下面两句代码是一样的效果,
<% %> 标识里面的是jsp代码.
<%=变量 %> 是 <% out.println(变量) %> 的简写方式
用户:<%=username%>
用户:<%out.println(username) %>
 5、动态构造下拉列表:

   for (var i=0;i<result.length;i++){
      option =document.createElement("OPTION");
      option.value = result[i][0];
      option.text = result[i][1];
      document.all.category.options.add(option);
   }
选定值:
for(varj=0;j<document.all.memberlevel.options.length;j++){
    if(document.all.memberlevel.options[j].value=='${member.memberLevel.id}')
      document.all.memberlevel.options[j].selected = true;
  }
 
 
   
6、jsp页面设日期输出格式

<fmt:formatDate value="${order.orderDate}" var="orderDateTime" type="both" pattern="yyyy年MM月dd日 hh:mm:ss"/>         
<td height="26"> 下单日期:${orderDateTime}</td>
 
 
五:
1、       Struts开发与jsp+servlet开发的差异:
***代码的规范性:struts基于MVC开发模式,结构清晰、层次分明,而jsp+servlet由于开发的任意性导致代码的规范性差;
***开发时间:struts稍微逊色,其前期需要编写一些配置文件
***后期维护:struts远胜于servlet,struts 开发结构清晰,数据层、业务逻辑层、控制层层次分明,符合java的模块化编程,易于维护;而servlet的开发中,其逻辑代码存在于jsp页面、servlet中,导致逻辑混乱,维护困难,后期维护容易引入新的bug。
 
2、Jquery-validate.js表单验证;
  1)通过name:
     $('#form1').validate({
        rules:{
          bookName : "required"
         },
         messages:{
            bookName : "商品不能为空"
         }
     });
2)通过id:
   $('#form1').validate();
   $('#user1').rules('add',{required:true,messages:{required:'请输入您的名字'}});
 
    //删除规则
   $('#user1').rules('remove');
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: