SSH框架

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

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

缘由:在session缓存中已经存在一个与当前传递进来的修改对象具备相同标识符(主键)的对象。Hibernate的机制是只能存在一个具备惟一标示的对象,不然增删改就会出错。java

解决办法:sql

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

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

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

 

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

 

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

 

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

Exceptionjsp

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包便可,还须要清理并构建这个项目,由于有的项目的配置信息一时更改不过来。

 

五、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表达式,那么就不会调用该方法了。

 

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

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

实现方法:

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

局部属性文件:放置在相关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 即是提示信息。

 

七、Struts框架有相似于html的标签,可是它有必定的格式,

可是咱们能够在struts.xml中配置一个常量,去掉它的格式。

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

 

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

例如我如今增长了两个错误信息:

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数据的方法

 

 

 

九、Struts上传文件

jsp部分:

 

 

struts.xml部分:

 

 

action部分:

 

 

 

注意:

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

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

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

 

十、struts下载文件

jsp部分:

 

 

struts.xml部分:

 

 

action部分:

 

 

 

十一、两级联动

演示:

 

 

 

 

 

 

 

原理:

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

客户端jsp页面:

 

 

 

 

 

 

 

后台:

 

 

 

 

注意:在js中若是某个元素还未被加载,那么只能够得到该元素的引用,不能对该元素进行绑定事件。

 

1三、struts框架中使用json

客户端:

 

 

 

Struts.xml:

 

 

UserAction:

 

 

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

 

1四、hibernate中的cascade属性

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

它的值有如下几种:

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

save-update:级联保存

delete:级联删除

all:级联保存和删除

 

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

 

1五、hibernate中的inverse属性

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

 

 

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

 

 

缘由:

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

因为Hibernate是双向维护外键,因此当修改区道中的街道时,会修改一次外键;在修改街道中的区道时,又会修改一次外键。

这样就会产生效率慢的问题,由于若是执行两次修改,那么第二次是无用的操做。利用inverse属性能够解决这一问题。

 

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

inverse的属性值以下:

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

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

 

 

 

一个国家有一个主席,国家有不少人,主席不可能认识国家的全部人,可是国家全部人能够认识主席。

 

1六、延迟加载

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

类级别延迟:

使用load(),例如:

 

 

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

关联级别延迟:

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

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

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

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

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

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

 

 

 

1七、fetch属性

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

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

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

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

subselect与select的区别:

 

 

设置不执行懒加载;

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

执行的sql以下所示:

 

 

 

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

执行的sql以下所示:

 

 

 

1八、批量抓取

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

 

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

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

 

 

 

 

 

 

 

 

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

 

 

因为发送sql数据的次数多少,因此batch-size的数值越大,效率就越高。

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

 

1九、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)几个单词的首字母简写。

相关文章
相关标签/搜索