Archive for the "Java 世界" Category

Java 面试:冒泡排序

面试无数,逢试必备——冒泡排序

public class TestBubbleUp { /* 冒泡排序算法 */
	public static int[] sort(int[] m) {
		int theLenth = m.length; /* 执行theLenth次 */
		for (int i = 0; i < theLenth; i++) { /* 每执行一次,将最小的数排在后面 */
			for (int j = 0; j < theLenth - i - 1; j++) {
				int a = m[j];
				int b = m[j + 1];
				if (a < b) {
					m[j] = b;
					m[j + 1] = a;
				}
			}
		}
		return m;
	}

	public static void main(String args[]) {
		int[] m = { 9, 1, 0, 13, 100, 39, 88, 32 };
		int[] n = sort(m);
		for (int i = 0; i < m.length; i++) {
			System.out.println(n[i]);
		}
	}
}
 

Hibernate Error:org.hibernate.AssertionFailure

最近频繁遇到Hibernate Error:org.hibernate.AssertionFailure: null id in cn.allobject.db.AReview entry (don’t flush the Session after an exception occurs)

错误原因:相信很多在看到这个错误的时候都会搜索出很多结果,大致有几个原因:
1、配置错误,实体配置注释错误,如没有配置逐渐生成方式;
2、不可为null的字段提供了null值,这也是搜索结果中提供的最多的一种原因;
3、是因为字段长度不够导致的

 

Hibernate MySql 连接池隔天断开解决方法

最近独自写了个小项目,测试的时候都OK,放到服务器後发现隔天便会出现Error:org.hibernate.exception.JDBCConnectionException: could not execute query,几经观察,确认是数据库连接池出了问题,查了些资料,找到了解决方法:

MySQL对所有连接的有效时间默认为28800秒,正好8小时,也就是说,如果一个连接8小时没有请求和操作,就会自动断开;但是对于Hibernate来说,它的连接池并不知道它所管理的连接中是否有被MySQL断开的。如果一个程序要使用数据库连接,而Hibernte的连接池分配一个已经被MySQL断开了的给程序使用,那么便会出现错误。

  为了证实确实是这个错误,我在本机上做了如下测试:首先启动Tomcat,网站能够正常打开;然后修改系统时间,往后调1天;然后再打开网站,同样的问题果然出现!MySQL + Hibernate架构相当普遍,所以这个问题也相当普遍,若读者也有这样的项目,建议做一下同样的测试,看看是否存在此问题!

问题找到了,怎么解决呢?
  思路1:增大MySQL的连接有效时间;
  思路2:从程序自身出发,修改连接池的相关参数。
  显然,思路1是不可行的,一方面这个思路不可能保证这个问题绝对的解决,如果无访问时间够长,还是大于MySQL的连接有效时间,问题同样会发生;另一方面,一般情况下,我们都是将程序部署在别人服务器上,我们不可能去修改MySQL配置。那么只能从思路2入手了。
  经查资料发现,Hibernate支持如下的连接池:
   DriverManagerConnectionProvider:代表由Hibernate提供的默认的数据库连接池
   C3P0ConnectionProvider:代表C3P0连接池
   ProxoolConnectionProvider:代表Proxool连接池
   DBCPConnectionProvider:代表DBCP连接池
   DatasourceConnectionProvider:代表在受管理环境中由容器提供的数据源
  其中,默认连接池并不支持在分配一个连接时,测试其有效与否的功能,而C3P0、Proxool、DBCP都提供了这样的功能,正好可以解决上述问题。综合考虑各个连接池的效率、稳定性、易用性,决定换用Proxool,它确实在各方面表现优良,方便配置。
  下面就看看如何配置Proxool:
  1、Hibernate配置文件:

<session-factory>
<property name=”hibernate.connection.provider_class”>org.hibernate.connection.ProxoolConnectionProvider</property>
<property name=”hibernate.proxool.xml”>proxool.xml</property>
<property name=”hibernate.proxool.pool_alias”>mysql</property>

<property name=”show_sql”>false</property>
<property name=”dialect”>org.hibernate.dialect.MySQLDialect</property>

<mapping resource=”com/lab1000/jcom/pojo/Admin.hbm.xml” />

</session-factory>

  其中各属性含义如下:
hibernate.connection.provider_class:指明使用Proxool连接池
hibernate.proxool.xml:指明Proxool配置文件所在位置,这里与Hibernate的配置文件在同一目录下
hibernate.proxool.pool_alias:指明要使用的proxool.xml中定义的proxool别名。

  2、Proxool配置文件(proxool.xml):

<?xml version=”1.0″ encoding=”UTF-8″?>
<!– the proxool configuration can be embedded within your own application’s.
Anything outside the “proxool” tag is ignored. –>
<something-else-entirely>
<proxool>

<!– proxool别名 –>
<alias>mysql</alias>

<!– 数据库连接Url –>
<driver-url>
jdbc:mysql://localhost/yourDatebase?useUnicode=true&characterEncoding=UTF-8
</driver-url>

<!– JDBC驱动名称 –>
<driver-class>com.mysql.jdbc.Driver</driver-class>

<!– 数据库连接帐号 –>
<driver-properties>
<property name=”user” value=”root” />
<property name=”password” value=”password” />
</driver-properties>

<!– proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁 –>
<house-keeping-sleep-time>90000</house-keeping-sleep-time>

<!– 指因未有空闲连接可以分配而在队列中等候的最大请求数,超过这个请求数的用户连接就不会被接受 –>
<maximum-new-connections>20</maximum-new-connections>

<!– 最少保持的空闲连接数 –>
<prototype-count>3</prototype-count>

<!– 允许最大连接数,超过了这个连接,再有请求时,就排在队列中等候,最大的等待请求数由maximum-new-connections决定 –>
<maximum-connection-count>20</maximum-connection-count>

<!– 最小连接数 –>
<minimum-connection-count>3</minimum-connection-count>

<!– 在分配连接前后是否进行有效性测试,这个是解决本问题的关键 –>
<test-before-use>true</test-before-use>
<test-after-use>true</test-after-use>

<!– 用于测试的SQL语句 一定要写(不知道问什么)–>
<house-keeping-test-sql>SELECT CURRENT_USER</house-keeping-test-sql>

</proxool>
</something-else-entirely>

  3、下载和安装Proxool的包文件
  下载地址:http://proxool.sourceforge.net/download.html
  下载后并解压后,将其中lib文件夹下的jar文件拷贝到你站点的WEB-INF/lib下

  自此,Proxool配置成功。重新启动Tomcat,再次做上述测试,问题解决。
  此外,如果要使用C3P0或DHCP,可以参考以下资料:
  http://blog.csdn.net/lip8654/archive/2008/02/26/2121387.aspx
  http://azi.javaeye.com/blog/182146
  http://fishyych.javaeye.com/blog/90793

PS:解决方案参考网络资源(忘了是在哪里看到的了:))

 

以后就用Resin了~

Tomcat用了好久,Weblogic要盗版或掏钱……,终于腻烦了,尝试用Resin,感觉不错,性能也很好。纪录两点使用上的心得:
一、配置文件:\conf\resin.conf,默认端口号为8080,在这里面可以修改端口号
二、安装的时候注意不要安装在Programm files下面(原因暂时是我在使用的时候发现读取不到其中的resin.jar包)
三、安装Resin系统服务的指令为: 进入到Resin根目录,然后执行 httpd.exe -install-as 服务名;删除服务则为httpd.exe -remove-as 服务名

来自百度百科的一段Resin的简介:

resin

  Resin是CAUCHO公司(http://www.caucho.com/)的产品,是一个非常流行的支持servlets 和jsp的引擎,速度非常快。Resin本身包含了一个支持HTTP/1.1的WEB服务器。虽然它可以显示动态内容,但是它显示静态内容的能力也非常强,速度直逼APACHE SERVER。许多站点都是使用该WEB服务器构建的。
  Resin也可以和许多其他的WEB服务器一起工作,比如Apache server和IIS等。Resin支持Servlets 2.3标准和JSP 1.2标准。熟悉ASPPHP的用户可以发现用Resin来进行JSP编程是件很容易的事情。
  Resin支持负载平衡(Load balancing),可以增加WEB站点的可靠性。方法是增加服务器的数量。比如一台SERVER的错误率是1%的话,那么支持负载平衡的两个Resin服务器就可以使错误率降到0.01%。
  你可以从http://www.caucho.com/download/ 站点上查询Resin的最新版本并下载它。
  Resin服务器平台介绍简介:
  Resin提供了最快的jsp/servlets运行平台。在java和javascript的支持下,Resin可以为任务灵活选用合适的开发语言。Resin的一种先进的语言XSL(XML stylesheet language)可以使得形式和内容相分离。 如果您选用jsp平台作为internet商业站点的支持,那么速度、价格和稳定性都是要考虑到的,resin十分出色,表现更成熟,很具备商业软件的要求。而且,它是全免费的。从站点下载的就是完整版本。所以值得向您推荐! 相对于tomcat3.1,后者更象是一个正在研究的项目。目前resin可以支持sun的j2ee,而tomcat不能直接支持,而j2ee是基于java服务器端大系统的基础。但tomcat结构非常合理,而且是apache组织的产品,因此有着很好的远景。
  Resin1.1的特性包括:
  1 支持jsp1.1和在服务器端编译的javascript.
  2 比mod_perl,mod_php更快,比Jakarta Tomcat快3倍。您可以在Caucho的站点看到很全面的各种测试报告。
  3 使用servlet2.2引擎。
  4 自动的servlet/bean编译!
  5 Servlet,XSL Filtering
  6 支持IIS,Apache,Netscape和其它内置了HTTP/1.1的Web服务器。
  7 XSLT和XPath1.0引擎。
  8 企业级的共享软件(基于一个开放源码的协议)安装与启动:安装特别简单,只需将resin-1.1.3.zip解压缩到某个目录即可。在运行之前需要有jdk的支持。启动方式是执行:resin-1.1.3/bin/httpd (在NT)系统已经按照缺省设置启动,系统将监听8080端口。jsp文件可放在resin-1.1.3/doc目录下;servlet可以放在resin-1.1.3/doc/web-inf/classes下面。测试 从 http://localhost:8080/ 中可以看到resin的欢迎界面。 
  下载您可以在此下载最新的Resin1.1.3。大概是2.5M。
  Resin 3.1.9使用jdk 1.6会启动错误,必须使用jdk1.5。。。
  详细资料请参考:http://blog.chinaunix.net/u/15315/showart.php?id=171755
  http://www.cnxuexi.com/computer/wangzhankaifa/JSP/5927.html
  最新的resin版本为Resin 4.0.0 可从 http://www.caucho.com/download/ 上下载 有win 和linux 两个版本(2009-05-05 )
 

字符串转换为时间与数据库中时间比对的方法

题设:startDay是一个时间的字符串:“2009-11-04”
java.util.Date start = new java.util.Date();
start = Date.valueOf(startDay);
得到的start是Date类型,此时间可与数据库中的时间比对。

 

工厂模式

原文地址:http://www.javaeye.com/topic/26455

简单工厂模式

1. 目的 
        工厂模式就是专门负责将大量有共同接口的类实例化,而且不必事先知道每次是要实例化哪一个类的模式。它定义一个用于创建对象的接口,由子类决定实例化哪一个类。
2 . 简单工厂模式的结构 
 
Factory mode1

3. 一个简单例子 java 代码

  • // 产品接口         
  • public interface Product {   
  •   
  •     public void getName();   
  •   
  • }   
  •   
  • // 具体产品A   
  • public class ProductA implements Product {   
  •   
  •     public void getName() {   
  •         System.out.println(“  I am ProductA  ”);   
  •     }   
  •   
  • }   
  •   
  • // 具体产品B   
  • public class ProductB implements Product {   
  •   
  •     public void getName() {   
  •         System.out.println(“  I am ProductB  ”);   
  •     }   
  •   
  • }   
  •   
  • // 工厂类   
  • public class ProductCreator {   
  •   
  •     public Product createProduct(String type) {   
  •         if (“ A ”.equals(type)) {   
  •             return new ProductA();   
  •         }   
  •         if (“ B ”.equals(type)) {   
  •             return new ProductB();   
  •         } else  
  •             return null;   
  •     }   
  •   
  •     public static void main(String[] args) {   
  •         ProductCreator creator = new ProductCreator();   
  •         creator.createProduct(“ A ”).getName();   
  •         creator.createProduct(“ B ”).getName();   
  •     }   
  • }  
  • 4. 小结工厂模式的适用范围
    • 在编码时不能预见需要创建哪一种类的实例。
    • 一个类使用它的子类来创建对象。
    • 开发人员不希望创建了哪个类的实例以及如何创建实例的信息暴露给外部程序。  

     

    抽象工厂模式 

    1. 抽象工厂模式可以说是简单工厂模式的扩展,它们主要的区别在于需要创建对象的复杂程度上。
    在抽象工厂模式中,抽象产品可能是一个或多个,从而构成一个或多个产品族。 在只有一个产品族的情况下,抽象工厂模式实际上退化到工厂方法模式。
    2. 抽象工厂模式的结构 

     Factory mode2

    3. 一个简单例子

    java 代码

  • //  产品 Plant接口         
  • public interface Plant {   
  • }   
  •   
  • // 具体产品PlantA,PlantB   
  • public class PlantA implements Plant {   
  •   
  •     public PlantA() {   
  •         System.out.println(“ create PlantA ! ”);   
  •     }   
  •   
  •     public void doSomething() {   
  •         System.out.println(“  PlantA do something  ”);   
  •     }   
  • }   
  •   
  • public class PlantB implements Plant {   
  •     public PlantB() {   
  •         System.out.println(“ create PlantB ! ”);   
  •     }   
  •   
  •     public void doSomething() {   
  •         System.out.println(“  PlantB do something  ”);   
  •     }   
  • }   
  •   
  • // 产品 Fruit接口   
  • public interface Fruit {   
  • }   
  •   
  • // 具体产品FruitA,FruitB   
  • public class FruitA implements Fruit {   
  •     public FruitA() {   
  •         System.out.println(“ create FruitA ! ”);   
  •     }   
  •   
  •     public void doSomething() {   
  •         System.out.println(“  FruitA do something  ”);   
  •     }   
  • }   
  •   
  • public class FruitB implements Fruit {   
  •     public FruitB() {   
  •         System.out.println(“ create FruitB ! ”);   
  •     }   
  •   
  •     public void doSomething() {   
  •         System.out.println(“  FruitB do something  ”);   
  •     }   
  • }   
  •   
  • // 抽象工厂方法   
  • public interface AbstractFactory {   
  •     public Plant createPlant();   
  •   
  •     public Fruit createFruit();   
  • }   
  •   
  • // 具体工厂方法   
  • public class FactoryA implements AbstractFactory {   
  •     public Plant createPlant() {   
  •         return new PlantA();   
  •     }   
  •   
  •     public Fruit createFruit() {   
  •         return new FruitA();   
  •     }   
  • }   
  •   
  • public class FactoryB implements AbstractFactory {   
  •     public Plant createPlant() {   
  •         return new PlantB();   
  •     }   
  •   
  •     public Fruit createFruit() {   
  •         return new FruitB();   
  •     }   
  • }  
  • 4. 小结
    在以下情况下,应当考虑使用抽象工厂模式。
      首先,一个系统应当不依赖于产品类实例被创立,组成,和表示的细节。这对于所有形态的工厂模式都是重要的。
      其次,这个系统的产品有多于一个的产品族。
      第三,同属于同一个产品族的产品是设计成在一起使用的。这一约束必须得在系统的设计中体现出来。
      最后,不同的产品以一系列的接口的面貌出现,从而使系统不依赖于接口实现的细节。
      其中第二丶第三个条件是我们选用抽象工厂模式而非其它形态的工厂模式的关键性条件。

     

    关于Java中serialization(序列化)

    Object serialization的定义:

    Object serialization 允许你将实现了Serializable接口的对象转换为字节序列,这些字节序列可以被完全存储以备以后重新生成原来的对象。 
    serialization不但可以在本机做,而且可以经由网络操作(RMI)。这个好处是很大的—-因为它自动屏蔽了操作系统的差异,字节顺序(用Unix下的c开发过网络编程的人应该知道这个概念,我就容易在这上面犯错)等。比如,在Window平台生成一个对象并序列化之,然后通过网络传到一台Unix机器上,然后可以在这台Unix机器上正确地重构这个对象。

    Object serialization主要用来支持2种主要的特性:

    1。Java的RMI(remote method invocation).RMI允许象在本机上一样操作远程机器上的对象。当发送消息给远程对象时,就需要用到serializaiton机制来发送参数和接收返回直。
    2。Java的JavaBeans.   Bean的状态信息通常是在设计时配置的。Bean的状态信息必须被存起来,以便当程序运行时能恢复这些状态信息。这也需要serializaiton机制。

    二。关于持久化

    英文中是persistence.但是Java语言里现在只支持lightweight persistence,就是轻量级持久化,这是通过serialization机制来实现的。
    persistence是指一个对象的生命周期不由程序是否执行来决定,即使是在程序终止时这个对象也存在。它把一个serializable的对象写到磁盘(本机或其他机器上的非RAM存储器),并在程序重新调用时再读取对象到通常的RAM存储器。 举例而言,public class Student implements Serializable就是对这个Student 的javabean的持久应用序列化。
    为什么说Java的serialization机制实现的是lightweight persistence?因为你必须显式的序列化和反序列化程序里的对象;而不是直接由一个关键词来定义一个对象是序列化的然后由系统做相应的处理。

     

    Java JDBC链接各种数据库手册

    一直做企业内部应用,通过Java获取用户名方法为:
    System.getenv(“USERNAME”);

    下面罗列了各种数据库使用JDBC连接的方式,可以作为一个手册使用。
    1、Oracle8/8i/9i数据库(thin模式)
    Class.forName(“oracle.jdbc.driver.OracleDriver”).newInstance();
    String url=”jdbcracle:thinlocalhost:1521rcl”; //orcl为数据库的SID
    String user=”test”;
    String passWord=”test”;
    Connection conn= DriverManager.getConnection(url,user,password);
    2、DB2数据库
    Class.forName(“com.ibm.db2.jdbc.app.DB2Driver “).newInstance();
    String url=”jdbc:db2://localhost:5000/sample”; //sample为你的数据库名
    String user=”admin”;
    String password=”";
    Connection conn= DriverManager.getConnection(url,user,password);
    3、Sql Server7.0/2000数据库
    Class.forName(“com.microsoft.jdbc.sqlserver.SQLServerDriver”).newInstance();
    String url=”jdbc:microsoftqlserver://localhost:1433;DatabaseName=mydb”;
    //mydb为数据库
    String user=”sa”;
    String password=”";
    Connection conn= DriverManager.getConnection(url,user,password);
    4、Sybase数据库
    Class.forName(“com.sybase.jdbc.SybDriver”).newInstance();
    String url =” jdbcybase:Tds:localhost:5007/myDB”;//myDB为你的数据库名
    Properties sysProps = System.getProperties();
    SysProps.put(“user”,”userid”);
    SysProps.put(“password”,”user_password”);
    Connection conn= DriverManager.getConnection(url, SysProps);
    5、Informix数据库
    Class.forName(“com.informix.jdbc.IfxDriver”).newInstance();
    String url = “jdbc:informixsqli://
    123.45.67.89:1533/myDB:INFORMIXSERVER=myserver;
    user=testuser;password=testpassword”; //myDB为数据库名
    Connection conn= DriverManager.getConnection(url);
    6、mysql数据库
    Class.forName(“org.gjt.mm.mysql.Driver”).newInstance();
    String url =”jdbc:mysql://localhost/myDB?
    user=soft&password=soft1234&useUnicode=true&characterEncoding=8859_1″
    //myDB为数据库名
    Connection conn= DriverManager.getConnection(url);
    7、PostgreSQL数据库
    Class.forName(“org.postgresql.Driver”).newInstance();
    String url =”jdbcostgresql://localhost/myDB” //myDB为数据库名
    String user=”myuser”;
    String password=”mypassword”;
    Connection conn= DriverManager.getConnection(url,user,password);
    8、Access数据库直连用ODBC的
    Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”) ;
    String url=”jdbc:odbc:Driver={MicroSoft Access Driver 
    (*.mdb)};DBQ=”+application.getRealPath(“/Data/ReportDemo.mdb”);
    Connection conn = DriverManager.getConnection(url,”",”");
    Statement stmtNew=conn.createStatement();

     

    Java从文件路径中获取文件名的几种方法

    举例:String fName =” G:\Java_Source\navigation_tigra_menu\demo1\img\lev1_arrow.gif ”

    方法一:

    1
    2
    3
    
    File tempFile =new File( fName.trim());
     
    String fileName = tempFile.getName();

    方法二:

    1
    2
    3
    
    String fName = fName.trim();
     
    String fileName = fName.subString(fName.lastIndexOf("/")-1);

    方法三:

    1
    2
    3
    4
    5
    
    String fName = fName.trim();
     
    String temp[] = fName.split("\\\\"); /**split里面必须是正则表达式,"\\"的作用是对字符串转义*/
     
    String fileName = temp[temp.length-1];

    字符串处理,感觉像个游戏,挺好玩的~哈!

     

    Java 程序员必备的 Jar 包搜索引擎: findJar.com

    Java之所以在世界范围内掀起巨大的狂潮,很大程度得益于它的开源及因此带来的社区框架支援。

    应用外部类库开发Java应用早已经是家常便饭了。那么,当遇到Jar缺少,而面对错误信息手足无措的时候,不妨试试下面这个Jar包搜索引擎!findJar.com

    使用示例:

    2009-08-06_214811