程序员便利贴
分类: Java | 评论

今天下班后,回家的路上,在思考网站的优化问题。 这个问题几年以来一直存在,但是都没找到解决方法,曾经也许找过,但是未果。 存在问题:首页、列表等页面,取出的list,存在大量的冗余数据。 我用代码举例说明一下,例如列表页取出某个产品的list,HQL代码如下: Java代码 1. String hql = “from Product p where p.valid=:valid order by…….”; 这段代码返回的list中,list的每一条,都会保存Product对象的所有的内容。 然而,列表页真正需要用到的,只有name(产品名称) publishTime(发布时间)……等等很少量的数据。像一些诸如产品规格、 的。 但是用不到,却取出来了,并且保存在返回的list里,于是就会增加不必要的内存开销,增加服务器的压力。 那么有什么办法能让list中的每一条数据,仅仅取出需要用到的呢?答案当然是有的,今天百度了一下, 找到如下的解决方案: 写道 SELECT new xxx.xxx.xxx.xx.User(t.id, t.username) FROM User t; 然后在User 使用查询列id,username做一个构造函数,不过仅限于hibernate3以上版本 举一反三,解决方案有了,呵呵。 Java代码 1. String hql = “select new Product(p.id, p.name, p.image) from Product p where p.valid=:v alid order by…….”; 这样查询出来的是Product对象,而不是Object[]对象,结果比较满意。

分类: Java | 评论

Struts跟Tomcat、Turbine等诸多Apache项目一样,是开源软件,这是它的一大优点。使开发者能更深入的 了解其内部实现机制。 Struts开放源码框架的创建是为了使开发者在构建基于Java Servlet和JavaServer Pages(JSP)技术的Web应用时更加容易。Struts框架为开放者提供了一 个统一的标准框架,通过使用Struts作为基础,开发者能够更专注于应用程序的商业逻辑。Struts框 架本身是使用Java Servlet和JavaServer Pages技术的一种Model-View-Controller(MVC)实现. 具体来讲,Struts的优点有: 1. 实现MVC模式,结构清晰,使开发者只关注业务逻辑的实现. 2. 有丰富的tag可以用 ,Struts的标记库(Taglib),如能灵活动用,则能大大提高开发效率。另外,就目前国 内的JSP开发者而言,除了使用JSP自带的常用标记外,很少开发自己的标记,或许Struts是一个很好的起点。 3. 页面导航.页面导航将是今后的一个发展方向,事实上,这样做,使系统的脉络更加清晰。通过一个配置文件,即可把握整个系统各部分之间的联系,这对于后期的 维护有着莫大的好处。尤其是当另一批开发者接手这个项目时,这种优势体现得更加明显。 4. 提供Exception处理机制 . 5. 数据库链接池管理 6. 支持I18N 缺点: 一、 转到展示层时,需要配置forward,每一次转到展示层,相信大多数都是直接转到jsp,而涉及到转向,需要配置forward,如果有十个展示层的 jsp,需要配置十次struts,而且还不包括有时候目录、文件变更,需要重新修改forward,注意,每次修改配置之 后,要求重新部署整个项目,而tomcate这样的服务器,还必须重新启动服务器,如果业务变更复杂频繁的系统,这样的操作简单不可想象。现在就是这样, 几十上百个人同时在线使用我们的系统,大家可以想象一下,我的烦恼有多大。 二、 Struts 的Action必需是thread-safe方式,它仅仅允许一个实例去处理所有的请求。所以action用到的所有的资源都必需统一同步,这个就引起了 线程安全的问题。 三、 测试不方便. Struts的每个Action都同Web层耦合在一起,这样它的测试依赖于Web容器,单元测试也很难 实现。不过有一个Junit的扩展工具Struts TestCase可以实现它的单元测试。 四、 类型的转换. Struts的FormBean把所有的数据都作为String类型,它可以使用工具Commons- Beanutils进行类型转化。但它的转化都是在Class级别,而且转化的类型是不可配置的。类型转化时的错误信息返回给用户也是非常困难的。 五、 对Servlet的依赖性过强. Struts处理Action时必需要依赖ServletRequest 和ServletResponse,所有它摆脱不了Servlet容器。 六、 前端表达式语言方面.Struts集成了JSTL,所以它主要使用JSTL的表达式语言来获取数据。可是JSTL的表达 式语言在Collection和索引属性方面处理显得很弱。 七、 对Action执行的控制困难. Struts创建一个Action,如果想控制它的执行顺序将会非常困难。甚至你要重 [...]

分类: Java | 评论

一 开发环境 Myelicpse8.5+Struts2.1+hibernate+MySql+Tomcat5.0.28 二 开发思路 既然讲的是Struts,那自然离不了MVC,分页显示也是如此。 写一个pagebean: import java.util.List; public class PageBean { private int firstRecord; //每页的第一条记录 private int currentPage; //当前页面 private static final int PAGESIZE = 16; //每页几条记录 private int totalCount; //总记录数 private boolean isFist; //是否是第一条记录 private boolean isLast; //是否是最后一条记录 private List results; //存储记录的结果集 private int totalPage; //总页数 public int getTotalPage() { return totalPage; [...]

分类: Java | 1 条评论
单独使用Compass需要的jar包

如果你的网站架构采用的是spring+hibernate。用现在比较流行的开源搜索引擎框架compass可以快速的给你的网站添加强大的搜索功能。从几十万条数据中,只需几毫秒的时间就可以搜索出你想要的数据。 Compass介绍 Compass是一个强大的,事务的,高性能的对象/搜索引擎映射(OSEM:object/search engine mapping)与一个Java持久层框架.Compass包括: * 搜索引擎抽象层(使用Lucene搜索引荐), * OSEM (Object/Search Engine Mapping) 支持, * 事务管理, * 类似于Google的简单关键字查询语言, * 可扩展与模块化的框架, * 简单的API. 官方网站:谷歌 1 序言 这些天一直在学点新的东西,想给毕业设计添加点含量,长时间的SSH项目也想尝试下新的东西和完善以前的技术,搜索毋容置疑是很重要的。作为javaer,作为apache的顶级开源项目lucene应该有所耳闻吧,刚学完lucene,知道了基本使用,学的程度应该到可以使用的地步,但不的不说lucene官方给的文档例子不是很给力的,还好互联网上资料比较丰富!在搜索lucene的过程中,知道了基于lucene的compass和lucene-nutch。lucene可以对给定内容加上索引搜索,但比如搜索本地数据库和web网页,你需要把数据给拿出来索引再搜索,所以你就想可不可以直接搜索数据库,以数据库内容作为索引,并且伴随着数据库的CRUD,索引也会更新,compass出现了,compass作为站内搜索那是相当的方便的,并且官方提供了spring和hibernate的支持,更是方便了。Lucene-nutch是基于lucene搜索web页面的,如果有必要我在分享下lucene、lecene-nutch的学习经验,快速入门,其他的可以交给文档和谷歌了。 不得不提下,compass09年貌似就不更新了,网上说只支持lucene3.0以下版本,蛮好的项目不知道为什么不更新了,试了下3.0以后的分词器是不能使用了,我中文使用JE-Analyzer.jar。我使用的环境: Spring3.1.0+Hibernate3.6.6+Compass2.2.0。 2 Compass介绍 Compass是一个强大的,事务的,高性能的对象/搜索引擎映射(OSEM:object/search engine mapping)与一个Java持久层框架.Compass包括: * 搜索引擎抽象层(使用Lucene搜索引荐), * OSEM (Object/Search Engine Mapping) 支持, * 事务管理, * 类似于Google的简单关键字查询语言, * 可扩展与模块化的框架, * 简单的API. 官方网站:谷歌 3 单独使用Compass Compass可以不继承到hibernate和spring中的,这个是从网上摘录的,直接上代码: @Searchable public class [...]

分类: 异常库 | 评论

明明很简单,一个hibernate的save而已。却出现了could not get next sequence value,导致插入不成功。后来经过分析。知道原来我把一个健设置为native ,在使用native的时候,hibernate默认会去找oracle中的hibernate_sequence序列。如果oracle中没有该序列,连oracle数据库会报错! 所以在数据库里面加了这个sequence就好了。加法如下: CREATE SEQUENCE hibernate_sequence INCREMENT BY 1 — 每次加几个 START WITH 1 — 从1开始计数 NOMAXVALUE — 不设置最大值 NOCYCLE — 一直累加,不循环 NOCACHE — 不建缓冲区 就可以了

分类: Java | 评论

在hibernate中有防注入的的方法这是为了避免在页面提交时给数据库带来不必要的麻烦 例如: String sql=“from table where name=‘”+name+“‘”; 那么用户输入:nan‘ and pass =’123 这样就会有安全漏洞,使程序报错。 Hibernate 中有一种简单的机制可以避免 永远也不要写这样的代码: String queryString = “from Item i where i.description like ‘” + searchString + “‘”; List result = session.createQuery(queryString).list(); 如果用户输入:foo’ and callSomeStoredProcedure() and ‘bar’ = ‘bar,则你的程序在执行一个简单查询后,还会调用某个存储过程, 这样你的程序就开了一个安全漏洞,如果用户偶尔输入了一个单引号,你的程序就可能报错(我的程序就这样呀!)。 永远也不要把未经检查的用户输入的值直接传给数据库! 幸运的时有一个简单的机制可以避免这种错误: JDBC在绑定参数时有一个安全机制,它可以准确的将那些需要转义的字符进行转义(escape), 如上面的searchString,它被escape,不再作为一个控制字符了,而是作为被查询的匹配的字符串的一部分。(这里指的是prepared statement,而是用普通的statment不行,我试过)。 另外,如果我们使用参数绑定,还可以提高数据库的执行效率,prepared statement语句被编译一次后,被放在cache中,就不再需要编译,可以提高效率。 参数绑定有2种办法:使用positional parameter或者named parameter。 Hibernate支持JDBC样式的positional parameter(查询字符串中使用?),它同使用named parameter的效果一样(查询字符串中使用:)。 使用named [...]

分类: Java | 评论

Hibernate缓存是一种提高系统性能的比较好的工具,如果使用合理,则能极大地提高系统性能,但如果使用不合理也会使系统性能下降。Hibernate缓存比较复杂,要想灵活使用hibernate缓存,必须深入研究Hibernate缓存原理。 Session缓存(一级缓存):当调用Session的保存、更新、查询操作时,在Session缓存中不存在相应对象,则把这些对象加入Session缓存。同一个Session操作,第一次通过ID调用load()或get()查询持久对象,先从Session缓存中查询,随即发送一条SQL语句生成一个持久对象并把该对象放入Session缓存。第二次再通过相同ID调用load()或get()查询时将直接从Session缓存将该对象返回,避免多余的数据库连接和查询的开销。 Session的load()和get()方法使用区别: 1、当数据库不存在对应ID数据时,调用load()方法将会抛出ObjectNotFoundException异常,get()方法将返回null. 2、当对象.hbm.xml配置文件元素的lazy属性设置为true时,调用load()方法时则返回持久对象的代理类实例此时的代理类实例是由运行时动态生成的类,该代理类实例包括原目标对象的所有属性和方法,该代理类实例的属性除了ID不为null外,所在属性为null值,查看日志并没有Hibernate SQL输出,说明没有执行查询操作,当代理类实例通过getXXX()方法获取属性值时,Hiberante才真正执行数据库查询操作。当对象.hbm.xml配置文件元素的lazy属性设置为false时,调用load()方法则是立即执行数据库并直接返回实体类,并不返回代理类。而调用get()方法时不管lazy为何值,都直接返回实体类。 3、load()和get()都会先从Session缓存中查找,如果没有找到对应的对象,则查询Hibernate二级缓存, 再找不到该对象,则发送一条SQL语句查询。

分类: Java | 评论

一个Student对应一个Classes,一个Classes包含多个Student; 元素的cascade属性表名操作是否从父对象级联到被关联的对象,它的取得可以是一下几种: none:在保存,删除或修改当前对象时,不对其附属对象(关联对象)进行级联操作,是默认值 save-update:在保存,更新当前对象时,级联保存,更新附属对象(临时对象,游离对象); delte:在删除当前对象时,级联删除附属对象。 all:所以情况下均进行级联操作,即包含save-update和delete操作 inverse属性默认是false的,就是说关系的两端都来维护关系。当在关系的一头,如Classes中的set中用了inverse=”true”时, 那就代表关系是由另一端维护的(Student) 就是说当插入Student时,不会操作Classes表,即使Student已经知道了关系。