以在实验室的电脑为例,新建一个Dynamic web项目,通过myeclipse智能功能来包装该项目,可以使其项目自动生成为一个Hibernate项目,使用的是test数据库下的user1数据库。
先建立一个User.cfg.xml文件。配置文件内容如下
:<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/test
</property>
<property name="connection.username">root</property>
<property name="connection.password">wdl03707552882</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!-- 设置hibernate的事务隔离级别 -->
<property name="connection.isolation">2</property>
<property name="myeclipse.connection.profile">db_10</property>
<!-- 删除对象后使其oid为null -->
<property name="use_identifier_rollback">true</property>
<!--配置文件所放在的包路径下,把.换成/-->
<mapping resource="com/test/User.hbm.xml" />
</session-factory>
</hibernate-configuration>
然后建立一个User持久化类,实现getter和setter方法。
package com.test;
public class User{
private Integer id;
private String username;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password="
+ password + "]";
}
public void setUsername(String username) {
this.username = username;
}
public User() {
super();
// TODO Auto-generated constructor stub
}
public User( String username, String password) {
super();
this.username = username;
this.password = password;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
建立映射文件:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.test.User" table="users1" catalog="test" >
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="identity" />
</id>
<property name="username" type="java.lang.String">
<column name="username" length="30" not-null="true" />
</property>
<property name="password" type="java.lang.String">
<column name="password" length="30" not-null="true" />
</property>
</class>
</hibernate-mapping>
前提是建立一个数据库,id(Integer) ,username(String) ,password (password)
属性和持久化类的字段对应
建立一个Junit类,实现各种方法
package com.test;
import java.sql.Connection;
import java.sql.SQLException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.jdbc.Work;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class TestSession {
Configuration con;
SessionFactory sessionfactory;
Transaction ts;
Session session;
@Before
public void before(){
con=new Configuration().configure();
ServiceRegistry serivice=(ServiceRegistry) new ServiceRegistryBuilder().applySettings(con.getProperties()).buildServiceRegistry();
sessionfactory=con.buildSessionFactory(serivice);
session=sessionfactory.openSession();
ts=session.beginTransaction();
}
@Test
public void testSession(){
User u=(User) session.get(User.class, 3);
System.out.println(u);
/*System.out.println(u);
User u2=(User) session.get(User.class, 3);
System.out.println(u2);*/
u.setUsername("河南郑州");
}
@After
public void after(){
/*Flush缓存:session按照缓存 中对象的属性变化来同步更新 数据库
* 默认情况下Session在以下时间点刷新:
* --显试调用Session 的flush()方法
* --当应用程序调用Transaction的commit()方法时,该方法先flush然后再向数据库提交事务。
* 当应用程序执行一些查询(HQL Criteria)操作时,如果缓存中持久化对象的属性已经发生变化,会先flush缓存。以保证查询结果能够反映持久化
* 对象的最新状态
* flush缓存的例外情况:如果对象使用native生成器生成oid那么当调用Session的save方法保存对象时,会立即执行向数据库插入该实体的insert语句
* commit()和flush()方法的区别:flush执行一系列sql语句,但不是提交事务,commit方法先调用fluseh方法。然后提交事务。一位置提交事务意味着对数据库操作永久保存下来
*
*
*
* refresh会强制发送select语句。以使session缓存对象的状态和数据库中的对象保持一致
*
*
* clear()清理缓存
* */
ts.commit();
session.close();
sessionfactory.close();
}
@Test
public void testclear(){
User u=(User) session.get(User.class, 1);
System.out.println(u);
session.clear();
User u2=(User) session.get(User.class, 1);
/*再不使用clear方法的情况下只打印一次sql语句
* 如果使用了clear则会打印两次,因为将session中的缓存清除掉了
* */
}
@Test
/*1.save()方法
* 1)使一个临时对象变为持久化对象
* 2)为对象分配一个id。不执行save。该对象为临时对象,没有id
* 3)在flush缓存时,会发送一条insert语句。
* 4)在save方法之前的id是无效的
* 5)持久化对象的id是不能修改的,因此在执行save方法之后不能操作该对象
* Session的save方法使一个临时对象变为一个持久化对象,Session的save方法完成以下操作。
* 1)把User对象加入到Session缓存中。使它进入到持久化状态。
* 2)选用映射文件指定的标识符生成器,为持久化对象分配一个唯一的id。
*在使用代理主键的情况下。setId()方法为User对象的设置OID是无效的。
*
*
* */
public void testSave(){
User u=new User();
u.setUsername("ccc");
u.setPassword("ccccc");
u.setId(100);
System.out.println(u);
session.save(u);
System.out.println(u);
}
@Test
public void testPersist(){
/*也会执行insert操作
* 和save方法有什么区别嘛
* 在調用persist方法之前若有id了則不會執行insert方法,并且会抛出异常,
*
* */
User u=new User();
u.setUsername("DED");
u.setPassword("eee");
u.setId(200);
session.persist(u);
}
@Test
public void testGet(){
User u=(User) session.get(User.class, 1);
// session.close();
System.out.println(u);
//System.out.println(u.getClass().getName()); com.test.User
/*hibernate中的get和load方法的区别
* 1.执行get方法:会立即加载对象,
* 而执行load方法若不适用对象,则不会立即执行查询操作。而返回一个代理对象
* get是立即检索,load是延迟检索。
*
* 2.如果在打印获取的对象之前调用了session.close()
* load可能会抛出懒加载异常。org.hibernate.LazyInitializationException:
* 因为代理对象之前已经关闭了session
*
*
* 3.若数据表中没有对应记录,且session也没有被关闭(session.close()),同时需要使用对象时:get返回null 而load则抛出异常。
* load若不适用任何属性,则没问题不抛出异常,若需要初始化了。则抛出异常。
*
* */
}
@Test
public void testLoad(){
User u=(User) session.load(User.class, 10);
System.out.println(u.getClass().getName()); // com.test.User_$$_javassist_0
// session.close();
// System.out.println(u);
}
/*update
* 1.若更新一个持久化对象不需要显试的调用update方法。因为在调用transaction的commit方法时,会先执行sesion的flush方法
* 2.更新一个游离对象,需要显试调用update方法,可以把一个游离对象变为一个持久化对象
*
*
* 需要注意的是:
*无论要更新的游离对象和数据表的记录是否一致都会发送update语句
*
*如何能让update方法不再盲目出发update语句。
* 在.hbm.xml文件的class节点设置select-before-update=true
*但通常不需要设置该属性。
*3.若数据表中没有对应的记录,但还是调用了update方法,会抛出异常,
*
*4.当update方法关联一个游离对象时,如果session的缓存中已经存在相同的oid的持久化对象
*因为在Session缓存中不能有两个相同的oid对象。此时会抛出一场错误NonUniqueObjectException异常
*
* */
@Test
public void testupdate(){
User u=(User)session.get(User.class, 1);
ts.commit();
session.close();
session=sessionfactory.openSession();
ts=session.beginTransaction();
// u.setPassword("sun");
User u1=(User) session.get(User.class,1);
session.update(u);
System.out.println(u);
}
/*Session的saveOrUpdate方法
* Session的saveOrUpdate()方法同时包含了save方法和update方法。
* 判定执行这个方法时候具体执行其中的哪个方法的标准
* 当一个对象为游离对象的时候,执行update方法。当一个对象是临时对象时候,执行save方法。
*
*
* 1)java对象的oid属性为null
* 2)映射文件中<id>设置了unsave-value属性值,并且java对象的oid取值与这个unsave-value属性值匹配。
* 注意:1)若oid不为空,但数据表中还没有对应的记录,会抛出一个异常。
* 2)了解oid值等于id的unsave-value属性对象,也可以认为是一个游离对象
*
* */
@Test
public void saveorupdate(){
User u=new User("struts","hibernate");//
u.setId(1);
session.saveOrUpdate(u);//如果没有u.setId()方法此时的u对象是临时对象(为空)/此时执行save方法,但是由于其设置其id为1.在数据库中存在,因此属于游离对象。
}
/*delete()方法
* delete:执行删除操作,只要oid和数据表中的一条记录对应,就会准备执行delete操作。若oid没有对应的操作,则抛出异常
可以通过设置hibernate配置的属性hibernate.use_identifier_rollback为true使其删除后把其oid设置为null
*
* */
@Test
public void delete(){
// User u=new User();
// u.setId(1);
User u=(User) session.get(User.class, 3);
session.delete(u);
System.out.println(u);
}
/*evict:从session缓存中把制定的持久化对象移除
* 移除后,原先改变的内容将不会提交给数据库记录中
*
* */
@Test
public void evice(){
User u=(User) session.get(User.class, 4);
User u1=(User) session.get(User.class, 5);
u.setUsername("111111111");
u1.setUsername("222222222");
session.evict(u1);
}
@Test
public void testdoWordk(){
session.doWork(new Work(){
@Override
public void execute(Connection arg0) throws SQLException {
// TODO Auto-generated method stub
//获取原生的connection对象
System.out.println(arg0);
}
});
}
}