标签:
---恢复内容开始---
一、hibernate如何转化jdbc代码实例【通过hibernate构建jdbc后往数据库传对象】
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
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.tool.hbm2ddl.SchemaExport;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.***.bean.User;
/**
 *通过hibernate构建jdbc后往数据库传对象
 * @author Victor
 *
 */
public class JdbcHibernate {
	private SessionFactory sf;
	private Session session;
	private Transaction tran;
	@Before
	public void before(){
		Configuration con=new Configuration().configure();
		sf=con.buildSessionFactory();
		session=sf.openSession();
		tran=session.beginTransaction();
	}
	@After
	public void after(){
		//把SQL语句刷到数据库,执行的是单纯的SQL语句
		//把对象刷到数据库中,调用对象的get方法
		//给?占位符赋值
		tran.commit();
		//关闭session【因为session不安全】
		//也会提交事务
		session.close();
	}
	@Test
	public void AutoCreateTable() {
		try {
			Configuration con=new Configuration().configure("/hibernate.cfg.xml");
			SchemaExport create=new SchemaExport(con);
			create.create(false, true);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	@Test//传单个对象【通过JDBC传对象】
	public void hibernate_jdbcInsertSingle(){
		//session.connection();
		try {//内部类实现
			session.doWork(new Work() {
				@Override
				public void execute(Connection conn) throws SQLException {
					// TODO Auto-generated method stub
					Statement sts=conn.createStatement();
					String sql="insert into s_user values(1,‘briup‘,1)";
					//写死的SQL语句只能插入一个对象
					sts.execute(sql);
				}
			});
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		
	}
	@Test//传多个对象【通过JDBC传对象】
	public void hibernate_jdbcInsertMany(){
		User u=new User();
		u.setId(1);
		u.setName("舒肤佳");
		u.setGender(true);
		JdBC_WorkImpl work=new JdBC_WorkImpl(u);
		session.doWork(work);
		User u1=new User();
		u1.setId(2);
		u1.setName("舒肤佳");
		u1.setGender(true);
		JdBC_WorkImpl work1=new JdBC_WorkImpl(u1);
		session.doWork(work1);
	}
	class JdBC_WorkImpl implements Work{
	private User user;
	public JdBC_WorkImpl(User user){
		this.user=user;
	}
	@Override
	public void execute(Connection conn) throws SQLException {
		// TODO Auto-generated method stub
		int a;
		if(user.getGender()==true){
			a=1;
		}else {
			a=0;
		}
		Statement sts=conn.createStatement();
		String sql="insert into s_user values("+user.getId()+",‘"+user.getName()+"‘,"+a+")";
		sts.execute(sql);
	}	
	}
}
二、操作hibernate二级缓存实例
import org.hibernate.CacheMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.***.bean.User;
/**
 * hibernate二级缓存操作
 * @author Victor
 *
 */
public class HibernateSessionFactory {
	private SessionFactory sf;
	private Session session;
	private Transaction tran;
	@Before
	public void before(){
		Configuration con=new Configuration().configure();
		sf=con.buildSessionFactory();
		session=sf.openSession();
		tran=session.beginTransaction();
	}
	@After
	public void after(){
		//把SQL语句刷到数据库,执行的是单纯的SQL语句
		//把对象刷到数据库中,调用对象的get方法
		//给?占位符赋值
		tran.commit();
		//关闭session【因为session不安全】
		//也会提交事务
		session.close();
	}
	@Test
	public void AutoCreateTable() {
		Configuration con=new Configuration().configure("/hibernate.cfg.xml");
		SchemaExport create=new SchemaExport(con);
		create.create(false, true);
	}
	@Test
	public void cache_sendSessionFactory(){
		try {
			User u=new User();
			u.setName("lisi");
			u.setGender(true);
			//save   把对象放到session缓存中,
			//同时调用insert语句
			session.save(u);
			//session.clear();
			//sf.evict(User.class);
			User s=(User) session.get(User.class, 1L);
			System.out.println(s);	
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	@Test
	public void cache_sendSessionFactory1(){
		User u=new User();
		u.setName("lisi");
		u.setGender(true);
		//save   把对象放到session缓存中,
		//同时调用insert语句
		session.save(u);
		//tran.commit();
		//sf.evict(User.class);
		//session.clear();
		//把只能读的内容放在二级缓存中去
		session.setCacheMode(CacheMode.GET);
		//把写的内容写到二级缓存中
		//session.setCacheMode(CacheMode.PUT);
		User s=(User) session.get(User.class, 1L);
		System.out.println(s);
	}
}
.cfg.xml配置文件:
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!-- 数据库的方言 -->
		<property name="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</property>
		<property name="hibernate.hbm2ddl.auto">create</property>
		<!-- 数据库的四要素 -->
		<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
		<property name="hibernate.connection.username">victor</property>
		<property name="hibernate.connection.password">victor</property>
		<property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:XE</property>
		<property name="current_session_context_class">thread</property>
		<property name="hibernate.cache.use_second_level_cache">true</property>
		<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
<class-cache usage="read-only" class="com/***/bean/User.hbm.xml"/>
		<property name="hibernate.show_sql">true</property>
		<property name="format SQL in log and console hibernate.format_sql">true</property>
		<mapping resource="com/***/subgroup/Animal.hbm.xml"/>
		<mapping resource="com/***/subgroup/Customer.hbm.xml"/>
		<mapping resource="com/***/bean/User.hbm.xml"/>
		<mapping resource="com/***/bean/Person.hbm.xml"/>
	</session-factory>
</hibernate-configuration>
三、openSession和getSession测试实例
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.After;
import org.junit.Before;
/**
 *getCurrentSession()获取测试实例
 *Session session=sf.openSession();和Session session1=sf.getCurrentSession();
 *开启的session和获取的session不是同一个session
 *因为在获取getCurrentSession()时会创建一个新的session
 *前提是配置#current_session_context_class thread
 * @author Victor
 *
 */
public class GetCurrentSessionTest {
	private SessionFactory sf;
	private Session session;
	private Transaction tran;
	@Before
	public void before(){
		Configuration con=new Configuration().configure();
		sf=con.buildSessionFactory();
		session=sf.openSession();
		tran=session.beginTransaction();
	}
	@After
	public void after(){
		//把SQL语句刷到数据库,执行的是单纯的SQL语句
		//把对象刷到数据库中,调用对象的get方法
		//给?占位符赋值
		tran.commit();
		//关闭session【因为session不安全】
		//也会提交事务
		session.close();
	}
	@org.junit.Test
	public void getCurrentSession(){
		//获取session 
		try {
			Session session1=sf.getCurrentSession();
			Session session2=sf.getCurrentSession();
			Session session3=sf.getCurrentSession();
			Session ss1=sf.openSession();
			Session ss2=sf.openSession();
			Session ss3=sf.openSession();
			System.out.println(session1==session2);
			System.out.println(session2==session3);
			System.out.println(session1==session3);
			System.out.println("---------------");
			System.out.println(ss1==ss2);
			System.out.println(ss2==ss3);
			System.out.println(ss1==ss3);
			System.out.println("+++++++++++++++");
			Session ss4=sf.openSession();
			Session s4=sf.getCurrentSession();
			System.out.println(ss4==s4);
			System.out.println(ss4.getClass());
			System.out.println(s4.getClass());
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
}
四、组件测试实
<一>
测试类:
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.***.subgroup.Address;
import com.***.subgroup.Customer;
/**封装组件测试实例component【属性封装】并获取对象信息
 * @author Victor
 *
 */
public class CustomerTest {
	private SessionFactory sf;
	private Session session;
	private Transaction tran;
	@Before
	public void before(){
		Configuration con=new Configuration().configure();
		sf=con.buildSessionFactory();
		session=sf.openSession();
		tran=session.beginTransaction();
	}
	@After
	public void after(){
		//把SQL语句刷到数据库,执行的是单纯的SQL语句
		//把对象刷到数据库中,调用对象的get方法
		//给?占位符赋值
		tran.commit();
		//关闭session【因为session不安全】
		//也会提交事务
		session.close();
	}
	@Test
	public void AutoCreateTable() {
		Configuration con=new Configuration().configure("/hibernate.cfg.xml");
		SchemaExport create=new SchemaExport(con);
		create.create(false, true);
	}
	@Test
	public void insert(){
		Customer customer=new Customer();
		Address  addr=new Address();
		customer.setName("sichuan");
		customer.setAddr(addr);
		addr.setCity("cc");
		addr.setProvince("vv");
		addr.setStreet("bb");
		session.save(customer);
		//Customer c=(Customer) session.get(Customer.class, 1L);
		Customer c=(Customer) session.load(Customer.class, 1L);
		System.out.println(c);
		/*String hql="from Customer";
		Query query=session.createQuery(hql);
		List<Customer> list=query.list();
		for(Customer c1:list){
			System.out.println(c1);
		}*/
	}
}
实体类
package com.***.subgroup;
public class Customer {
	private long id;
	private String name;
	private Address addr;
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Address getAddr() {
		return addr;
	}
	public void setAddr(Address addr) {
		this.addr = addr;
	}
	@Override
	public String toString() {
		//return "Customer [id=" + id + ": name=" + name + ": addr=" + addr + "]";
		return id+"--"+name+"--"+addr.getCity()+"--"+addr.getProvince()+"--"+addr.getStreet();
	}
}
封装类:
package com.***.subgroup;
public class Address {
	private String province;
	private String city;
	private String street;
	public String getProvince() {
		return province;
	}
	public void setProvince(String province) {
		this.province = province;
	}
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	public String getStreet() {
		return street;
	}
	public void setStreet(String street) {
		this.street = street;
	}
}
.hbm.xml配置文件:
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="com.***.subgroup.Customer" table="s_customer">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name"/>
		<component name="addr" class="com.***.subgroup.Address">
			<property name="province"/>
			<property name="city"/>
			<property name="street"/>
		</component>
	</class>
</hibernate-mapping>
<二>
测试类:
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.briup.subgroup.Dog;
import com.briup.subgroup.Pig;
/**
 * 继承组件测试实例【子类继承父类】subclass
 * @author Victor
 *
 */
public class AnimalTest {
	private SessionFactory sf;
	private Session session;
	private Transaction tran;
	@Before
	public void before(){
		Configuration con=new Configuration().configure();
		sf=con.buildSessionFactory();
		session=sf.openSession();
		tran=session.beginTransaction();
	}
	@After
	public void after(){
		//把SQL语句刷到数据库,执行的是单纯的SQL语句
		//把对象刷到数据库中,调用对象的get方法
		//给?占位符赋值
		tran.commit();
		//关闭session【因为session不安全】
		//也会提交事务
		session.close();
	}
	@Test
	public void AutoCreateTable() {
		Configuration con=new Configuration().configure("/hibernate.cfg.xml");
		SchemaExport create=new SchemaExport(con);
		create.create(false, true);
	}
	@Test
	public void insert(){
		try {
			Dog dog=new Dog();
			dog.setName("dog");
			dog.setHeight(14);
			Pig p=new Pig();
			p.setName("pig");
			p.setWeight(180.5);
			session.save(dog);
			session.save(p);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
}
实体类【父类】:
package com.***.subgroup;
public class Animal {
	private long id;
	private String name;
	private long gender;
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public long getGender() {
		return gender;
	}
	public void setGender(long gender) {
		this.gender = gender;
	}
}
实体类【子类一】:
package com.***.subgroup;
public class Pig extends Animal{
	private Double weight;
	public Double getWeight() {
		return weight;
	}
	public void setWeight(Double weight) {
		this.weight = weight;
	}
}
实体类【子类二】:
package com.***.subgroup;
public class Dog extends Animal{
	private double height;
	public double getHeight() {
		return height;
	}
	public void setHeight(double height) {
		this.height = height;
	}
}
.hbm.xml配置文件:
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="com.***.subgroup.Animal" table="s_animal">
		<id name="id">
			<generator class="native"/>
		</id>
		<discriminator column="type" type="string"/>
		<property name="name"/>
		<property name="gender"/>
		<subclass name="com.***.subgroup.Dog" discriminator-value="D">
			<property name="height" column="height"/>
		</subclass>
		<subclass name="com.***.subgroup.Pig" discriminator-value="P">
			<property name="weight" column="weight"/>
		</subclass>
	</class>
</hibernate-mapping>
总结:
hibernate一级缓存
一级缓存很短和session的生命周期一致,
一级缓存也叫
session级的缓存或事务级缓存
哪些方法支持一级缓存:
	* get()
	* load()
如何管理一级缓存:
	* session.clear(),session.evict()
如何避免一次性大量的实体数据入库导致内存溢出
	* 先flush,再clear
如果数据量特别大,考虑采用jdbc实现,如果jdbc也不能满足
要求可以考虑采用数据本身的特定导入工具
hibernate二级缓存
二级缓存也称进程级的缓存或SessionFactory级的缓
存,
二级缓存可以被所有的session共享
二级缓存的生命周期和SessionFactory的生命周期
一致
,SessionFactory可以管理二级缓存
二级缓存的配置和使用:
	* 将echcache.xml文件拷贝到src下
	* 开启二级缓存,修改hibernate.cfg.xml文件
		<property name="hibernate.cache.use_second_level_cache">true</property>
	* 指定缓存产品提供商,修改hibernate.cfg.xml文件
		<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
	* 指定那些实体类使用二级缓存(两种方法)
		* 在映射文件中采用<cache>标签
		* 在hibernate.cfg.xml文件中,采用<class-cache>标签
		
二级缓存是缓存实体对象的
了解一级缓存和二级缓存的交互	
hibernate如何转化jdbc代码;				 
					
id的增长策略
gengerate表示id的自动生成器,class表示id的生成策略(以什么方式生成id)
1.assigned手动设置,也是默认的设置,
主键由外部程序负责生成,无需Hibernate参与。----如果要由程序
代码来指定主键,就采有这种
<id name="id" column="id" type="string">
    <generator class="assigned" />
</id>
2.increment id自动增长,每次在最大的基础之上自动加一
对 long , short 或 int 的数据列生成自动增长主键。
  increment主键生成方式的特点是与底层数据库无关性,
大部分数据库如 Mysql,MSSQL 和ORACLE等都支持
increament生成方式。
此方式的实现机制为在当前应用实例中维持一个变量,
以保存着当前的最
大值,之后每次需要生成主键的 时候将此值加1作为主键。
increment方式
的不足之处是当多个线程并发对数据库表进行写操作时
,可能出现相同的
主键值,发生主键重复的冲突,因此多线程并发操作时,
不应该使用此方法。
<id name="id" column="id">
    <generator class="increment" />
</id>
3.sequence 默认使用sequence的序列生成id值,默认使用Hibernate_sequence的
	3.1我们可以指定序列
在ORACLE等数据库中使用sequence生成主键。sequence的特点是
于数据库的相关性,
seqhio要求底层能支持sequence,列如Oracle。
数据库中的语法如下:
Oracle:create sequence seq_name increment by 1 start with 1;
需要主键值时可以调用seq_name.nextval或者seq_name.curval得到,数据库会帮助我们维护这个sequence序列,保证每次取到的值唯一,如:
insert into tbl_name(id, name) values(seq_name.nextval, ‘terry ren’);
<id name="id" column="id" type="long">
    <generator class="sequence">
       <param name="sequence">seq_name</param>
   </generator>
</id>
4.identity自动增长策略,
如果数据列的类型是 long, short 或 int ,可使用主键生成器生
成自动增长Hibernate主键。与底层数据库有关,
要求数据库支持identify,如MySQL中是auto_increment,SQL Server
中是Identify.支持的数据库
有MySQL,SQL Server,DB2,Sybase和HypersonicSQL.(
好像不支持oracle) 无需Hibernate和用户的干涉,
使用较为方便,但不便于在不同的数据库之间移植程序。
identity的优点是不会发生 increment方式的并发错做问题。
数据库涉及到的表要设置自动增长。
<id name="id" column="id" type="long">
    <generator class="identity" />
</id>
5.native根据本地数据库类型自己选择认为合适一种类型,默认悬着sequence则略
由Hibernate根据不同的数据库方言,
自行判断采用identity、hilo、sequence其中一种作为
Hibernate主键生成方式,native的 优点是与底层性无关,
便于不同数据库之间的移植,由Hibernate根据不同数据库选
择主键的生成方式。在oracle中需要创建叫
Hibernate_sequence名字的sequence,
如果设置了Hibernate.hbm2ddl.auto属性,
不需要手动建立序列,前提 
是数据库帐号必须有Create Sequence这种高级权限。
mysql等数据库则不用建立sequence。
<id name="id" column="id">
    <generator class="native" />
</id>
6.hilo  id值通过高低位运算得到,
	1.在数据库中,要有一张表来维护高位的值
	2在数据库中地位我们需要指点一个范围循环,1-5
	一般会从0或1到指定值循环,这要看数据库
	id=hi*(max_lo+1)+lo lo值在0或1到最大max_lo之间循环,
	lo每循环一圈,hi值加1
获得链接或用户自定义提供的链接中,不要使用这种生成器。
hilo方式需要维护表信息,
因此对数据的影响的要率会造成一定影响。
create table hi_value(next_hi number not null);
insert into hi_value(next_hi) values(1);
commit;
<id name="id" column="id">
    <generator class="hilo">
       <param name="table">hi_value</param>
       <param name="column">next_hi</param>
       <param name="max_lo">100</param>
   </generator>
</id>
	
7.seqhilo 和上面不同的是,从序列中拿到一个高为的值
与hilo 类似,通过hi/lo 算法实现的主键生成机制,
只是主键历史状态保存在Sequence中,
适用于支持Sequence的数据库,
如Oracle。如果数据列的类型是 long, short 或 int可使用
该主键生成器。
<id name="id" column="id">
   <generator class="seqhilo">
      <param name="sequence">seq_name</param>
      <param name="max_lo">100</param>
   </generator>
</id>
8.uuid 
9.guid
注意:如果想要使用uuid或guid就要把id改为String类型
hibernate对象的状态
1.瞬时态/自由态,Transient
由new操作符创建(刚刚new出来的对象,在session缓存中还不存在),且尚未与hibernate session关联的对象
这种状态的对象也称为临时对象。
特点:不处于session的缓存中,即不被任何一个session实例关联,在数据库中没有记录关联
2、持久态,
对象已经被持久化,加入到session的缓存中,处于持久化状态的java对象被称为持久化对象
特点:处于一个session对象的缓存中,持久化对象在数据库中有对应的记录
session在清理缓存时(flush),会根据持久化对象的属性的变化来同步更新数据库;
3.脱管态/游离态Detached
对象已经被持久化,但不处于session的缓存中,处于
托管状态的java对象称为游离对象。
特点:不在位于session缓存中,机不被session关联
游离对象是由持久化对象转变过来的,因此存在数据库有相应的记录
和其对应
瞬时态对象和游离对象的比较
相同点:session缓存中没有这些对象,hiberntae不会保证
他们的属性变化与数据库保持同步。
不同点:前者在数据库中没有与之对应的记录,后者
由持久化对象转变而来,因此数据库中可能还存在与之对应的记录
注意:
hibernate只会保证持久态的对象属性的变化和数据库同步
,因此持久态对象在session的缓存中存在;
总结:hibernate只能管理做了映射的类的对象,对于一个
实体类的对象
1.session缓存中有没有这个对象
2.数据库中有没有这个对象对应的记录
注意:用主键的值来判断这两个问题十分成立,然后在根据这两个问题的结果来判断对象的状态
怎么判断一个对象在session的缓存中有没有,
看这个对象的主键值和session的缓存中对象的主键值有
没有相同的的,如果有说明这个对象在session的缓存中存在
怎么判断一个对象在数据库中有没有对应的记录,
看这个对象的主键值和数据库表中数据的主键值有没有相同的,如果有,则说明这个数据在数据库中有对应的记录
组件映射:继承和封装
---恢复内容结束---
标签:
原文地址:http://www.cnblogs.com/victor963/p/4808959.html