blogjava-凯发k8网页登录http://www.blogjava.net/action/.....zh-cnsat, 08 apr 2023 20:37:53 gmtsat, 08 apr 2023 20:37:53 gmt60mysql集群之读写分离http://www.blogjava.net/action/archive/2011/10/18/361499.html我心依旧我心依旧tue, 18 oct 2011 01:58:00 gmthttp://www.blogjava.net/action/archive/2011/10/18/361499.htmlhttp://www.blogjava.net/action/comments/361499.htmlhttp://www.blogjava.net/action/archive/2011/10/18/361499.html#feedback0http://www.blogjava.net/action/comments/commentrss/361499.htmlhttp://www.blogjava.net/action/services/trackbacks/361499.html
n年没写blog了。好了废话不多说。直接上配置文件。都有注视如果有问题请联系我新浪微博


###############################主库配置###############################
#主机标示,整数
server-id=1
#确保此文件可写
log_bin=c:\mysql-bin.log
#主机,读写都可以
read-only=0
#需要备份数据,多个写多行
binlog-do-db=appcom
#不需要备份的数据库,多个写多行
binlog-ignore-db=mysql
###############################主库配置###############################
###############################从库配置###############################
#server-id=2
#log_bin=c:\mysql-bin.log
#master-host=172.16.33.44
#master-user=root
#master-pass=5719
#master-port=3306
#如果从服务器发现主服务器断掉,重新连接的时间差(秒)
#master-connect-retry=5
#只复制某个库
#binlog-do-db=appcom
#不复制某个库
#binlog-ignore-db=mysql
###############################从库配置###############################


我心依旧 2011-10-18 09:58 发表评论
]]>
这个blog五年没上了。欢迎同行做java的朋友加我的微博http://t.qq.com/javamailhttp://www.blogjava.net/action/archive/2011/03/17/346481.html我心依旧我心依旧thu, 17 mar 2011 09:54:00 gmthttp://www.blogjava.net/action/archive/2011/03/17/346481.htmlhttp://www.blogjava.net/action/comments/346481.htmlhttp://www.blogjava.net/action/archive/2011/03/17/346481.html#feedback0http://www.blogjava.net/action/comments/commentrss/346481.htmlhttp://www.blogjava.net/action/services/trackbacks/346481.html

我心依旧 2011-03-17 17:54 发表评论
]]>
ssh ajax整合简明实例http://www.blogjava.net/action/archive/2008/11/03/238427.html我心依旧我心依旧mon, 03 nov 2008 12:36:00 gmthttp://www.blogjava.net/action/archive/2008/11/03/238427.htmlhttp://www.blogjava.net/action/comments/238427.htmlhttp://www.blogjava.net/action/archive/2008/11/03/238427.html#feedback1http://www.blogjava.net/action/comments/commentrss/238427.htmlhttp://www.blogjava.net/action/services/trackbacks/238427.html







                                                        by michael


我心依旧 2008-11-03 20:36 发表评论
]]>
原创 struts spring hibernate (ssh) 整合实例http://www.blogjava.net/action/archive/2007/08/28/140566.html我心依旧我心依旧tue, 28 aug 2007 08:17:00 gmthttp://www.blogjava.net/action/archive/2007/08/28/140566.htmlhttp://www.blogjava.net/action/comments/140566.htmlhttp://www.blogjava.net/action/archive/2007/08/28/140566.html#feedback21http://www.blogjava.net/action/comments/commentrss/140566.htmlhttp://www.blogjava.net/action/services/trackbacks/140566.html首选创建web.xml 主要是配置struts的actionservlet和spring的字符过滤器


http://java.sun.com/xml/ns/j2ee" xmlns:xsi="" version="2.4" xsi:schemalocation="   ">
 
 
    characterencodingfilter
    org.springframework.web.filter.characterencodingfilter
   
      encoding
      utf-8
   

   
      forceencoding
      true
   

 

 
 
    characterencodingfilter
    /*
 

 
 
    action
    org.apache.struts.action.actionservlet
   
      config
      /web-inf/struts/struts.xml
   

   
      debug
      3
   

   
      detail
      3
   

    0
 

 
 
    action
    *.do
 

 
 
 
    10
 

 
 
 
    index.jsp
    index.html
 

 

 

然后创建struts.xml(string配置文件) 要注意这里集成了spring插件,把全部spring配置文件注入到contextloaderplugin中


http://struts.apache.org/dtds/struts-config_1_2.dtd">

 
 
 

 
   
 

 
        name="loginvo"
      type="org.springframework.web.struts.delegatingactionproxy"
      parameter="action"
      scope="request">
      
      
    

 

 
 
   
 


配置spring配置文件


http://www.springframework.org/dtd/spring-beans.dtd">

 
 
  
   
    classpath:hibernate.properties
   

  

 

 
 
    
  
  
  
    
  
  
   

 
   
     
        
     

       
           
                com/po/login.hbm.xml
           

       

       
      
         ${hibernate.dialect}
         ${hibernate.showsql}
      

     

   

 
   
    
      
    

   

 
   
    
      
    

    
      
           propagation_required,-exception
               propagation_required,-exception
               propagation_required,-exception
               propagation_required,-exception
               propagation_required,-exception
               propagation_required,-exception
               propagation_required,readonly
               propagation_required,readonly
               propagation_required,readonly
               propagation_required,readonly
               propagation_required
      

    

   




配置action将service注入到action


http://www.springframework.org/dtd/spring-beans.dtd">

 
  
   
         
       

  



配置service将dao注入到service


http://www.springframework.org/dtd/spring-beans.dtd">

 
   
    
      
    

   

   
       
         
       

   



配置dao 注入session工厂


http://www.springframework.org/dtd/spring-beans.dtd">

 
   
       
         
       

   



数据源属性文件(注意不是hibernate的配置文件,是为了让spring读入的)

hibernate.dialect=org.hibernate.dialect.sqlserverdialect
hibernate.driverclassname=com.mysql.jdbc.driver
hibernate.url=jdbc:mysql://127.0.0.1:3306/ssh
hibernate.username=root
hibernate.password=5719
hibernate.showsql=true
hibernate.maxactive=50
hibernate.maxidle=30
hibernate.maxwait=1000

log4j配置文件(简单)

log4j.rootlogger=error,console,file

log4j.appender.console=org.apache.log4j.consoleappender
log4j.appender.console.layout=org.apache.log4j.patternlayout
log4j.appender.console.layout.conversionpattern=%-5p %d [%f,%l] - %m%n

log4j.appender.file=org.apache.log4j.rollingfileappender
log4j.appender.file.file=f:\\ssh.log
#log4j.appender.file.maxfilesize=100000kb
#log4j.appender.file.maxbackupindex=1
log4j.appender.file.layout=org.apache.log4j.patternlayout
log4j.appender.file.layout.conversionpattern=%-5p %d [%f,%l] - %m%n

下面是类文件

package com.action;

import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;

import org.apache.commons.logging.log;
import org.apache.commons.logging.logfactory;
import org.apache.struts.action.actionform;
import org.apache.struts.action.actionforward;
import org.apache.struts.action.actionmapping;
import org.apache.struts.actions.dispatchaction;

import com.service.loginservice;
import com.vo.loginvo;

public class loginaction extends dispatchaction {

 private log logger = logfactory.getlog(loginaction.class);
 private loginservice loginservice;

 public void setloginservice(loginservice loginservice) {
  this.loginservice = loginservice;
 }

 public actionforward login(actionmapping mapping,actionform form,httpservletrequest request,httpservletresponse response) {
  try {
   loginvo loginvo = (loginvo) form;
   string username = loginvo.getusername();
   string password = loginvo.getpassword();
   system.out.println(username password);
   if(loginservice.validate(username, password)) {
    return mapping.findforward("index");
   }
   return mapping.findforward("error");
  } catch (exception e) {
   logger.error(e);
   return mapping.findforward("error");
  }
 }

 public actionforward save(actionmapping mapping,actionform form,httpservletrequest request,httpservletresponse response) {
  try {
   loginvo loginvo = (loginvo) form;
   loginservice.saveuser(loginvo);
   return mapping.findforward("index");
  } catch (exception e) {
   logger.error(e);
   return mapping.findforward("error");
  }
 }
}



package com.dao;

import java.util.list;

import org.springframework.orm.hibernate3.support.hibernatedaosupport;

import com.po.loginpo;

public class logindao extends hibernatedaosupport {

 @suppresswarnings("unchecked")
 public string getpassword(string username) {
  string hql = "from loginpo l where l.username=?";
  list list = getsession().createquery(hql).setstring(0,username).list();
  if(list!=null && list.size()>0) {
   loginpo loginpo = (loginpo) list.get(0);
   return loginpo.getpassword();
  }
  return null;
 }

 public void save(loginpo loginpo) {
  getsession().save(loginpo);
 }
}



package com.po;

import java.io.serializable;

public class loginpo implements serializable {

 private static final long serialversionuid = 1l;

 private integer id = null;
 private string username = null;
 private string password = null;

 public integer getid() {
  return id;
 }
 public string getpassword() {
  return password;
 }
 public string getusername() {
  return username;
 }
 public void setid(integer id) {
  this.id = id;
 }
 public void setpassword(string password) {
  this.password = password;
 }
 public void setusername(string username) {
  this.username = username;
 }
}



package com.service;

import com.dao.logindao;
import com.po.loginpo;
import com.vo.loginvo;

public class loginservice {

 private logindao logindao;

 public void setlogindao(logindao logindao) {
  this.logindao = logindao;
 }

 public boolean validate(string username,string password) {
  string pass = logindao.getpassword(username);
  if(pass!=null) {
   if(pass.equals(password)) {
    return true;
   }
  }
  return false;
 }

 public void saveuser(loginvo loginvo) {
  loginpo loginpo = new loginpo();
  loginpo.setusername(loginvo.getusername());
  loginpo.setpassword(loginvo.getpassword());
  system.out.println(loginvo.getusername() "-" loginvo.getpassword() ":save succeed...");
  logindao.save(loginpo);
  //故意制造异常,测试事务。
  //logindao.save(null);
 }
}



package com.vo;

import org.apache.struts.action.actionform;

public class loginvo extends actionform {

 private static final long serialversionuid = 1l;
 
 private string username = null;
 
 private string password = null;
 
 public string getpassword() {
  return password;
 }
 public string getusername() {
  return username;
 }
 public void setpassword(string password) {
  this.password = password;
 }
 public void setusername(string username) {
  this.username = username;
 }
}

hibernate映射文件


"">


   
       
       
       
   
   
  

       
       
           
               
           

       

       
       
           
               
           

       

   



jsp页面文件

<%@ page contenttype="text/html;charset=utf-8" language="java" %>


  


   

blogjava-凯发k8网页登录


   

username:

   
   

password:


   

   

   
  

  

  

  

  

   
   

username:

   
   

password:


   

   

   
  




jar包太多太大了这里就不发了.具体什么意思都有注视,完全实例,理论知识以后在说,欢迎拍砖嘎嘎...

我心依旧 2007-08-28 16:17 发表评论
]]>
北京有换工作的没,我们公司急聘中,高级软件工程师,系统分析师,我们soa项目,有兴趣的可以发简历到huanglia@163.com http://www.blogjava.net/action/archive/2007/06/29/127111.html我心依旧我心依旧fri, 29 jun 2007 09:29:00 gmthttp://www.blogjava.net/action/archive/2007/06/29/127111.htmlhttp://www.blogjava.net/action/comments/127111.htmlhttp://www.blogjava.net/action/archive/2007/06/29/127111.html#feedback1http://www.blogjava.net/action/comments/commentrss/127111.htmlhttp://www.blogjava.net/action/services/trackbacks/127111.html北京有换工作的没,我们公司急聘中,高级软件工程师,系统分析师,我们soa项目,有兴趣的可以发简历到huanglia@163.com
我qq是147372304

我心依旧 2007-06-29 17:29 发表评论
]]>
hibernate 解决sql count(*)的问题.http://www.blogjava.net/action/archive/2007/06/05/122089.html我心依旧我心依旧tue, 05 jun 2007 03:28:00 gmthttp://www.blogjava.net/action/archive/2007/06/05/122089.htmlhttp://www.blogjava.net/action/comments/122089.htmlhttp://www.blogjava.net/action/archive/2007/06/05/122089.html#feedback1http://www.blogjava.net/action/comments/commentrss/122089.htmlhttp://www.blogjava.net/action/services/trackbacks/122089.html// 用于hibernate 2.x
protected string getcountsql(string originalhql, net.sf.hibernate.sessionfactory sessionfactory) throws exception {
querytranslator translator = new querytranslator(originalhql);

translator.compile((net.sf.hibernate.engine.sessionfactoryimplementor)sessionfactory, collections.empty_map, false);

return "select count(*) from (" translator.getsqlstring() ") tmp_count_t";
}
// 用于hibernate 3.x
protected string getcountsql(string originalhql, org.hibernate.sessionfactory sessionfactory) throws exception {
querytranslatorimpl querytranslator = new querytranslatorimpl(originalhql, originalhql,
collections.empty_map, (org.hibernate.engine.sessionfactoryimplementor)sessionfactory);

querytranslator.compile(collections.empty_map, false);

return "select count(*) from (" querytranslator.getsqlstring() ") tmp_count_t";
}

string strhql = "select count(*) from tb_po";
long count = (long)session.createquery(strhql).uniqueresult();



我心依旧 2007-06-05 11:28 发表评论
]]>
理解session缓存机制 操纵持久化对象http://www.blogjava.net/action/archive/2007/05/24/119737.html我心依旧我心依旧thu, 24 may 2007 07:43:00 gmthttp://www.blogjava.net/action/archive/2007/05/24/119737.htmlhttp://www.blogjava.net/action/comments/119737.htmlhttp://www.blogjava.net/action/archive/2007/05/24/119737.html#feedback0http://www.blogjava.net/action/comments/commentrss/119737.htmlhttp://www.blogjava.net/action/services/trackbacks/119737.htmlhibernate向我们提供的主要的操纵数据库的接口,session就是其中的一个,它提供了基本的增,删,改,查方法.而且具有一个缓存机制,能够按照某个时间点,按照缓存中的持久化对象属性的变化来更新数据库,着就是session的缓存清理过程.在hibernate中对象分为三个状态,临时,持久化,游离.如果我们希望java里的一个对象一直存在,就必须有一个变量一直引用着这个对象.当这个变量没了.对象也就被jvm回收了.当然这个是最基本的常识了.当session的save()方法持久化了一个对象的时候,即使这个对象的引用变量小时了.这个对象也依然存在,因为sessoin里保存了一个这个对象的引用,当然session缓存被清空,这个对象就over了.在这个对象保存在sessoin的时候如果调用load()方法试图去数据库中加载一个对象,这个时候session会先判断缓存中有没有这个对象,如果有了,那么就不需要去数据库加载了.这样可以减少访问数据库的频率,还可以保证缓存中的对象于数据库的同步.
      session有两个方法,一个commit()事务提交方法,还有flush()刷新缓存方法,都有着清理缓存的作用,flush()进行缓存的清理,执行一系列的sql语句,但不会提交事务.而commit()方法会先调用flush()方法,然后在提交事务.session还有一个方法就是setfushmode()方法,用户设定清理缓存的时间点,主要有三种模式,默认flush.mode.auto
      1)flushmode.auto session的查询方法,commit方法,flush方法都会清理缓存.
      2)flushmode.commit session的commit方法,flush方法会清理缓存.
      3)flushmode.never session的flush方法会清理缓存.
对象的临时状态:刚用new创建对象的时候,它还没有被持久化,这个时候是临时状态.
对象的持久化状态:已经被加入到session的缓存中,通常所说的持久化对象就是只一个对象在这个状态的时候.
对象的游离状态:已经被持久化,但是不属于session的缓存的时候是游离状态.

我心依旧 2007-05-24 15:43 发表评论
]]>
分析hibernate映射的关联关系http://www.blogjava.net/action/archive/2007/05/23/119405.html我心依旧我心依旧wed, 23 may 2007 07:07:00 gmthttp://www.blogjava.net/action/archive/2007/05/23/119405.htmlhttp://www.blogjava.net/action/comments/119405.htmlhttp://www.blogjava.net/action/archive/2007/05/23/119405.html#feedback8http://www.blogjava.net/action/comments/commentrss/119405.htmlhttp://www.blogjava.net/action/services/trackbacks/119405.html      hibernate的映射关联关系和我们现实世界里事物的关联关系一样.比如在uml语言中,以客户customer和订单order的关系为例.一个客户可以发送多个订单,而一个订单只能属于一个客户,这是一对多的关联,因此可以成为单向关联.如果同时包含了两两种关联关系,就成为双向关联.在关系数据库中只有外键参照主键的关系.所以关系数据库实际上至支持一对一,或一对多的单向关系.在类于类之间的关系中.要算多对一关系和数据库中的外键参照主键关系最匹配了.因此如果使用单向关联从订单到客户的多对一单向关联,在订单类中就要定义一个客户的属性.表示这个订单属于哪个客户,而客户类就无需定义存放订单的集合属性了.下面写一个简单的例子.
//首先定义客户类
public class customer implements sreializable {
   private long id;
   private string name;
   //省略属性的访问方法
}
//然后定义订单类
public class order implements sreializable {
   private long id;
   private string ordername;
   private customer customer;
   //省略属性的访问方法,要注意的是customer的访问方法.
}
customer类的所有属性和customers表的所有属性一一对应,创建起来就比较简单了.下面主要看一下order类的映射文件.

   

因为customer属性是是customer类型,而orders表的customer_id是整数类型,是不匹配的.所以我们不能用普通的元素来定义,而我们需要使用元素来配置了.

元素负责建立order订单类的customer属性和数据库中的customer_id外键字段之间的映射.
name:设定映射文件的属性名
column:设定和持久化类对应的表的外键名
class:设定持久化类的属性的类型,这里指定具体的类,也就是主键存在的类
not-null:设定为true表示customer属性不允许为null,默认是false,这个属性会影响到bhm2ddl工具,会为orders表的customer_id外键设置为不允许空的约束,但是不会影响到hbm2java工具生长java源代码.此外还会影响到hibernate运行时的行为,在保存order对象的时候会检查customer属性是否为null.用hbm2ddl编译之后得到的数据库文件如下:

create table customers (
   id bigint not null,
   name varchar(15),
   primary key (id)
);
create table orders (
   id bigint not null,
   order_number varchar(15),
   customer_id bigint not null,
   primary key (id)
);
alter table orders add index fk8b7256e516b4891c (customer_id),
add constraint fk8b7256e516b4891c foreign key (customer_id) references customers (id);
看到结果我们可以简单的把理解为在数据库中,创建外键的作用.上边这个例子就简单的演示了hibernate映射的一对一关联关系,至于一对多的关联关系比这个稍微复杂一点.而且可以看出,当hibernate持久化一个临时对象的时候,在默认的情况下它不会自动持久化关联其他临时对象,而是会抛出transientobjectexception异常.如果希望hibernate持久化对象的时候也自动持久化说关联的对象,就要把元素的cascade属性设置为save-update,表示级联操作的意思,cascade属性的默认值为none.当这个属性设置ok了.数据库就实现了级联保存更新的操作.
      在类和类之间建好了关联关系之后,就可以方便的从一个对象得到它关联的对象.例如customer customer=order.getcustomer();这样获得的了customer对象了.但是如果想获得所有属于customer客户的order订单对象,就涉及到了一对多双向关联了.在内存中,从一个对象导航都另一个对象要比从数据库中通过一个字段查询另一个字段快的多的多,但是也给编程的时候带来了麻烦,随意修改一个对象就可能牵一发而动全身,所以说双向的关联比较复杂,但是类和类之间到底建立单向还是双向关联,这个要根据业务需求来决定.比如说业务需求根据指定客户查询客户所有订单,根据指定的订单,查询出发这个订单的客户.这个时候我们不妨用多对一双向关联处理.其实上边的例子的映射文件已经简历了客户和订单之间的一对多双向关联关系,只不过要在客户类中加一个集合的属性:
private set orders = new hashset();
public set getorders() {
   return orders;
}
public void setorders(set orders) {
   this.orders = orders;
}
有了orders属性,客户就可以通过getorders()方法或者客户的全部订单了,hibernate在定义这个集合属性的时候必须声明为接口类型,但是不光光是set还有map和list,这样可以提高程序的强壮性,就是说set方法接受的对象只要是实现了set接口就ok.避免出现null值的现象.这里要注意的是hbm2java工具生成类的集合属性的代码时,不会给它初始化一个集合对象的实例,这里我们需要自己手动修改,当然不修改也是可以的.接下来还要在customer.hbm.xml映射文件里映射集合类型的orders属性,当然这个和order表的的同理,所以不能通过普通的元素来设置属性和字段的映射关系.要使用元素来设置:




name:设定类的属性名
cascade:设置为save-update表示级联保存更新,当保存或更新customer类的时候会级联保存更新跟它关联的order类.
元素是用来设定跟持久化类关联的类的外键
元素看起来很熟悉,哦是设置外键的元素反过来了.这里它是用来设置所关联的持久化类的.这里设置为和客户关联的订单order类,这里表明这个属性里要存放一组order类型的对象.
这个元素是表示orders属性声明为set类型.
元素还有一个inverse属性,这个方法主要是在给已存在数据库中的字段建立关联的时候很有用.就是说当我们获得数据库中的两个表的两条记录的对象customer客户对象和order订单对象(映射文件已经建立了他们类和类之间的关联,但外键的值为null的情况下)然后我们想建立这个客户对象和订单对象之间的关联,我们要先调用order.setcustomer(customer);然后在调用customer.getorder().add(order);在hibernate自动清理缓存的持久化对象的时候会提交两条sql语句.进行了两个update操作.但是实际上只修改了一条记录.重复的执行sql语句是会降低系统的运行效率的,当把inverse属性设置为true的时候,同样的操作就会合并到一条sql语句执行了,inverse默认为false;
      级联删除就很简单了,把cascade属性设置为delete,如果你删除了一个客户,程序就会先执行删除这个客户全部的订单的sql语句,然后在删除这个客户,所谓删除一个持久化对象不是在内存中删除这个对象,而是删除数据库中相关的记录,这个对象依然在内存中,只不过由持久化状态转为临时状态,当这个对象的引用消失后,这个对象会被垃圾回收.但是如果我又想级联删除,还想级联保存,更新的时候应该怎么办呢?这个时候我们将cascade属性设置为all-delete-orphan就ok了.非常简单明了.我们还可以通过持久化类的customer.getorder().rumove(order);解除关联.这里的操作表示获得客户订单的集合对象,然后从集合对象中删除order的订单,其实这种操作的意义不大,当我们不需要的这个订单的时候完全可以删除它,解除关联之后如果设置了级联删除属性,这个无用的记录也是要被删除的.其实解除关联就是把外键设为null.通常我们的外键都要约束不可以为空.
      映射关联还有一种多对多的关联,是一种自身关联关系.就是同一张表.自己和自己的关联.比如说一张人表,地球人是人,美国人,中国人,日本人都属于地球人,中国人有分北京人,山东人.日本人也有下一级的比如东京人.下面设想如果日本人被消灭掉了,那么东京人也应该都被没有了吧,这就是一种关系,自身对自身的关联关系.这就有点类似树的结构了.下面用一个例子演示这种关系,代码来源于孙mm的<<精通hibernate>>一书.
public class category implements serializable {

    private long id;

    private string name;

    private category parentcategory;

    private set childcategories;

    public category(string name, mypack.category parentcategory, set childcategories) {
        this.name = name;
        this.parentcategory = parentcategory;
        this.childcategories = childcategories;
    }

    public category() {
    }

    public category(set childcategories) {
        this.childcategories = childcategories;
    }

    public category getparentcategory() {
        return this.parentcategory;
    }

    public void setparentcategory(category parentcategory) {
        this.parentcategory = parentcategory;
    }

    public set getchildcategories() {
        return this.childcategories;
    }

    public void setchildcategories(set childcategories) {
        this.childcategories = childcategories;
    }
   //为了节省空间省略了id,name属性的访问方法

}

 
   
     
   

   
       
   

            name="childcategories"
        cascade="save-update"
        inverse="true"
        >
       
       
    
  
           name="parentcategory"
        column="category_id"
        class="mypack.category"
       />
 


      我觉得这种方式其实和上边的一对多,一对一关系一样,只不过两个用的都是同一个类罢了.看一下例子理解上应该很简单.      



我心依旧 2007-05-23 15:07 发表评论
]]>
映射对象标识符http://www.blogjava.net/action/archive/2007/05/22/119134.html我心依旧我心依旧tue, 22 may 2007 07:05:00 gmthttp://www.blogjava.net/action/archive/2007/05/22/119134.htmlhttp://www.blogjava.net/action/comments/119134.htmlhttp://www.blogjava.net/action/archive/2007/05/22/119134.html#feedback1http://www.blogjava.net/action/comments/commentrss/119134.htmlhttp://www.blogjava.net/action/services/trackbacks/119134.html      hibernate采用对象标识符,也就是通常我们所说的oid来创建对象和数据库表里记录的对应关系,对象的oid和表里的主键对应,所以说oid是非常重要的,不应该让程序来给它赋值.数据库区分同一表的不同记录是用主键来区分.数据库中的主键最重要的3个基本要素就是不允许为null,不允许有重复值,主键永远不会改变.所以通常我们设计表都会设计主键的值为自动增加,没有业务逻辑含义的一组数字,当然针对每个数据库,设置的方法也不同.但是都非常简单.加一个属性就可以了.
      而java区分同一类的不同对象是用内存地址,在java语言中判断两个对象的引用变量是否想相等,有以下两种比较方式.1)用运算符"=="比较内存地址,此外还可以用object的equals方法也是按内存地址比较.2)比较两个对象的值是否相同,java中的一些覆盖了object类的equals方法实现比较合适.例如string和date类,还有java包装类.如果是string.equals(string)这种方式的比较就是比较这两个string的值的.如果是object原是的equals方法就是比较地址了.这点很容易混淆.
      通常,为了包装hibernate的oid的唯一性和不可变性,由hibernate或者底层数据库来给oid赋值比较合理.因此我们在编程的时候最好把持久化类的oid设置为private或者protected类型,这样可以防止java程序随便更改oid.而oid的get方法我们还是要设置为public类型,这样方便我们读取. 在对象-关系映射文件里的      1)increment 代理主键,hibernate自动以递增的方式来生成标识符,每次增加1.
      2)identity 代理主键,由底层数据库生成标识符,前提就是底层的数据库支持自动增长的类型.
      3)sequence 代理主键,hibernate根据底层数据库生成的标识符,前提是底层数据库支持序列
      4)hilo 代理主键,hibernate根据higg/low算法来生成的标识符,把特定表的字段作为high的值,默认选用hibernate_unique_key表的next_hi字段
      5)native 代理主键,根据底层数据库对自动生成标识符的支持能力,还选择identity,sequence,或hilo.
      6)uuid.hex 代理主键,hibernate采用128位的uuid算法生成标识符,uuid算法能够在网络环境下生成唯一字符串标识符.不过字符串要比数据占用的空间多的多.所以不流行使用.
      7)assigned 适用于自然主键,由java应用程序负责生成标识符,为了能让java设置oid.不能吧setid方法设置为非公共类型了,这种方式也尽量避免使用.
      这里个人觉得第一种方式,也就是说由hibernate来生成对象标识符的方式比较好.但是这种方式的缺点是只能一个hibernate对应一个数据库的表.当同时创建了seesionfactory实例的时候.两个或者更多的hibernate对应同一个数据库的时候就会插入出错.这个时候我们可以选择第二种方式把标识符的生成工作交给底层数据库.还有一个小知识点要注意就是oid必须定义为long,int,short类型,如果定义为byte会报异常,这里推荐用long.
      总结一下,这7中生成oid标识符的方法,increment 比较常用,把标识符生成的权力交给hibernate处理.但是当同时多个hibernate应用操作同一个数据库,甚至同一张表的时候.就推荐使用identity 依赖底层数据库实现,但是数据库必须支持自动增长,sequence 以来底层数据库实现,但是数据库必须支持系列.hilo 根据特定的表实现.这三种方式了.当然针对不同的数据库选择不同的方法.如果你不能确定你使用的数据库具体支持什么的情况下.可以选择第三种.或者用native 让hibernate来帮选择identity,sequence,或hilo.后边的自然主键不推荐使用,因为自然主键就是具有业务含义的主键,在现在的软件开发结构中,已经很少有人用了.下面总结一下几种常用数据库,可以使用的标识符类型.
      mysql:identity数据库底层实现,需要支持自动增长,increment由hibernate实现,hilo用特定的表实现,
      mssql:identity数据库底层实现,需要支持自动增长,increment由hibernate实现,hilo用特定的表实现,
      oracle:sequence数据库底层实现,需要支持序列,increment由hibernate实现,hilo用特定的表实现,
      以上不难发现,所有的数据库都支持hibernate用increment实现oid的生成,mysql和mssql数据库底层实现支持自动增长,而oracle支持序列,还有用特殊表的实现方式这三个数据库都支持.还有一种实现方式适用于所有的数据库,就是native,由hibernate去选择使用什么样的方式来生成iod对象标识符,这种方式也是跨平台的.下面是各种设置方式的例子*.hbm.xml文件四个.例题来源孙mm的<<精通hibernate>>一书.我非常喜欢这本书,讲的非常简单明了.感兴趣的朋友可以去买一本看看(当当打7.3折哦).

public "-//hibernate/hibernate mapping dtd 2.0//en"
"">

 
   
   
   
                hi_value
                next_value
                100
       

   

   
       
   

   
 
 


public "-//hibernate/hibernate mapping dtd 2.0//en"
"">

 
   
   
     
   

   
       
   

   
 
 


public "-//hibernate/hibernate mapping dtd 2.0//en"
"">

 
   
   
     
   

   
       
   

   
 
 


public "-//hibernate/hibernate mapping dtd 2.0//en"
"">

 
   
   
      private
     
   

   
       
   

   
 
 



我心依旧 2007-05-22 15:05 发表评论
]]>
hibernate orm 对象-关系 映射http://www.blogjava.net/action/archive/2007/05/21/118886.html我心依旧我心依旧mon, 21 may 2007 07:21:00 gmthttp://www.blogjava.net/action/archive/2007/05/21/118886.htmlhttp://www.blogjava.net/action/comments/118886.htmlhttp://www.blogjava.net/action/archive/2007/05/21/118886.html#feedback2http://www.blogjava.net/action/comments/commentrss/118886.htmlhttp://www.blogjava.net/action/services/trackbacks/118886.html       hibernate的持久化类使用的是javabean的风格,为要被访问的属性提供了一套get和set方法,这两个方法也叫做持久化类的访问方法.记得曾经在接触javabean的时候我很迷糊,总觉得提供这两个方法,倒不如把bean的属性设置public,然后直接调用对象.属性,这样来的方便.但是后来,有一个这样的需求,就是一个人名字可以被查看,但是不可以修改.这个时候如果用set方法的话,只需要把set方法的修饰符换为private就ok了.如果是用对象.属性的形式调用就麻烦了.而且最重要的一个有点是javabean的风格可以简化hibernate通过java反射机制来获得持久化类的访问方法的过程,至于java的反射机制我也是了解一些皮毛.据说很深奥.有兴趣的朋友可以google一下.有一点值得注意,就是java应用程序不能访问javabean持久化类的private类型的get,set方法.而hibernate没有这个限制,可以访问所有的级别.包括private default,protected,public.
      java有8种基本类型:byte,short,char,int,long,float,double,boolean,还有8种与之对应的包装类型,byte,short,character,integer,long,float,double,boolean包装类型就是把基本类型包装成对象的意思.基本类型于包装类型之间可以方便的转换,例如:
      int i = 0;
      integer ie = new integer(i);//基本类型转换成包装类型
      i = ie.intvalue();//包装类型转化成基本类型

      注意,直接转换也是可以的.例如i = ie; java会自动把包装类型转换成基本类型.或者ie = i; java会自动把基本类型转换成包装类型.在持久化类中,既可以把属性定义为基本类型,也可以定义为包装类型,他们对应的hibernate映射类型int和integer都对应int类型,这个表示不是很明显,在用java对象类型字符串举例string,数据库是varhcar(50),在hibernate的*.hbm.xml映射文件里一律写为string.其实使用基本类型或者包装类型来定义持久化类中的属性是各有优缺点的.基本类型就是使用方便,简单,在需要数字运算的时候直接可以运算.而包装类型就要麻烦的先转换成基本类型,然后在进行运算,但是包装类型的优点在于能表达null值,每一个包装类型的对象创建的时候默认值都是null类型的.而基本类型是不可以表达null的,它们的默认值是0.为什么要表达null值呢.因为sql中.所有类型的数据,默认值都是null的.当进入insert的时候,没有复值的属性,默认值就是null,所以说java的包装类型和数据库之间的对应关系更直接.这里建议hibernate的oid设置为包装类型,其他的属性就根据业务需要和个人习惯来定吧.
      hibernate在初始化阶段会根据映射文件的信息,为所有的持久化类预定义insert语句,update语句where id,delete语句where id,select语句where id,这里所说的语句就是标准的sql增,删,改,查.语句,参数用?代表jdbc preparedstatement中的参数,这里就不举例了.这些sql语句都存放在sessionfactory的缓存中,当执行session的save(),update(),delete(),load()方法时,将会从sessionfactory的缓存中读取这些预定义的sql语句,在把具体的参数值绑定到sql语句中,这就是hibernate的基本原理.在默认的情况下这些语句表达的是所有的字段.当然hibernate还允许我们在映射文件里控制insert和update语句的内容.比如在映射文件中      1)元素 insert属性:设置为false,在insert语句中不包含这个字段,表示永远不会被插入,默认true
      2)元素 update属性:设置为false,在update语句中不包含这个字段,表示永远不会被修改,默认true
      3)元素 mutable属性:设置为false就是把所有的元素的update属性设置为了false,说明这个对象不会被更新,默认true
      4)元素 dynamic-insert属性:设置为true,表示insert对象的时候,生成动态的insert语句,如果这个字段的值是null就不会加入到insert语句当中.默认false
      5)元素 dynamic-update属性,设置为true,表示update对象的时候,生成动态的update语句,如果这个字段的值是null就不会被加入到update语句中,默认false
      6)元素 dynamic-insert属性:设置为true,表示把所有的元素的dynamic-insert属性设置为true,默认false
      7)元素 dynamic-update属性:设置为true,表示把所有的元素的dynamic-update属性设置为true,默认false

      hibernate生成动态sql语句的消耗的系统资源(比如cpu,内存等)是很小的,所以不会影响到系统的性能,如果表中包含n多字段,建议把dynamic-update属性和insert属性设置为true,这样在插入和修改数据的时候,语句中只包括要插入或者修改的字段.可以节省sql语句的执行时间,提高程序的运行效率.
      


我心依旧 2007-05-21 15:21 发表评论
]]>
网站地图