struts2+hibernate3+spring2读书笔记12(操纵实体对象)
第13章 Hibernate操纵实体对象
本章导读语
在对数据库进行操作时,常见的操作除了查询外,还有添加、修改和删除记录。本章首先是进了hibernate对象的3种状态,即瞬时态(Transient)、持久态(persistent)、脱管态(Detached)。接关将讲述如何利用Hibernate提供的API来保存、更新和删除对象。另外还讲述了如何绕过Hibernate的API来进行操作。
一.解说Hibernate对象的三种状态
1.持久态
处于持久态的对象在数据库中具有对应的记录,并拥有一个持久化标识。若这两个条件都不满足,该对象将变成瞬时态的对象。当只满足第一个对件时,该对象将变成脱管态对象,持久态对象有两个特点:(1)是和session实例关联。(2)在数据库中有与之关联的记录。
2.瞬时态
由new开辟内存空间的java对象,如User user=new User (“hhr”,”男”,”26”),如果没有变量对该对象进行引用,它将被JVM(java虚拟机)回收。处于瞬间态的对象在内存中孤立存在,它是携带信息的载体,但是不和数据库的数据存在任何关联关系。
3.脱管态
当与某持久对象关联的session被关闭后,该持久对象转变成为脱管对象,脱管对象有如下特点:
(1)本质上与瞬时对象相同,在没有任何变量引用它时,JVM会在适当的时候将它收。
(2)比瞬时对象多了一个数据库记录标识值。
4.各种状态对象在Hibernate中的转换
(1)瞬时态—持久态的转换
瞬时态的对象可转为持久态的对象,具体方法是通过session的save()或saveOrUpdate()方法将瞬时对象与数据库关联,并将数据对应地插入数据库中,此时瞬时态变成持久态。
(2)持久态—瞬时态的转换
当对一个持久态的对象使用Hibernate的delete()访法时,将使得处于持久态的对象变成瞬时态。
(3)持久态—脱管态的转换
当一个处于持久态的对象执行session的close()或clear()、evict()之后,该对象将变成脱管态对象,此时该对象虽然具有数据识别值,但它已不在Hibernate持久层的管理之下。
(4)脱管态—持久态的转换
当脱管态的对象被重新关联上session时,将使得该对象转变成持久态的对象。脱管对象拥有数据库的识别值,可通过update()、saveOrUpdate()等方法转变成持久对象
(5)脱管态—瞬时态的转换
处于脱管对象执行session的delete()方法,可变成瞬时态的对象。
二.保存实体对象
在进行关系数据库的操作中,查询、保存、更新和删除记录者是很常用的操作,在Hibernate中,在Hibernate中提供这几个方法都是Session接口.
1.创建hibernate.cfg.xml文件
在src目录中建立Hibernate的配置文件hibernate.cfg.xml,该文件配置连接本地的MySQL,并加上映射文件User.hbm.xml该文件的内容如下:
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- 在后台打印sql语句 --> <property name="show_sql">true</property> <!-- 指定sql的本地方言,根据连接的数据库确定--> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 指定jdbc url,MySql的默认端口为3306,localhost为需要连接的主机,testhibernate为连接的数据库 --> <property name="connection.url">jdbc:mysql://localhost:3306/testhibernate</property> <!-- 数据库的用户名 --> <property name="connection.username">root</property> <!-- 数据库的密码 --> <property name="connection.password"></property> <!-- 设定数据库的驱动类,MySql的驱动jar包为mysql-connector-java-5.0.4-bin.jar,驱动类为com.mysql.jdbc.Driver --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <!--指定0到多个hbm.xml映射文件--> <mapping resource="amigo/hibernate/operate/User.hbm.xml" /> </session-factory> </hibernate-configuration>
package amigo.hibernate.operate; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.apache.log4j.*; /** * Hibernate的session获取类. * */ public class HibernateSessionFactory { public static Logger log=(Logger)Logger.getLogger(HibernateSessionFactory.class);private static String CONFIG_FILE_LOCATION="/hibernate.cfg.xml"; /**持有一个单态的Session实例.*/ private static final ThreadLocal threadLocal=new ThreadLocal(); /**持有一个单态的configuration实例.*/ private static final Configuration cfg=new Configuration(); private static SessionFactory sessionFactory; /** * 获得当前的Session实例 * */ public static Session currentSession() throws HibernateException{ Session session = (Session)threadLocal.get(); if(session==null||session.isOpen()==false){ if(sessionFactory==null){ try{ cfg.configure(CONFIG_FILE_LOCATION); sessionFactory=cfg.buildSessionFactory(); } catch(Exception e){ log.error(e); log.error("Error Creating SessionFactory%%%%"+session.isOpen()); } } session=sessionFactory.openSession(); threadLocal.set(session); } return session; } /**关闭session*/ public static void closeSession() throws HibernateException{ Session session=(Session) threadLocal.get(); threadLocal.set(null); if(session !=null){ session.close(); } } private HibernateSessionFactory(){ } } CREATE DATABASE `testhibernate`;USE `testhibernate`;#创建用户信息表CREATE TABLE `tbl_user` ( `loginName` varchar(50) NOT NULL COMMENT '用户登录名', `name` varchar(50) NOT NULL COMMENT '姓名', `password` varchar(50) NOT NULL COMMENT '登录密码', `createTime` datetime NOT NULL COMMENT '创建时间', PRIMARY KEY (`loginName`)) ENGINE=InnoDB DEFAULT CHARSET=gb2312 COMMENT='用户信息表
package amigo.hibernate.operate;import java.io.Serializable;/** * 用户信息pojo类 * */public class User implements Serializable {private static final long serialVersionUID=1L;/**登录名,主键*/private String loginName;/**姓名*/private java.lang.String name;/**密码*/private String password;/**创建时间*/private java.util.Date createTime;public String getLoginName() {return loginName;}public void setLoginName(String loginName) {this.loginName = loginName;}public java.lang.String getName() {return name;}public void setName(java.lang.String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public java.util.Date getCreateTime() {return createTime;}public void setCreateTime(java.util.Date createTime) {this.createTime = createTime;}}<?xml version="1.0" encoding='UTF-8'?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" > <hibernate-mapping package="amigo.hibernate.operate"><class name="User" table="tbl_user"><id name="loginName" column="loginName" type="java.lang.String"><generator column="name" type="java.lang.String" not-null="true"/><property name="password" column="password" type="java.lang.String" not-null="true"/><property name="createTime" column="createTime" type="java.util.Date" not-null="true"/></class></hibernate-mapping>
package amigo.hibernate.operate;import java.util.Date;import org.hibernate.Session;import org.hibernate.Transaction;/**测试利用Session接口的方法保存对象*/public class SaveTest {public static void main(String[] args)throws Exception{//瞬时态对象User user = new User();//设置对象的属性user.setLoginName("amigo");user.setName("阿密果");user.setPassword("198211");user.setCreateTime(new Date());//获得sessionSession session = HibernateSessionFactory.currentSession();//获得事务Transaction ts = session.beginTransaction();//调用Session接口save()访法保存对象//将对象从瞬时态变成持久态session.save(user);//在提交事务之前,数据并没有保存到数据库中//执行如下这句后,会将数据提交到数据库ts.commit();//执行完毕后,关闭sessionHibernateSessionFactory.closeSession();System.out.println("保存成功!");}}package amigo.hibernate.operate;import org.hibernate.Session;import org.hibernate.Transaction;/** * 测试利用Session接口方法更新对象 * */public class UpdateTest {public static void main(String[] args)throws Exception{//获得sessionSession session= HibernateSessionFactory.currentSession();//获得事务Transaction ts = session.beginTransaction();//获得持久化对象String loginname = "amigo";User user = (User)session.get(User.class, loginname);//更新对象的属性user.setName("hhr");user.setPassword("123456");session.update(user);ts.commit();HibernateSessionFactory.closeSession();System.out.println("更新成功!");}}package amigo.hibernate.operate;import java.util.Iterator;import org.hibernate.Query;import org.hibernate.Session;import org.hibernate.Transaction;/** * 批量更新对象 * */public class BatchUpdateTest {public static void main(String[] args)throws Exception{//获得sessionSession session = HibernateSessionFactory.currentSession();//获得事务Transaction ts = session.beginTransaction();//第3种方式批量更新数据//将所有loginname中包含amigo的记录的name都改为"阿密果"Query queryUpdate = session.createQuery("from User where loginname like ?");queryUpdate.setParameter(0, "%amigo%");//循环更新数据Iterator users = queryUpdate.list().iterator();int count=0;while(users.hasNext()){User user = (User)users.next();user.setName("阿密果");session.flush();session.evict(user);count++;}System.out.println("使用第3种方式批量更新记录条数为="+count);//第4种方式批量更新数据//将所有loginname中包含xiexx的记录的name都修改为"amigo"String hqlUpdate="update User set name=? where loginname like ?";Query query = session.createQuery(hqlUpdate);query.setParameter(0, "amigo");query.setParameter(1, "%xiexx%");int updateCount = query.executeUpdate();System.out.println("使用第4种方式批量更新记录条数为="+updateCount);ts.commit();HibernateSessionFactory.closeSession();}}package amigo.hibernate.operate;import org.hibernate.Query;import org.hibernate.Session;import org.hibernate.Transaction;/** * 测试利用Session的接口的方法来删除对象 * */public class DeleteTest {public static void main(String[] args)throws Exception{//获得session对象 Session session = HibernateSessionFactory.currentSession(); //获得事务 Transaction ts = session.beginTransaction(); //获得持久化对象 String loginname="amigo"; User user = (User)session.get(User.class,loginname); //删除单个对象 session.delete(user); System.out.println("删除成功!"); //删除所有loginname包含xiexx的记录 String hqlDelete ="delete User where loginname like ?"; Query query = session.createQuery(hqlDelete); query.setParameter(0, "%xiexx%"); int deletecount = query.executeUpdate(); System.out.println("批量删除记录条数为="+deletecount); ts.commit(); //执行完毕后,关闭session HibernateSessionFactory.closeSession(); }}package amigo.hibernate.operate;import java.sql.Connection;import java.sql.PreparedStatement;import org.hibernate.Session;import org.hibernate.Transaction;/** * 使用JDBC API进行数据操作 * */public class JdbcTest {public static void main(String[] args)throws Exception{//获得sessionSession session = HibernateSessionFactory.currentSession();//获得事务Transaction ts = session.beginTransaction();//通过Session的Connection()方法获得Connection对象//该方法已不推荐使用Connection con = session.connection();//添加数据String insertSql="insert into tbl_user(loginname,name,password,createTime)"+"value('amigoxx','amigoxx','123','2008-8-3')";PreparedStatement stmtInsert = con.prepareStatement(insertSql);stmtInsert.executeUpdate(insertSql);System.out.println("添加成功!");//修改数据//将所有longinname为amigo的数据的name字段改为:amigoString updateSql="update tbl_user set name='amigo' where loginname like '%amigo%'";PreparedStatement stmtUpdate=con.prepareStatement(updateSql);stmtUpdate.executeUpdate(updateSql);System.out.println("修改成功!");//删除数据//删除所有loginname为xiexx的数据String deleteSql="delete from tbl_user where loginname like '%xiexx%'";PreparedStatement stmtDelete = con.prepareStatement(deleteSql);stmtDelete.executeUpdate(deleteSql);System.out.println("删除成功!");//提交事务ts.commit();//执行完毕后,关闭sessionHibernateSessionFactory.closeSession();}}