zoukankan      html  css  js  c++  java
  • SSH框架

    1、使用hibernate进行更新操作时,首先调用了findById方法获取要修改的对象,此时session没有被关闭,接着重新创建一个对象,将要修改的属性值赋值给这个对象。调用修改方法抛出如下异常:

    org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session

    原因:在session缓存中已经存在一个与当前传递进来的修改对象具有相同标识符(主键)的对象。Hibernate的机制是只能存在一个具有唯一标示的对象,否则增删改就会出错。

    解决办法:

    :在使用过滤器/拦截器时,每次开启session,操作后就关闭session。

    session.evict(Object object),从缓存中清除指定的对象。

    ƒsession.clear(),是将session缓存中的对象全部清除,杀伤面太大了,不建议使用。

    2、HibernateSessionFactory类中有一个线程ThreadLocal类的对象,它用来分配session对象,经测试后发现,由它每回获取的session都不同,有时为空,有时可以得到之前存进去的session对象。

    3、如果使用struts+hibernate框架实现数据库的增删改,使用过滤器去开启和提交事务时,有时增删改会没有效果,因为action没有被过滤器过滤,这个使我困惑了很久,因为之前的项目都可以被过滤到,后面我想用拦截器拦截action,在拦截器中开启和提交事务,试验之后发现此法可行。

     

    4、使用hibernate+struts框架开发项目时,系统抛出如下异常:

    Exception

    java.lang.reflect.InvocationTargetException

    root Cause:

    java.lang.NoSuchMethodError: antlr. Collections.AST.getLine()I

     

    原因:由于我用的是MyEclipse自动生成的struts和hibernate类库,hibernate中有个antlr-2.7.7.jar,而struts中有个antlr-2.7.2.jar。异常的原因就是说没有找到antlr.Collections.AST类中的getLine()方法,高版本的jar中有getLine()方法,而低版本中没有getLine()方法,系统默认使用的是低版本的jar包。

    解决办法:去除struts类库中的antlr.jar包即可,还需要清理并构建这个项目,因为有的项目的配置信息一时更改不过来。

     

    5、Struts的类型转换器用于将String类型转化为指定的数据类型,还可以将指定的数据类型转化为String类型。开发项目时很方便。

    实现方法:

    :新建一个类继承StrutsTypeConverter类,实现其中的两个抽象方法,作为转换器类。

    ‚:新建局部属性文件或者全局属性文件

     

    局部属性文件:放置在相关action类同级目录下,文件名格式:action类名-conversion.properties

    里面存放键值对,如:hobbies=util.ListConverter

    hobbies就是要转化的属性名,util.ListConverter就是转换器类的完全限定名。

    全局属性文件:放置在src目录下,文件名格式:xwork-conversion.properties

    里面存放键值对,如:java.util.Date=util.DateConverter

    java.util.Date就是要转化的数据类型,util.DateConverter

    就是转换器类的完全限定名。

    注意:如果我们使用<s:property/>标签,那么它会调用转换其中的convertToString(),如果使用EL表达式,那么就不会调用该方法了。

     

    6、针对类型转换出错的处理--在页面上显示友好提示:

    类型转换出错时,要抛出一个运行时异常,程序会根据建立的属性文件,显示错误提示。

    实现方法:

    :新建局部属性文件或者全局属性文件

    局部属性文件:放置在相关action类同级目录下,文件名格式:action类名.properties

    里面存放键值对,如:invalid.fieldvalue.time=mistake

    invalid.fieldvalue.time就是出错的字段名,mistake是错误提示信息。

    全局属性文件:放置在src目录下,文件名格式:message.properties,属性文件的名称不作要求。

    还要在struts.xml中配置一个常量:

    <constant name="struts.custom.i18n.resources" value="message"/>

    属性文件中存放键值对,如:xwork.default.invalid.fieldvalue=fieldname is {0} is error

    这是固定的格式,{0}代表错误的字段名,系统会自动赋值。

    fieldname is {0} is error 便是提示信息。

     

    7、Struts框架有类似于html的标签,但是它有一定的格式,

    但是我们可以在struts.xml中配置一个常量,去掉它的格式。

         <constant name="struts.ui.theme" value="simple"/>

     

    8、当我们显示错误信息的时候,会发现错误信息会以列表的形式显示,这样就不美观了,达不到我们想要的标准。所以我们可以用另外的方式输出错误信息。

    例如我现在增加了两个错误信息:

    this.addFieldError("username","用户名太长!");

    this.addFieldError("username","2222!");

    那么我就可以使用以下四种方法输出错误信息:

        <s:property value="errors.username[0]"/>  

       ‚ <s:property value="fieldErrors.username[0]"/> 

       ƒ ${errors["username"][0] }

       4 ${fieldErrors["username"][0] }

    原理:在值栈中有fieldErrorserrors两个对象,这两个对象中存储着错误信息,利用<s:debug/>可以观察到,这两个对象其实就是map数据类型的。

    获取map数据的方法

     

     

    9、Struts上传文件

    jsp部分:

     

    struts.xml部分:

     

    action部分:

     

     

    注意:

    文件对象名就是表单文件控件的name

    文件类型的命名=文件对象名+FileContentType

    文件名称的命名=文件对象名+FileName

     

    10、struts下载文件

    jsp部分:

     

    struts.xml部分:

     

    action部分:

     

     

    11、两级联动

    演示:

     

     

     

    原理:

    将数据库中的数据封装成对象,然后将对象转化为json数据,在客户端用异步获取后台的json数据即可。

    客户端jsp页面:

     

     

     

     

    后台:

     

     

     

    注意:在js中如果某个元素还未被加载,那么只可以获得该元素的引用,不能对该元素进行绑定事件。

     

    13、struts框架中使用json

    客户端:

     

     

    Struts.xml:

     

    UserAction:

     

    注意struts类库里面没有提供ezmorph-1.0.6.jar文件,所以要手动添加。

     

    14、hibernate中的cascade属性

    Cascade属性是存在于set标签中,用来做级联删除和保存。

    它的值有以下几种:

    默认值是none,不做级联动作;

    save-update:级联保存

    delete:级联删除

    all:级联保存和删除

     

    注意:属性名称和属性值都严格需分大小写

     

    15、hibernate中的inverse属性

    修改街道对应的区道信息:

     

    修改后会发现程序执行了两次修改操作:

     

    原因:

    区道与街道是一对多的关系;

    由于Hibernate是双向维护外键,所以当修改区道中的街道时,会修改一次外键;在修改街道中的区道时,又会修改一次外键。

    这样就会产生效率慢的问题,因为如果执行两次修改,那么第二次是无用的操作。利用inverse属性可以解决这一问题。

    在区道表的映射文件里面的set标签中设置inverse属性为true;

    inverse的属性值如下:

    默认值为false,表示我方不放弃维护外键的权利

    true,表示我方放弃维护外键的权利

     

    一个国家有一个主席,国家有很多人,主席不可能认识国家的所有人,但是国家所有人可以认识主席。

     

    16、延迟加载

    延迟加载分为类级别延迟和关联级别延迟。

    类级别延迟:

    使用load(),例如:

     

    只有当使用这个对象时才会进行查询,如输出str和str.getName()时就会执行查询语句,但是str.getId()并不会进行查询。

    关联级别延迟:

    使用set标签中的lazy属性,lazy的属性值有true(默认值)、false、extra(极其懒惰,要什么才查什么);

    懒加载的意思就是当你使用到对象中的关联对象时,才执行查询操作。

    如当lazy=”true”时,当你使用set时才执行查询操作。

    如当lazy=”false”时,当你获取District对象时,同时会查出所有的Street。

    如当lazy=”extra”时,用什么查什么。

    如我要查询set.size(),系统会执行一下的查询语句:

     

    17、fetch属性

    fetch的属性值有select(默认值)、join、subselect

    fetch=”select”时,程序会先查询返回要查询的主体对象,然后根据lazy属性看是否懒加载。

    fetch=”join”时,程序会将主体对象和关联对象用一句连接查询的sql同时查询出来,这样以来,懒加载就无用武之地了。

    subselect和select一样,不会一开始就将关联对象查出来。

    subselect与select的区别:

     

    设置不执行懒加载;

    select是根据关联外键的id,每一个对象发一个select查询,获取关联的对象。

    执行的sql如下所示:

     

    subselect是发送两条sql语句,一条是查询主体对象,而另一条是抓取在前面查询到的所有实体对象的关联集合。

    执行的sql如下所示:

     

    18、批量抓取

    批量抓取的使用场景是查询出来一个集合,然后又查询每个集合对象中的集合。使用set标签中的batch-size属性实现。

    数据库中只有5个区道信息;

    设置batch-size=”5”,执行的查询语句如下:

     

     

    而设置batch-size=”7xxx”,执行的查询语句如下:

    由于发送sql数据的次数多少,所以batch-size的数值越大,效率就越高。

    batch-size为4时,首先会有4个?号,接着一个查询语句会有1个?号。

    19、QBC查询

    格式:

     

    qbc的统计查询得使用projection实现,有两种方式:

    (1)

     

    (2)

     

    查看文档发现ProjectionList和Projection的关系如下所示:

     

    可以使用groupProperty投影对结果集进行分组(使用SQL的GROUP BY子句),当你通过某个属性分组时,程序就会查询出该属性所对应的列名。

    可以使用Property.forName()来表示投影,就是查询指定的字段。

    创建别名有三种方式:

     

     

    20、离线查询:

     

    离线查询使用DetachedCriteria对象设置限制条件,然后再通过session获取Criteria对象。

    离线查询的使用场景:例如Biz类和Dao类,在Dao类中利用session操作CRUD,如果你想在Biz中设置限定条件,如果不使用离线查询,那么势必得获取Criteria对象,如此一来又得获取session,有点麻烦。

    但是使用离线查询的话,可以直接获取DetachedCriteria对象设置限定条件,然后再将这个对象传递到Dao中即可。

    概念:

    投影就是指部分字段,例如我只查询学生表中的姓名,这就叫投影。

    CRUD是指在做计算处理时的增加(Create)、读取查询(Retrieve)、更新(Update)和删除(Delete)几个单词的首字母简写。

  • 相关阅读:
    使用VS2012开发基于Office 2013的AddIn程序
    Silverlight Virtualization Overview
    解除.NET中虚拟路径的疑惑
    T4 Template Overview
    Silverlight ItemsControl详细解析+解惑
    C#多线程词频统计修改
    C#多线程词频统计
    通讯录从诺基亚手机同步至iphone
    验证邮箱合法性的一些测试样例
    九度1131:合唱队形
  • 原文地址:https://www.cnblogs.com/syjp/p/11082904.html
Copyright © 2011-2022 走看看