1. 基本操作
下面的例子使用的表computer的定义如下:
create table `hibernate`.`computer`( `id` int not null auto_increment, `cpu` varchar ( 50 ), `mainboard` varchar ( 50 ), `displaycard` varchar ( 50 ), `harddisk` varchar ( 50 ), `display` varchar ( 50 ), `memory` varchar ( 50 ), `soundcard` varchar ( 50 ), `cdrom` varchar ( 50 ), `mouse` varchar ( 50 ), `keyboard` varchar ( 50 ), primary key (`id`) ); create unique index ` PRIMARY ` on `hibernate`.`computer`(`id`);对应的Computer类如下:
package com.weportal.computer; import java.io.Serializable; import org.hibernate.CallbackException; import org.hibernate.Session; import org.hibernate.classic.Lifecycle; public class Computer implements Lifecycle ... { private int id; private String cpu; private String mainboard; private String memory; private String harddisk; private String display; private String keyboard; private String mouse; private String displaycard; private String soundcard; private String cdrom; /** *//** * @return Returns the cpu. * @hibernate.property * */ public String getCpu() ...{ return cpu; } /** *//** * @param cpu * The cpu to set. */ public void setCpu(String cpu) ...{ this.cpu = cpu; } /** *//** * @return Returns the display. * @hibernate.property */ public String getDisplay() ...{ return display; } /** *//** * @param display * The display to set. */ public void setDisplay(String display) ...{ this.display = display; } /** *//** * @return Returns the displaycard. * @hibernate.property */ public String getDisplaycard() ...{ return displaycard; } /** *//** * @param displaycard * The displaycard to set. */ public void setDisplaycard(String displaycard) ...{ this.displaycard = displaycard; } /** *//** * @return Returns the harddisk. * @hibernate.property */ public String getHarddisk() ...{ return harddisk; } /** *//** * @param harddisk * The harddisk to set. */ public void setHarddisk(String harddisk) ...{ this.harddisk = harddisk; } /** *//** * @return Returns the id. * @hibernate.id generator-class = "native" */ public int getId() ...{ return id; } /** *//** * @param id * The id to set. * */ public void setId(int id) ...{ this.id = id; } /** *//** * @return Returns the keyboard. * @hibernate.property s */ public String getKeyboard() ...{ return keyboard; } /** *//** * @param keyboard * The keyboard to set. */ public void setKeyboard(String keyboard) ...{ this.keyboard = keyboard; } /** *//** * @return Returns the mainboard. * @hibernate.property */ public String getMainboard() ...{ return mainboard; } /** *//** * @param mainboard * The mainboard to set. */ public void setMainboard(String mainboard) ...{ this.mainboard = mainboard; } /** *//** * @return Returns the memory. * @hibernate.property */ public String getMemory() ...{ return memory; } /** *//** * @param memory * The memory to set. */ public void setMemory(String memory) ...{ this.memory = memory; } /** *//** * @return Returns the mouse. * @hibernate.property */ public String getMouse() ...{ return mouse; } /** *//** * @param mouse * The mouse to set. */ public void setMouse(String mouse) ...{ this.mouse = mouse; } /** *//** * @return Returns the soundcard. * @hibernate.property */ public String getSoundcard() ...{ return soundcard; } /** *//** * @param soundcard * The soundcard to set. */ public void setSoundcard(String soundcard) ...{ this.soundcard = soundcard; } /** *//** * @return Returns the cdrom. * @hibernate.property */ public String getCdrom() ...{ return cdrom; } /** *//** * @param cdrom * The cdrom to set. */ public void setCdrom(String cdrom) ...{ this.cdrom = cdrom; } public boolean onSave(Session s) ...{ System.out.println("on save"); return false; } public boolean onUpdate(Session s) throws CallbackException ...{ System.out.println("on update"); return false; } public boolean onDelete(Session s) throws CallbackException ...{ System.out.println("on delete"); return false; } public void onLoad(Session s, Serializable id) ...{ System.out.println("on load"); } /** *//** * constructor */ public Computer(String... values) ...{ for (int i = 0; i < values.length; i++) ...{ switch (i) ...{ case 0: setCpu(values[i]); break; case 1: setCdrom(values[i]); break; case 2: setDisplay(values[i]); break; case 3: setDisplaycard(values[i]); break; case 4: setHarddisk(values[i]); break; case 5: setSoundcard(values[i]); break; case 6: setKeyboard(values[i]); break; case 7: setMainboard(values[i]); break; case 8: setMemory(values[i]); break; case 9: setMouse(values[i]); break; } } } public Computer()...{ }}映射文件Computer.hbm.xml的内容如下:
<? xml version="1.0" ?> <! DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" > < hibernate-mapping package ="com.weportal.computer" > < class name ="com.weportal.computer.Computer" > < id name ="id" type ="int" > < generator class ="native" ></ generator > </ id > < property name ="cpu" length ="50" ></ property > < property name ="mainboard" length ="50" ></ property > < property name ="displaycard" length ="50" ></ property > < property name ="harddisk" length ="50" ></ property > < property name ="display" length ="50" ></ property > < property name ="memory" length ="50" ></ property > < property name ="soundcard" length ="50" ></ property > < property name ="cdrom" length ="50" ></ property > < property name ="mouse" length ="50" ></ property > < property name ="keyboard" length ="50" ></ property > </ class > </ hibernate-mapping >1.1 新建数据
利用Hibernate新建一个持久化类的对象实例,并将这个对象实例传递到数据库的过程等价于利用JDBC在数据库中建立一行新的数据记录。 简单的持久化类如下所示:
package com.weportal.hibernate; import org.apache.log4j.PropertyConfigurator; import org.hibernate.FlushMode; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import com.weportal.computer.Computer; public class NewPOExample ... { public static void main(String[] args) ...{ PropertyConfigurator.configure("log4j.Properties"); Configuration cfg = new Configuration(); cfg.configure(); SessionFactory sf = cfg.buildSessionFactory(); Session sess = sf.openSession(); sess.setFlushMode(FlushMode.COMMIT); Transaction t = sess.beginTransaction(); Computer pc = new Computer(); pc.setCpu("intel 3.9"); pc.setDisplay("LG"); pc.setDisplaycard("geforce 4"); pc.setHarddisk("WD120JB"); pc.setMainboard("gigabyte"); pc.setMemory("kingMax1024MB"); pc.setMouse("logitech"); pc.setSoundcard("creative"); pc.setKeyboard("logitech"); //pc.setId(10); System.out.println("id is : " + pc.getId()); System.out.println(sess.getFlushMode()); sess.save(pc); t.commit(); sess.close(); }}程序执行的结果是向数据库中添加了一条新的记录。
1.2 导出数据对象
1.2.1 使用load方法
package com.weportal.hibernate; import org.apache.log4j.PropertyConfigurator; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import com.weportal.computer.Computer; public class LoadPOExample ... { public static void main(String[] args) ...{ PropertyConfigurator.configure("log4j.Properties"); Configuration cfg = new Configuration(); cfg.configure(); SessionFactory sf = cfg.buildSessionFactory(); Session sess = sf.openSession(); Transaction t = sess.beginTransaction(); Computer pc = new Computer(); sess.load(pc,new Integer(1)); //Computer pc = (Computer)sess.load(Computer.class, new Integer(2)); System.out.println(pc.getCpu()); //pc.setCpu("CTU season 1"); sess.save(pc); t.commit(); sess.close(); }}1.2.2 使用get方法
get()方法在执行时不会因为指定的数据行不存在而抛出异常,而是返回一个null对象。
package com.weportal.hibernate; import org.apache.log4j.PropertyConfigurator; import org.hibernate.LockMode; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import com.weportal.computer.Computer; public class GetPOExample ... { public static void main(String[] args) ...{ PropertyConfigurator.configure("log4j.Properties"); Configuration cfg = new Configuration(); cfg.configure(); SessionFactory sf = cfg.buildSessionFactory(); Session sess = sf.openSession(); Transaction t = sess.beginTransaction(); Computer pc = (Computer) sess.get(Computer.class,new Integer(10),LockMode.UPGRADE); if(pc!=null)pc.setCpu("AMD 4.0"); else...{ pc = new Computer(); pc.setCpu("AMD 4.0"); } sess.save(pc); t.commit(); sess.close(); }}1.3 查询数据
1.3.1 HQL查询
createQuery()方法是用来创建HQL语句查询对象的。
package com.weportal.hibernate; import java.util.Iterator; import java.util.List; import org.apache.log4j.PropertyConfigurator; import org.hibernate.FlushMode; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import com.weportal.computer.Computer; public class ComputerQuery ... { public static void main(String[] args) ...{ PropertyConfigurator.configure("log4j.Properties"); Configuration cfg = new Configuration(); cfg.configure(); SessionFactory sf = cfg.buildSessionFactory(); Session sess = sf.openSession(); sess.setFlushMode(FlushMode.COMMIT); Transaction t = sess.beginTransaction(); Query q = sess.createQuery("from Computer where cpu = 'Intel 奔腾 P4 2.3B GHz'");/**//* for(Iterator it = q.iterate();it.hasNext();){ Computer pc = (Computer)it.next(); System.out.println(pc.getCpu()); }*/ List results = q.list(); for(Iterator it = results.iterator();it.hasNext();)...{ Computer pc = (Computer)it.next(); System.out.println(pc.getCpu()); } t.commit(); sess.close(); }}1.3.2 条件查询示例代码如下:
package com.weportal.hibernate; import java.util.Iterator; import java.util.List; import org.apache.log4j.PropertyConfigurator; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.criterion.Expression; import com.weportal.computer.Computer; public class CriteriaQuery ... { public static void main(String[] args) ...{ PropertyConfigurator.configure("log4j.Properties"); Configuration cfg = new Configuration(); cfg.configure(); SessionFactory sf = cfg.buildSessionFactory(); Session sess = sf.openSession(); Criteria cr = sess.createCriteria(Computer.class); cr.add(Expression.eq("cpu","intel 3.9")); List ps = cr.list(); System.out.println("this is the result begin:"); for(Iterator it = ps.iterator();it.hasNext();)...{ System.out.println(((Computer)it.next()).getCpu()); } sess.close(); System.out.println("this is the result end."); }}1.3.3 滚动结果集示例代码:
package com.weportal.hibernate; import org.apache.log4j.PropertyConfigurator; import org.hibernate.Query; import org.hibernate.ScrollMode; import org.hibernate.ScrollableResults; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import com.weportal.computer.Computer; public class ComputerScrollView ... { public static void main(String[] args) ...{ PropertyConfigurator.configure("log4j.Properties"); Configuration cfg = new Configuration(); cfg.configure(); SessionFactory sf = cfg.buildSessionFactory(); Session sess = sf.openSession(); Transaction t = sess.beginTransaction(); Query q = sess.createQuery("from Computer as pc"); ScrollableResults sr = q.scroll(ScrollMode.SCROLL_INSENSITIVE); while(sr.next())...{ Computer pc = (Computer) sr.get(0); System.out.println(((Computer) sr.get(0)).getCpu()); } sr.first(); System.out.println(((Computer) sr.get(0)).getCpu()); sr.next(); System.out.println(((Computer) sr.get(0)).getCpu()); sr.previous(); System.out.println(((Computer) sr.get(0)).getCpu()); sr.close(); t.commit(); sess.close(); }}1.4 更新数据
Session接口的update()方法可以更新持久化数据对象,使其对象属性的状态改变传递到数据库。
package com.weportal.hibernate; import org.apache.log4j.PropertyConfigurator; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import com.weportal.computer.Computer; public class UpdateExample ... { public static void main(String[] args) ...{ PropertyConfigurator.configure("log4j.Properties"); Configuration cfg = new Configuration(); cfg.configure(); SessionFactory sf = cfg.buildSessionFactory(); Session sess01 = sf.openSession(); Transaction t01 = sess01.beginTransaction(); Computer pc01 = new Computer(); sess01.load(pc01,new Integer(2)); pc01.setCpu("intel 2.4"); sess01.update(pc01); t01.commit(); sess01.close(); Session sess02 = sf.openSession(); sess02.load(pc01,new Integer(2)); System.out.println(pc01.getCpu()); sess02.close(); }}1.5 删除数据
delete()方法,由于持久化对象对应于数据库中数据表的一行记录,所以在Session删除持久化类对象的同时,表中对应的记录也被删除。
package com.weportal.hibernate; import org.apache.log4j.PropertyConfigurator; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import com.weportal.computer.Computer; public class DeletePO ... { public static void main(String[] args) ...{ PropertyConfigurator.configure("log4j.Properties"); Configuration cfg = new Configuration(); cfg.configure(); SessionFactory sf = cfg.buildSessionFactory(); Session sess = sf.openSession(); Transaction t = sess.beginTransaction(); Computer pc = new Computer(); sess.load(pc,new Integer(1)); sess.delete(pc); t.commit(); sess.close(); }}1.6 数据对象的生命周期(Life Cycle)
在Hibernate中,持久化类对象存在生命周期,持久化类可以通过实现LifeCycle接口的方法来添加处理生命周期事件的方法。上面的Computer类即实现了该接口。
1.7 Session的缓冲
Session可以为持久化数据对象建立缓冲,同时也可利用Session的evict()方法从其缓冲中删除持久化对象的实例。
package com.weportal.hibernate; import org.apache.log4j.PropertyConfigurator; import org.hibernate.FlushMode; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import com.weportal.computer.Computer; public class SessEvictTest ... { public static void main(String[] args) ...{ PropertyConfigurator.configure("log4j.Properties"); Configuration cfg = new Configuration(); cfg.configure(); SessionFactory sf = cfg.buildSessionFactory(); Session sess = sf.openSession(); sess.setFlushMode(FlushMode.COMMIT); Transaction t = sess.beginTransaction(); Computer pc = (Computer) sess.get(Computer.class,new Integer(2)); pc.setCpu("amd 3.5"); sess.save(pc); sess.flush(); sess.evict(pc); sess.refresh(pc); t.commit(); sess.close(); }}2 元数据接口
可以从持久化类对象中获取其元数据信息,元数据中包含了映射文件中配置的信息和持久化类的属性等内容。
2.1 持久化类的元数据ClassMetadata
package com.weportal.hibernate; import org.apache.log4j.PropertyConfigurator; import org.hibernate.EntityMode; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.metadata.ClassMetadata; import com.weportal.computer.Computer; public class MetadataExample ... { public static void main(String[] args) ...{ PropertyConfigurator.configure("log4j.Properties"); Configuration cfg = new Configuration(); cfg.configure(); SessionFactory sf = cfg.buildSessionFactory(); Session sess = sf.openSession(); Computer pc = (Computer) sess.get(Computer.class,new Integer(16)); ClassMetadata pcMeta = sf.getClassMetadata(Computer.class); String[] names = pcMeta.getPropertyNames(); Object[] values = pcMeta.getPropertyValues(pc,EntityMode.POJO); for(int i=0;i<names.length;i++)...{ System.out.println("属性:"+names[i]+"="+values[i]); } sess.close(); }}程序的执行结果如下:
on load属性:cpu = intel 3.9 属性:mainboard = gigabyte属性:displaycard = geforce 4 属性:harddisk = WD120JB属性:display = LG属性:memory = kingMax1024MB属性:soundcard = creative属性:cdrom = null 属性:mouse = logitech属性:keyboard = logitech2.2 集合的元数据
是针对集合属性设计的元数据接口,通过这个接口,可以获得有关集合属性的信息。
3 编程接口汇总
SessionFactory、Session、Query、Criteria、ClassMetadata、CollectionMetadata、FlushMode、LockMode、ScrollMode、ReplicationMode、FetchMode
参考《精通Hibernate》 刘洋 著