posts - 495,  comments - 11,  trackbacks - 0
 

在*.hbm.xml必须声明的< generator>子元素是一个Java类的名字,用来为该持久化类的实例生成唯一的标识。

< generator class="sequence"/>

这是一个非常简单的接口;某些应用程序可以选择提供他们自己特定的实现。当然,Hibernate提供了很多内置的实现。下面是Generator子元素的一些内置生成器的快捷名字:

increment(递增)

用于为long, short或者int类型生成唯一标识。只有在没有其他进程往同一张表中插入数据时才能使用。 在集群下不要使用。

identity

对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。返回的标识符是long, short 或者int类型的。

sequence (序列)

在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence),而在Interbase中使用生成器(generator)。返回的标识符是long, short或者 int类型的。

hilo (高低位)

使用一个高/低位算法来高效的生成long, short或者 int类型的标识符。给定一个表和字段(默认分别是是hibernate_unique_key 和next_hi)作为高位值得来源。高/低位算法生成的标识符只在一个特定的数据库中是唯一的。在使用JTA获得的连接或者用户自行提供的连接中,不要使用这种生成器。

seqhilo(使用序列的高低位)

使用一个高/低位算法来高效的生成long, short或者 int类型的标识符,给定一个数据库序列(sequence)的名字。

uuid.hex

用一个128-bit的UUID算法生成字符串类型的标识符。在一个网络中唯一(使用了IP地址)。UUID被编码为一个32位16进制数字的字符串。

uuid.string

使用同样的UUID算法。UUID被编码为一个16个字符长的任意ASCII字符组成的字符串。不能使用在PostgreSQL数据库中

native(本地)

根据底层数据库的能力选择identity, sequence 或者hilo中的一个。

assigned(程序设置)

让应用程序在save()之前为对象分配一个标示符。

foreign(外部引用)

使用另外一个相关联的对象的标识符。和< one-to-one>联合一起使用。

Generator子元素的用法:

  1. <  class name="onlyfun.caterpillar.User" table="USER">
  2.            <  id name="id" type="string" unsaved-value="null">
  3.                <  column name="USER_ID"/>
  4.                <  generator class="uuid.hex"/>
  5.            <   /id>
posted @ 2009-07-03 14:04 jadmin 阅读(53) | 评论 (0)编辑 收藏

在Hibernate中有三种状态,对它的深入理解,才能更好的理解hibernate的运行机理,刚开始不太注意这些概念,后来发现它是重要的。对于理解hibernate,JVM和sql的关系有更好的理解。对于需要持久化的JAVA对象,在它的生命周期中有三种状态,而且互相转化。

Hibernate三种状态之一:临时状态(Transient):用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫临时对象;

Hibernate三种状态之二:持久化状态(Persistent):已经持久化,加入到了Session缓存中。如通过hibernate语句保存的对象。处于此状态的对象叫持久对象;

Hibernate三种状态之三:游离状态(Detached):持久化对象脱离了Session的对象。如Session缓存被清空的对象。特点:已经持久化,但不在Session缓存中。处于此状态的对象叫游离对象;

Hibernate三种状态中游离对象和临时对象异同:

两者都不会被Session关联,对象属性和数据库可能不一致;

游离对象由持久化对象关闭Session而转化而来,在内存中还有对象所以此时就变成游离状态了;

Hibernate和SQL的关系:

在操作了hibernate的方法如save()等后,并没有直接生成sql语句,去操作数据库,而是把这些更新存入Session中,只有Session缓存要被更新时,底层的sql语句才能执行,数据存入数据库;

下面举例说明:

一,Session.save(user)运行机理。
1,把User对象加入缓存中,使它变成持久化对象;
2,选用映射文件指定的标识生成ID;
3,在Session清理缓存时候执行:在底层生成一个insert sql语句,把对象存入数据库;

注意:在你执行Session.save(user)后,在Session清理缓存前,如果你修改user对象属性值,那么最终存入数据库的值将是最后修改的值;此过程中ID不能被修改;

二,Session.delete(user)运行过程。
如果user是持久化对象,则执行删除操作,同样底层数据库的执行条件是:在Session清理缓存时候;
如果user是游离对象:
1,将user对象和Session关联,使之成为持久化对象;
2,然后按照user 是持久化对象的过程执行;

posted @ 2009-07-03 14:00 jadmin 阅读(50) | 评论 (0)编辑 收藏

Hibernate访问多个数据库的设计思路:利用 Hibernate中config = new Configuration().configure(configFile);可以加载不同数据库配置信息的原理,编写一个数据库操作类,再编写一个数据库管理程序[map],将加载的数据库连接实例put早数据库管理程序中,具体实现见下面:

Hibernate访问多个数据库步骤一:hibernate配置文件

localhost.cfg.xml

  1. < ?xml version="1.0" encoding="utf-8"?>
  2. < !DOCTYPE hibernate-configuration
  3.      PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
  4.      "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
  5. < hibernate-configuration>
  6.     < session-factory >
  7.   < !-- local connection properties -->
  8.   < property name="hibernate.connection.url">jdbc:mysql://localhost:3306/bookshop?zeroDateTimeBehavior=convertToNull< /property>
  9.   < property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver< /property>
  10.   < property name="hibernate.connection.username">root< /property>
  11.   < property name="hibernate.connection.password">12345678< /property>
  12.   < !-- property name="hibernate.connection.pool_size">< /property -->
  13.   < !-- dialect for MySQL -->
  14.         < property name="dialect">org.hibernate.dialect.MySQLDialect< /property>
  15.         < property name="hibernate.show_sql">true< /property>
  16.         < property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory< /property>        
  17.         < property name="hbm2ddl.auto">update< /property>
  18.      < mapping resource="org/jskyme/data/local/po/Shop.hbm.xml"/>
  19.     < /session-factory>
  20. < /hibernate-configuration>

data_server.cfg.xml

  1. < ?xml version="1.0" encoding="utf-8"?>
  2. < !DOCTYPE hibernate-configuration
  3.      PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
  4.      "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
  5. < hibernate-configuration>
  6.     < session-factory >
  7.   < !-- local connection properties -->
  8.   < property name="hibernate.connection.url">jdbc:mysql://192.168.0.10:3306/bookshop?zeroDateTimeBehavior=convertToNull< /property>
  9.   < property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver< /property>
  10.   < property name="hibernate.connection.username">root< /property>
  11.   < property name="hibernate.connection.password">12345678< /property>
  12.   < !-- property name="hibernate.connection.pool_size">< /property -->
  13.   < !-- dialect for MySQL -->
  14.         < property name="dialect">org.hibernate.dialect.MySQLDialect< /property>
  15.         < property name="hibernate.show_sql">true< /property>
  16.         < property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory< /property>        
  17.         < property name="hbm2ddl.auto">update< /property>
  18.      < mapping resource="org/jskyme/data/local/po/Shop.hbm.xml"/>
  19.     < /session-factory>
  20. < /hibernate-configuration>

Hibernate访问多个数据库步骤二:数据库访问类:

数据库管理类:DataBaseManager

  1. package org.jskyme.hibernate.util;
  2. import java.util.HashMap;
  3. public class DataBaseManager extends HashMap {
  4. private static final long serialVersionUID = 6491666983237498097L;
  5. private static DataBaseManager inst = new DataBaseManager();
  6. public static DataBaseManager getInst() {
  7.   return inst;
  8. }
  9. public SessionManager get(Object key) {
  10.   return (SessionManager) super.get(key);
  11. }
  12. @Override
  13. public Object put(Object key, Object value) {
  14.   return super.put(key, value);
  15. }
  16. public static void setInst(DataBaseManager inst) {
  17.    DataBaseManager.inst = inst;
  18. }
  19. }

Hibernate连接数据库操作类:

  1. package org.jskyme.hibernate.util;
  2. import java.util.List;
  3. import org.hibernate.Criteria;
  4. import org.hibernate.Query;
  5. import org.hibernate.SQLQuery;
  6. import org.hibernate.Session;
  7. import org.hibernate.SessionFactory;
  8. import org.hibernate.Transaction;
  9. import org.hibernate.cfg.Configuration;
  10. public final class SessionManager {
  11. private Configuration config;
  12. private SessionFactory sessionFactory;
  13. private Session session;
  14. public Criteria createCriteria(Class persistentClass) {
  15.   return session.createCriteria(persistentClass);
  16. }
  17. private void buildSession() {
  18.    sessionFactory = config.buildSessionFactory();
  19.    session = sessionFactory.openSession();
  20. }
  21. public SessionManager(String configFile) {
  22.    config = new Configuration().configure(configFile);
  23.    buildSession();
  24. }
  25. public Session getSession() {
  26.   return session;
  27. }
  28. public void save(Object obj) {
  29.    Transaction tx = session.beginTransaction();
  30.    session.save(obj);
  31.    tx.commit();
  32. }
  33. public Object load(Class clas, Integer priId) {
  34.   return session.get(clas, priId);
  35. }
  36. public Query findbyhql(String hql) {
  37.   return session.createQuery(hql);
  38. }
  39. public List pageSizeByhql(String hql) {
  40.   return findbyhql(hql).list();
  41. }
  42. public SQLQuery findbysql(String sql) {
  43.   return session.createSQLQuery(sql);
  44. }
  45. public void update(Object obj) {
  46.    Transaction tx = session.beginTransaction();
  47.    session.saveOrUpdate(obj);
  48.    tx.commit();
  49. }
  50. public void delete(Class clas, Integer inte) {
  51.    session.delete(load(clas, inte));
  52. }
  53. public void delete(Object obj) {
  54.    session.delete(obj);
  55. }
  56. public void deletebyhql(String hql) {
  57.    Query query = session.createQuery(hql);
  58.    query.executeUpdate();
  59. }
  60. public Query createQuery(String hql) {
  61.   return session.createQuery(hql);
  62. }
  63. }

Hibernate访问多个数据库步骤三:测试类

  1. package org.jskyme.data.test;
  2. import junit.framework.TestCase;
  3. import org.hibernate.Query;
  4. import org.jskyme.hibernate.util.DataBaseManager;
  5. import org.jskyme.hibernate.util.SessionManager;
  6. public class DataBaseManagerTest extends TestCase {
  7. DataBaseManager dbm = DataBaseManager.getInst();
  8. public void testDatabase() {
  9.    setDatabase();
  10.    SessionManager tempSess = dbm.get("dataLocal");
  11.    Query query = tempSess.createQuery("from   Shop");
  12.    query.list();
  13.   
  14.    SessionManager tempSess27 = dbm.get("dateManage");
  15.    Query query27 = tempSess27.createQuery("from Shop");
  16.    query27.list();
  17. }
  18. private void setDatabase() {
  19.    SessionManager dateManageLocal = new SessionManager("localhost.cfg.xml");
  20.    SessionManager dateManage27 = new SessionManager("data_server.cfg.xml");
  21.    dbm.put("dateManage", dateManage27);
  22.    dbm.put("dataLocal", dateManageLocal);
  23. }
  24. }
posted @ 2009-07-03 13:51 jadmin 阅读(70) | 评论 (0)编辑 收藏

Hibernate延时加载,其实这个异常写的非常之清楚,就是会话关闭,无法对Hibernate实体进行操作。造成这样的情况有很多,什么书写错误啊,逻辑错误啊。

但就此说一下关于lazy机制:

Hibernate延时加载包括延迟初始化错误,这是运用Hibernate开发项目时最常见的错误。如果对一个类或者集合配置了延迟检索策略,那么必须当代理类实例或代理集合处于持久化状态(即处于Session范围内)时,才能初始化它。如果在游离状态时才初始化它,就会产生延迟初始化错误。

下面把Customer.hbm.xml文件的< class>元素的lazy属性设为true,表示使用延迟检索策略:

  1. < class name="mypack.Customer" table="CUSTOMERS" lazy="true">  

当执行Session的load()方法时,Hibernate不会立即执行查询CUSTOMERS表的select语句,仅仅返回Customer类的代理类的实例,这个代理类具由以下特征:

(1) 由Hibernate在运行时动态生成,它扩展了Customer类,因此它继承了Customer类的所有属性和方法,但它的实现对于应用程序是透明的。

(2) 当Hibernate创建Customer代理类实例时,仅仅初始化了它的OID属性,其他属性都为null,因此这个代理类实例占用的内存很少。

(3)当应用程序第一次访问Customer代理类实例时(例如调用customer.getXXX()或customer.setXXX ()方法), Hibernate会初始化代理类实例,在初始化过程中执行select语句,真正从数据库中加载Customer对象的所有数据。但有个例外,那就是当 应用程序访问Customer代理类实例的getId()方法时,Hibernate不会初始化代理类实例,因为在创建代理类实例时OID就存在了,不必 到数据库中去查询。

提示:Hibernate采用CGLIB工具来生成持久化类的代理类。CGLIB是一个功能强大的Java字节码生成工具,它能够在程序运行时动态生成扩 展 Java类或者实现Java接口的代理类。

以下代码先通过Session的load()方法加载Customer对象,然后访问它的name属性:

  1. tx = session.beginTransaction();
  2. Customer customer=(Customer)session.load(Customer.class,new Long(1));
  3. customer.getName();
  4. tx.commit();  

在运行session.load ()方 法时Hibernate不执行任何select语句,仅仅返回Customer类的代理类的实例,它的OID为1,这是由load()方法的第二个 参数指定的。当应用程序调用customer.getName()方法时,Hibernate会初始化Customer代理类实例,从数据库中加载 Customer对象的数据,执行以下select语句:

  1. select * from CUSTOMERS where ID=1;
  2. select * from ORDERS where CUSTOMER_ID=1;  

当< class>元素的lazy属性为true,会影响Session的load()方法的各种运行时行为,下面举例说明。

1.如果加载的Customer对象在数据库中不存在,Session的load()方法不会抛出异常,只有当运行customer.getName()方法时才会抛出以下异常:

  1. ERROR LazyInitializer:63 - Exception initializing proxy
  2. net.sf.hibernate.ObjectNotFoundException: No row with the given identifier exists: 1, of class:
  3. mypack.Customer  

2.如果在整个Session范围内,应用程序没有访问过Customer对象,那么Customer代理类的实例一直不会被初始化,Hibernate不会执行任何select语句。以下代码试图在关闭Session后访问Customer游离对象:

  1. tx = session.beginTransaction();
  2. Customer customer=(Customer)session.load(Customer.class,new Long(1));
  3. tx.commit();
  4. session.close();
  5. customer.getName();  

由于引用变量customer引用的Customer代理类的实例在Session范围内始终没有被初始化,因此在执行customer.getName()方法时,Hibernate会抛出以下异常(Hibernate延时加载的问题之一):

  1. ERROR LazyInitializer:63 - Exception initializing proxy
  2. net.sf.hibernate.HibernateException: Couldnotinitializeproxy-theowningSessionwasclosed  

由此可见,Customer代理类的实例只有在当前Session范围内才能被初始化。

3.net.sf.hibernate.Hibernate类的initialize()静态方法用于在Session范围内显式初始化代理类实例,isInitialized()方法用于判断代理类实例是否已经被初始化。例如:

  1. tx = session.beginTransaction();
  2. Customer customer=(Customer)session.load(Customer.class,new Long(1));
  3. if(!Hibernate.isInitialized(customer))
  4. Hibernate.initialize(customer);
  5. tx.commit();
  6. session.close();
  7. customer.getName();  

以上代码在Session范围内通过Hibernate类的initialize()方法显式初始化了Customer代理类实例,因此当Session关闭后,可以正常访问Customer游离对象。

4.当应用程序访问代理类实例的getId()方法时,不会触发Hibernate初始化代理类实例的行为,例如:

  1. tx = session.beginTransaction();
  2. Customer customer=(Customer)session.load(Customer.class,new Long(1));
  3. customer.getId();
  4. tx.commit();
  5. session.close();
  6. customer.getName();  

当应用程序访问customer.getId()方法时,该方法直接返回Customer代理类实例的OID值,无需查询数据库。由于引用变量 customer始终引用的是没有被初始化的Customer代理类实例,因此当Session关闭后再执行customer.getName()方法, Hibernate会抛出以下异常(Hibernate延时加载的问题之一):

  1. ERROR LazyInitializer:63 - Exception initializing proxy
  2. net.sf.hibernate.HibernateException: Couldnotinitializeproxy-theowningSessionwasclosed  

解决方法:

由于hibernate采用了lazy=true,这样当你用hibernate查询时,返回实际为利用cglib增强的代理类,但其并没有实际填 充;当你在前端,利用它来取值(getXXX)时,这时Hibernate才会到数据库执行查询,并填充对象,但此时如果和这个代理类相关的session已关闭掉,就会产生种错误.

在做一对多时,有时会出现"could not initialize proxy - clothe owning Session was sed,这个好像是hibernate的缓存问题.问题解决:需要在< many-to-one>里设置lazy="false". 但有可能会引发另一个异常叫

  1. failed to lazily initialize a collection of role: XXXXXXXX, no session or session was closed  

解决方法:在web.xml中加入

  1. < filter>
  2.     < filter-name>hibernateFilter< /filter-name>
  3.     < filter-class>
  4.       org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
  5.     < /filter-class>
  6. < /filter>
  7. < filter-mapping>
  8.     < filter-name>hibernateFilter< /filter-name>
  9.     < url-pattern>*.do< /url-pattern>
  10. < /filter-mapping>

就可以了。

以上文章转自:http://developer.51cto.com/art/200907/133249.htm

关键字:Hibernate,延时加载,lazy

posted @ 2009-07-03 13:39 jadmin 阅读(77) | 评论 (0)编辑 收藏
众所周知,设计模式描述的就是针对软件设计中的常见问题做出的可重复使用的解决方案。而了解及使用这些模式则是SOA取得成功的根本。
企业软件热点文章
Windows 7与Vista价格对比 微软大幅延长Windows 7 降级XP期限
Windows 7完整公开发售路线图 微软推Windows 7选择升级计划 VAIO率先响应
微软称Windows 7限期打折 预定只须50美元 Windows 7免费升级计划截至2010年1月31日
欧洲用户不能升级Windows 7 只能全新安装 消息称Windows 7中国零售价最低399元起

众所周知,设计模式描述的就是针对软件设计中的常见问题做出的可重复使用的解决方案。而了解及使用这些模式则是SOA取得成功的根本。下面是Gartner公司的分析师们通过分析得出的五种新兴SOA设计模式:

1. 多通道应用

2. 复合应用

3. 业务流程编排

4. 面向服务的企业

5. 联邦SOA

多通道应用

用SOA实现多通道应用真是再合适不过。这种模式能将后端业务逻辑与前端逻辑分离,通过各个通道在最短的时间内将全部的应用功能提交到最大数量的用户手上,并能重复使用同一服务。

战略远景:2008年,将有超过66%的新开发的中到大型交互式应用软件是支持多通道访问的,而2007年这一数据尚不及33%。

复合应用

在复合应用中使用的服务可能是新部署的服务、经过调整和封装的旧应用组件、或者是以上两者的组合。在组合SOA环境中,有两种集成技术是使系统有效运行的关键:1)帮助用户封装并接受各种初始SOA应用的服务接口底层的集成技术;和2)帮助用户组装并监控服务操作的集成技术。

战略远景:到2012年,大部分SOA应用软件将是交互式的复合应用。

业务流程编排

业务流程管理(BPM)软件包是用来实现基于SOA的多步处理过程的工具。BPEL标准经常被用来描述所设计的元数据流模型。元数据库(meta-database)是用来在运行时管理这些业务过程模型的行为的。这些过程中的部分步骤是通过调用SOA服务实现的。其它的步骤则需要人为的干预。

战略远景:到2009年,有超过75%的SOA应用将通过外部BPM技术实现一部分与服务部署无关的顺序控制。

面向服务的企业

基于SOA的企业模型离复合应用只有一步之遥。在这里,所有的应用程序都被看作是整体的一个组成部分。没有任何新应用程序是独立创建的。所有的应用程序都是以可重用的组件为基础构建的,它们不但可以实现预期的功能,也可以在其它环境下被不同的客户端使用。从本质上说,综合式的复合企业所拥有的已不是应用程序,而是业务组件——每一个组件都是企业的资产。

战略远景:到2010年,超过85%的企业会把应用集成视为与SOA管理工具和组织同样的企业组件。

联邦SOA

联邦SOA的基本概念就是采用合理的程序将企业分解为半独立的SOA领域(比如,以子公司、业务单元或部门来表示企业组织),每个领域都有其独自特有的SOA基础设施、治理过程和SOA卓越中心。然后各领域通过合适的互用性基础设施、治理过程和组织方式形成联邦(即以联合的方式实现领域内的服务共享,这是通常的方式,但不是必须的方式)。“SOA联邦”即是通过适当的技术、治理和组织方式形成联邦式SOA的过程。

战略远景:很少有大型组织有能力独自做出整个IT的宏伟蓝图。最好的实践还是支持领域的独立性并允许使用不同的技术与架构以换取互操作性协议与传输的同步。合并与收购很显然就是联邦SOA的一种方式。

posted @ 2009-06-28 13:25 jadmin 阅读(64) | 评论 (0)编辑 收藏
  许多种类的错误将触发异常,这些问题从像硬盘(crash)坠毁这样的严重硬件错误,到尝试访问越界数组元素这样的简单程序错误,像这样的错误如果在java函数中发生,函数将创建一个异常对象并把他抛出到运行时系统(runtimesystem)。

  许多种类的错误将触发异常,这些问题从像硬盘(crash)坠毁这样的严重硬件错误,到尝试访问越界数组元素这样的简单程序错误,像这样的错误如果在java函数中发生,函数将创建一个异常对象并把他抛出到运行时系统(runtimesystem)。异常对象包含异常的信息,包括异常的类型,异常发生时程序的状态。运行时系统则有责任找到一些代码处理这个错误。在java技术词典中,创建一个异常对象并把它抛给运行时系统叫做:抛出异常(throwinganexception)。

  当某个函数抛出一个异常后,运行时系统跳入了这样一个动作,就是找到一些人(译者注:其实是代码)来处理这个异常。要找的处理异常的可能的人(代码)的集合(set)是:在发生异常的方法的调用堆栈(callstack)中的方法的集合(set)。运行时系统向后搜寻调用堆栈,从错误发生的函数,一直到找到一个包括合适的异常处理器(exceptionhandler)的函数。一个异常处理器是否合适取决于抛出的异常是否和异常处理器处理的异常是同一种类型。因而异常向后寻找整个调用堆栈,直到一个合格的异常处理器被找到,调用函数处理这个异常。异常处理器的选择被叫做:捕获异常(catchtheexception)。

  如果运行时系统搜寻整个调用堆栈都没有找到合适的异常处理器,运行时系统将结束,随之java程序也将结束。

  使用异常来管理错误,比传统的错误管理技术有如下优势:

  1. 将错误处理代码于正常的代码分开。

  2. 沿着调用堆栈向上传递错误。

  3. 将错误分作,并区分错误类型。

  1. 将错误处理代码于正常的代码分开。

  在传统的程序种,错误侦测,报告,和处理,经常导致令人迷惑的意大利面条式(spaghetti)的代码。例如,假设你要写一个将这个文件读到内存种的函数,用伪代码描述,你的函数应该是这个样子的:

  readFile

  open the file; //打开文件

  determine its size; //取得文件的大小

  allocate that much memory; //分配内存

  read the file into memory; //读文件内容到内存中

  close the file; //关闭文件

  匆匆一看,这个版本是足够的简单,但是它忽略了所有潜在的问题:

  n 文件不能打开将发生什么?

  n 文件大小不能取得将发生什么?

  n 没有足够的内存分配将发生什么?

  n 读取失败将发生什么?

  n 文件不能关闭将发生什么?

  为了在read_file函数中回答这些错误,你不得不加大量的代码进行错误侦测,报告和处理,你的函数最后将看起来像这个样子:

  errorCodeType readFile

  initialize errorCode = 0;

  open the file;

  if (theFileIsOpen)

  determine the length of the file;

  if (gotTheFileLength)

  allocate that much memory;

  if (gotEnoughMemory)

  read the file into memory;

  if (readFailed)

  errorCode = -1;

  else

  errorCode = -2;

  else

  errorCode = -3;

  close the file;

  if (theFileDidntClose && errorCode 0)

  errorCode = -4;

  else

  errorCode = errorCode and -4;

  else

  errorCode = -5;

  return errorCode;

  随着错误侦测的建立,你的最初的7行代码(粗体)已经迅速的膨胀到了29行-几乎400%的膨胀率。更糟糕的是有这样的错误侦测,报告和错误返回值,使得最初有意义的7行代码淹没在混乱之中,代码的逻辑流程也被淹没。很难回答代码是否做的正确的事情:如果函数分配内容失败,文件真的将被关闭吗?更难确定当你在三个月后再次修改代码,它是否还能够正确的执行。许多程序员“解决”这个问题的方法是简单的忽略它,那样错误将以死机来报告自己。

  对于错误管理,Java提供一种优雅的解决方案:异常。异常可以使你代码中的主流程和处理异常情况的代码分开。如果你用异常代替传统的错误管理技术,readFile函数将像这个样子:

  readFile

  try

  open the file;

  determine its size;

  allocate that much memory;

  read the file into memory;

  close the file;

  catch (fileOpenFailed)

  doSomething;

  catch (sizeDeterminationFailed)

  doSomething;

  catch (memoryAllocationFailed)

  doSomething;

  catch (readFailed)

  doSomething;

  catch (fileCloseFailed)

  doSomething;

  注意:异常并不能节省你侦测,报告和处理错误的努力。异常提供给你的是:当一些不正常的事情发生时,将所有蹩脚(grungy)的细节,从你的程序主逻辑流程中分开。

  另外,异常错误管理的膨胀系数大概是250%,比传统的错误处理技术的400%少的多。

tags:异常

posted @ 2009-06-25 23:45 jadmin 阅读(76) | 评论 (0)编辑 收藏

       MD5的全称是Message-Digest Algorithm 5,在90年代初由MIT的计算机科学实验室和RSA Data Security Inc发明,经MD2、MD3和MD4发展而来。

       Message-Digest泛指字节串(Message)的Hash变换,就是把一个任意长度的字节串变换成一定长的大整数。请注意我使用了“字节串”而不是“字符串”这个词,是因为这种变换只与字节的值有关,与字符集或编码方式无关。

       MD5将任意长度的“字节串”变换成一个128bit的大整数,并且它是一个不可逆的字符串变换算法,换句话说就是,即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有无穷多个,这有点象不存在反函数的数学函数。

       MD5的典型应用是对一段Message(字节串)产生fingerprint(指纹),以防止被“篡改”。举个例子,你将一段话写在一个叫 readme.txt文件中,并对这个readme.txt产生一个MD5的值并记录在案,然后你可以传播这个文件给别人,别人如果修改了文件中的任何内容,你对这个文件重新计算MD5时就会发现(两个MD5值不相同)。如果再有一个第三方的认证机构,用MD5还可以防止文件作者的“抵赖”,这就是所谓的数字签名应用。

       MD5还广泛用于加密和解密技术上,在很多操作系统中,用户的密码是以MD5值(或类似的其它算法)的方式保存的, 用户Login的时候,系统是把用户输入的密码计算成MD5值,然后再去和系统中保存的MD5值进行比较,而系统并不“知道”用户的密码是什么。

       关键词:MD5,MD5算法,文件的MD5值,文件 | 曦勤,[风故故,也依依], 博客,百度,IT

posted @ 2009-05-28 19:45 jadmin 阅读(108) | 评论 (0)编辑 收藏

代码如下:

/*
* @(#)DatabaseBackup.java Apr 23, 2009
*
* Copyright (c) 2009 by jadmin. All Rights Reserved.
*/

package util.dbak;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

/**
* MySQL数据库的备份与恢复
* 缺陷:可能会被杀毒软件拦截
*
* @author <a href="mailto:jadmin@163.com">jadmin</a>
* @version $Revision: 1.0 Apr 23, 2009 11:44:00 PM $
*/
public class DatabaseBackup {

/** MySQL安装目录的Bin目录的绝对路径 */
private String mysqlBinPath;

/** 访问MySQL数据库的用户名 */
private String username;

/** 访问MySQL数据库的密码 */
private String password;

public String getMysqlBinPath() {
   return mysqlBinPath;
}

public void setMysqlBinPath(String mysqlBinPath) {
   this.mysqlBinPath = mysqlBinPath;
}

public String getUsername() {
   return username;
}

public void setUsername(String username) {
   this.username = username;
}

public String getPassword() {
   return password;
}

public void setPassword(String password) {
   this.password = password;
}

public DatabaseBackup() {
   super();
}

public DatabaseBackup(String mysqlBinPath, String username, String password) {
   super();
   if (!mysqlBinPath.endsWith(File.separator)) {
    mysqlBinPath = mysqlBinPath + File.separator;
   }
   this.mysqlBinPath = mysqlBinPath;
   this.username = username;
   this.password = password;
}

/**
* 备份数据库
*
* @param output 输出流
* @param dbname 要备份的数据库名
*/
public void backup(OutputStream output, String dbname) {
   String command = "cmd /c " + mysqlBinPath + "mysqldump -u" + username + " -p" + password + " --set-charset=utf8 "
     + dbname;
   System.out.println(command);
   PrintWriter p = null;
   BufferedReader reader = null;
   try {
    p = new PrintWriter(new OutputStreamWriter(output, "utf8"));
    Process process = Runtime.getRuntime().exec(command);
    InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream(), "utf8");
    reader = new BufferedReader(inputStreamReader);
    String line = null;
    while ((line = reader.readLine()) != null) {
     p.println(line);
    }
    p.flush();
   } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
   } catch (IOException e) {
    e.printStackTrace();
   } finally {
    try {
     if (reader != null) {
      reader.close();
     }
     if (p != null) {
      p.close();
     }
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
}

/**
* 备份数据库,如果指定路径的文件不存在会自动生成
*
* @param dest 备份文件的路径
* @param dbname 要备份的数据库
*/
public void backup(String dest, String dbname) {
   try {
    OutputStream out = new FileOutputStream(dest);
    backup(out, dbname);
   } catch (FileNotFoundException e) {
    e.printStackTrace();
   }
}

/**
* 恢复数据库
*
* @param input 输入流
* @param dbname 数据库名
*/
public void restore(InputStream input, String dbname) {
   String command = "cmd /c " + mysqlBinPath + "mysql -u" + username + " -p" + password + " " + dbname;
   try {
    Process process = Runtime.getRuntime().exec(command);
    OutputStream out = process.getOutputStream();
    String line = null;
    String outStr = null;
    StringBuffer sb = new StringBuffer("");
    BufferedReader br = new BufferedReader(new InputStreamReader(input, "utf8"));
    while ((line = br.readLine()) != null) {
     sb.append(line + "\r\n");
    }
    outStr = sb.toString();

    OutputStreamWriter writer = new OutputStreamWriter(out, "utf8");
    writer.write(outStr);
    writer.flush();
    out.close();
    br.close();
    writer.close();
   } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
   } catch (IOException e) {
    e.printStackTrace();
   }

}

/**
* 恢复数据库
*
* @param dest 备份文件的路径
* @param dbname 数据库名
*/
public void restore(String dest, String dbname) {
   try {
    InputStream input = new FileInputStream(dest);
    restore(input, dbname);
   } catch (FileNotFoundException e) {
    e.printStackTrace();
   }
}

public static void main(String[] args) {
   DatabaseBackup bak = new DatabaseBackup("C:/MySQL/UTF8/bin", "root", "root");
   bak.restore("c:/t.sql", "ttk");
}
}

tags:java,mysql,database,数据库,备份,恢复,mysql命令

posted @ 2009-04-24 22:55 jadmin 阅读(83) | 评论 (0)编辑 收藏

在实际项目中,经常会遇到这样的问题:想得到某个目录下的所有具有特定扩展名文件的文件名集合

解决方法:

1.定义自己的文件名过滤器类,这个类必须实现java.io.FilenameFilter接口

2.调用


下面是我的一个例子,目标:得到目录Constans.SCRIPT_DIR下所有扩展名为".sql"的文件的文件名集合

1.实现自己的文件名过滤类

/**
* 脚本文件过滤器
*
* @author <a href="mailto:jadmin@126.com">jadmin</a>
*/
public class ScriptFilenameFilter implements FilenameFilter {

private String suffix;

public ScriptFilenameFilter(String suffix) {
   this.suffix = suffix;
}

public boolean accept(File dir, String name) {
   if(name.endsWith(suffix)) {
    return true;
   }
   return false;
}

}


2.调用

String[] names = new java.io.File(Constans.SCRIPT_DIR).list(new ScriptFilenameFilter(".sql"));

这样就得到了一个文件名数组,注:Constans.SCRIPT_DIR是【目录】常量串

posted @ 2009-01-16 21:56 jadmin 阅读(91) | 评论 (0)编辑 收藏

使用笔记本,避免不了经常变换IP,如果是手动去每次都设置,太烦人了,下面推荐一款实用的绿色IP切换工具IPWhiz,使用起来非常方便,下面是截图:

PS:之前一直使用的是ASUS的公用程序Net4Switch,其实这一款也是很好用的IP切换工具,只不过我的瑞星更新到2009版后Net4Switch就出问题了,可能是软件之间冲突了吧...

posted @ 2008-12-30 20:38 jadmin 阅读(60) | 评论 (0)编辑 收藏
仅列出标题
共50页: First 上一页 14 15 16 17 18 19 20 21 22 下一页 Last