javaee之hibernate的缓存与注解

hibernate的注解:
在项目中,除了有xml的映射配置文件外,还可以在实体类中采用注解的方式来生成映射。

在比较大的项目,通常都是采用xml的映射配置文件,主要是因为在大项目中比较好维护;在小项目中,主要是要求是开发的速率快,大多数就是采用注解的方式来开发


常用的注解:
@Entity:声明一个类是一个映射类  类似:<class name="..." />
@Table : 声明一个类映射到的表名  类似:<class table="..." />
@Id    : 声明一个类的主键 类似:<id name=".." />
@Column :声明一个类映射表的字段  类似:<property column=".." />
@JoinColumn:用来设置外键 类似:<key column=".." />
@JoinTable :设置中间表   类似:<set table=".." />
@OneToMany :一对多的映射关系
@ManyToMany:多对多的映射关系
@OneToOne  :一对一的映射关系


一对多:
User:

import java.util.HashSet;
import java.util.Set;


import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;


import org.hibernate.engine.internal.Cascade;


@Entity
@Table(name="t_user")
public class User {


	//主键
	@Id
	@GeneratedValue //设置id的主键生成策略,generator的属性表示生成策略的类型
	@Column(name="id")	//生成的字段列,不写name,默认为属性名
	private int id;
	@Column(name="name")
	private String name;
	
	//一对多的关系
	/**
	 * cascade:表示设置级联操作
	 * mappedBy:表示设置的是维护关联关系,参数值为多方的属性值
	 */
	@OneToMany(mappedBy="user",cascade={CascadeType.ALL})
	//@JoinColumn(name="uid")	//当设置了mappedBy的时候,就不能使用JoinColumn或者JoinTable注解
	private Set<Address> addresses = new HashSet<Address>();
	
	public Set<Address> getAddresses() {
		return addresses;
	}
	public void setAddresses(Set<Address> addresses) {
		this.addresses = addresses;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	
}




Address:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;


@Entity
@Table(name="t_address")
public class Address {


	@Id
	@GeneratedValue
	@Column(name="id")
	private int id;
	@Column(name="name")
	private String name;
	@Column(name="phone")
	private String phone;
	@Column(name="addre")
	private String addre;
	
	//表示的多对一
	@ManyToOne
	@JoinColumn(name="uid")
	private User user ;


	public int getId() {
		return id;
	}


	public void setId(int id) {
		this.id = id;
	}


	public String getName() {
		return name;
	}


	public void setName(String name) {
		this.name = name;
	}


	public String getPhone() {
		return phone;
	}


	public void setPhone(String phone) {
		this.phone = phone;
	}


	public String getAddre() {
		return addre;
	}


	public void setAddre(String addre) {
		this.addre = addre;
	}


	public User getUser() {
		return user;
	}


	public void setUser(User user) {
		this.user = user;
	}
	
	
}



多对多:
Course:

import java.util.HashSet;


import java.util.Set;


import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;


/**
 * @author Mao
 *
 */
@Entity
@Table(name="t_course")
public class Course {


	@Id
	@GeneratedValue
	@Column(name="id")
	private int id;
	@Column(name="name")
	private String name;
	
	
	@ManyToMany(mappedBy="course")
	private Set<Student> student = new HashSet<Student>();




	public int getId() {
		return id;
	}




	public void setId(int id) {
		this.id = id;
	}




	public String getName() {
		return name;
	}




	public void setName(String name) {
		this.name = name;
	}




	public Set<Student> getStudent() {
		return student;
	}




	public void setStudent(Set<Student> student) {
		this.student = student;
	}
	
	
	
}




Student:

import java.util.HashSet;
import java.util.Set;


import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;


@Entity
@Table(name="t_student")
public class Student {


	@Id
	@GeneratedValue
	@Column(name="id")
	private int id;
	@Column(name="name")
	private String name;
	
	//表示多对多关系
	@ManyToMany(cascade={CascadeType.ALL})
	//设置中间表
	@JoinTable(name="student_course",joinColumns=@JoinColumn(name="sid"),inverseJoinColumns=@JoinColumn(name="cid"))
	private Set<Course> course = new HashSet<Course>();


	public int getId() {
		return id;
	}


	public void setId(int id) {
		this.id = id;
	}


	public String getName() {
		return name;
	}


	public void setName(String name) {
		this.name = name;
	}


	public Set<Course> getCourse() {
		return course;
	}


	public void setCourse(Set<Course> course) {
		this.course = course;
	}
	
	
}


一对一:
Person:
	
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;


@Entity
@Table(name="t_person")
public class Person {


	@Id
	@GeneratedValue
	@Column(name="id")
	private int id;
	@Column(name="name")
	private String name;
	
	@OneToOne(mappedBy="person",cascade={CascadeType.ALL})
	private IdCard idcard;


	public int getId() {
		return id;
	}


	public void setId(int id) {
		this.id = id;
	}


	public String getName() {
		return name;
	}


	public void setName(String name) {
		this.name = name;
	}


	public IdCard getIdcard() {
		return idcard;
	}


	public void setIdcard(IdCard idcard) {
		this.idcard = idcard;
	}
	
	
}



IdCard:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;


@Entity
@Table(name="t_idcard")
public class IdCard {


	@Id
	@GeneratedValue
	@Column(name="id")
	private int id;
	@Column(name="cardno")
	private String cardno;
	
	@OneToOne
	@JoinColumn(name="pid",unique=true)
	private Person person;


	public int getId() {
		return id;
	}


	public void setId(int id) {
		this.id = id;
	}


	public String getCardno() {
		return cardno;
	}


	public void setCardno(String cardno) {
		this.cardno = cardno;
	}


	public Person getPerson() {
		return person;
	}


	public void setPerson(Person person) {
		this.person = person;
	}
	
	
}




测试类:

import org.hibernate.Session;


import org.hibernate.Transaction;
import org.junit.Test;


import util.HibernateUtils;


public class text {


	@Test
	public void test01(){
		Session session = HibernateUtils.getSession();
		Transaction tx = session.getTransaction();
		tx.begin();


		User u = new User();
		u.setName("狗剩");


		Address a1 = new Address();
		a1.setName("狗剩的老婆");
		a1.setAddre("广州天河");


		Address a2 = new Address();
		a2.setName("狗剩的妈妈");
		a2.setAddre("广州番禺");


		u.getAddresses().add(a1);
		u.getAddresses().add(a2);
		a1.setUser(u);
		a2.setUser(u);


		session.save(u);


		tx.commit();
		HibernateUtils.close(session);
	}
	
	@Test
	public void test02(){
		Session session = HibernateUtils.getSession();
		Transaction tx = session.getTransaction();
		tx.begin();


		Student s1 = new Student();
		s1.setName("张三");
		
		Student s2 = new Student();
		s2.setName("李四");


		
		Course c1 = new Course();
		c1.setName("jsp开发");
		
		Course c2 = new Course();
		c2.setName("struts2框架");
		
		
		s1.getCourse().add(c1);
		s1.getCourse().add(c2);
		c1.getStudent().add(s1);
		c2.getStudent().add(s1);
		
		s2.getCourse().add(c1);
		c1.getStudent().add(s2);
		
		session.save(s1);
		session.save(s2);
		
		tx.commit();
		HibernateUtils.close(session);
	}
	
	@Test
	public void test03(){
		Session session = HibernateUtils.getSession();
		Transaction tx = session.getTransaction();
		tx.begin();


		Person p = new Person();
		p.setName("张三");
		
		IdCard ic = new IdCard();
		ic.setCardno("4422223333");
		
		p.setIdcard(ic);
		ic.setPerson(p);
		
		session.save(p);
		
		tx.commit();
		HibernateUtils.close(session);
	}
}



hibernate的懒加载:
当要查询数据的时候,hibernate会先去一级缓存和二级缓存中查询,如果没有查询到数据的时候,这个时候才会去数据库查询。
采用懒加载的机制后,查询到的数据不会一次性全部查询到,而是到了需要用到的数据才会去查询该数据


Address:

public class Address {


	private int id;
	private String name;
	private String phone;
	private String address;
	
	private User user;


	public int getId() {
		return id;
	}


	public void setId(int id) {
		this.id = id;
	}


	public String getName() {
		return name;
	}


	public void setName(String name) {
		this.name = name;
	}


	public String getPhone() {
		return phone;
	}


	public void setPhone(String phone) {
		this.phone = phone;
	}


	public String getAddress() {
		return address;
	}


	public void setAddress(String address) {
		this.address = address;
	}


	public User getUser() {
		return user;
	}


	public void setUser(User user) {
		this.user = user;
	}
	
	
}



User:

import java.util.HashSet;
import java.util.Set;


public class User {


	private int id;
	private String name;
	
	private Set<Address> addresses = new HashSet<Address>();


	public int getId() {
		return id;
	}


	public void setId(int id) {
		this.id = id;
	}


	public String getName() {
		return name;
	}


	public void setName(String name) {
		this.name = name;
	}


	public Set<Address> getAddresses() {
		return addresses;
	}


	public void setAddresses(Set<Address> addresses) {
		this.addresses = addresses;
	}
	
	
	
}




Address.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="demo3_lazy">
	
	<class name="Address" table="add" lazy="false">
		
		<id name="id">
        	<generator class="native"></generator>
		</id>
		<property name="name" type="string" column="name"/>
		<property name="phone"></property>
		<property name="address"></property>
		
		<many-to-one name="user"  class="demo3_lazy.User" column="uid" />
		
	</class>
	
</hibernate-mapping>



User.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="demo3_lazy">
	
	<class name="User" table="users">
		
		<id name="id">
        	<generator class="native"></generator>
		</id>
		<property name="name" type="string" column="name"/>
		
		<set name="addresses" lazy="false">
			<key column="uid"></key>
			<one-to-many class="demo3_lazy.Address"/>
		</set>
		
	</class>
	
</hibernate-mapping>



测试类:

/**
 * 
//延迟加载
/**
 * 1) 类的延迟加载
 *      get(): 不支持类的延迟加载
 *      load(): 支持类的延迟加载
 *      
 *  2) 类的关联关系延迟加载
 *      lazy="false"
 * @author APPle
 */
public class App {


	@Test
	public void test01(){
		Session session = HibernateUtils.getSession();
		Transaction tx = session.beginTransaction();
		
		/**
		 * 一个对象的延迟加载:get和load方法区别
		 * get方法都是立即加载的,没有延迟加载的效果
		 * load方法是支持延迟加载的
		 * 
		 * 2、当在映射文件中设置lazy为false,则表示不懒加载,默认为true
		 */
		User u = (User)session.load(User.class, 1); //现在查询到只是User的对象地址,不包含其他属性
		System.out.println(u.getName());	//这个时候需要得到user的name,所有才继续去查询,但是这是只有name这个属性,没有其他属性
		
		
		System.out.println(u.getAddresses());  //这个时候又再去查询user的address属性
		
		
		User u1 = (User)session.get(User.class, 1);//现在查询到User对象,包括User里面的全部属性
		System.out.println(u.getName());	//这个时候可以直接取到来使用
		System.out.println(u.getAddresses());
		 
		tx.commit();
		HibernateUtils.close(session);
	}



hibernate的缓存:
1、关于hibernate的缓存机制,是为了提供hibernate框架运行的性能,尽量减少和数据库的连接次数。其中包括hibernate的一级缓存、hibernate的二级缓存


hibernate一级缓存:
为Session级别的缓存,是属于事务缓存,所有缓存数据都放在session对象,当session关闭的时候就会丢失缓存数据


Student:

public class Student {


	private int id;
	private String name;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	
}



Student.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="demo2_session">
	
	<class name="Student" table="stu">
		
		<id name="id">
        	<generator class="native"></generator>
		</id>
		<property name="name" type="string" column="name"/>
		
	</class>
	
</hibernate-mapping>




测试类:

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;


import util.HibernateUtils;


public class App {


	//演示一级缓存
	@Test
	public void test01(){
		Session session = HibernateUtils.getSession();
		Transaction tx = session.beginTransaction();
		
		//第一次查询过的数据会放在一级缓存中,并且使用id来标记
		Student s1 =(Student) session.get(Student.class, 1);


		Student s2 =(Student) session.get(Student.class, 1);
		System.out.println(s1=s2);  //true
		
		tx.commit();
		HibernateUtils.close(session);
	}
	
	//修改也是走一级缓存
	@Test
	public void test02(){
		Session session = HibernateUtils.getSession();
		Transaction tx = session.beginTransaction();
		
		/*Student s = (Student)session.get(Student.class, 1); // s对已经放到了一级缓存
		//修改
		s.setName("李四");//修改一级缓存中的数据
		*/		
		/*int i =1;
		for(Student s: list){
			if(i%1000==0){
				//同步数据
				session.flush();
				//清空一级缓存的数据
				session.clear();
			}
			session.save(s);
		}*/
		
		Student s1 = (Student)session.get(Student.class, 1); 
		Student s2 = (Student)session.get(Student.class, 1);
		session.evict(s1);
		//session.clear();
		
		Student s3 = (Student)session.get(Student.class, 1); 
		
		tx.commit();  //commit()方法在提交事务之前,会调用session.flush()方法来同步一级缓存和数据库的数据
		HibernateUtils.close(session);
	}
	
	//演示hibernate不同对象状态的转换
	@Test
	public void test03(){
		Session session = HibernateUtils.getSession();
		Transaction tx = session.beginTransaction();
		
		Student s = new Student(); //s是处于临时状态
		s.setName("xx"); //不会对数据库进行任何的操作
		
		session.save(s); //s是处于持久化状态
		
		session.evict(s); //s是处于游离态
		
		session.delete(s); //s是处于删除态
		
		tx.commit(); 
		HibernateUtils.close(session);
}
}


hibernate二级缓存:
为SessionFactory级别的缓存,是属于进程缓存,所有缓存数据都放在SessionFactory,所有二级缓存的数据不会随着session对象的关闭而丢失



测试类:


//演示二级缓存,同时需要在cfg.xml中进行配置
		@Test
		public void test2(){
		
			Session session1 = HibernateUtils.getSession();
			Transaction tx = session1.getTransaction();
			tx.begin();
			
			Address a1 = (Address)session1.get(Address.class, 1);
			tx.commit();
			
			HibernateUtils.close(session1);
			
			Session session2 = HibernateUtils.getSession();
			Transaction tx2 = session2.getTransaction();
			tx2.begin();
			Address a2 = (Address)session2.get(Address.class, 1);
			tx2.commit();
			HibernateUtils.close(session2);
		}



hibernate.cfg.xml
<!-- 加入c3p0连接池 -->
				<property name="connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
				<property name="c3p0.max_size">20</property>
				<property name="c3p0.min_size">10</property>
				<property name="c3p0.timeout">3000</property>
	
	
			<!-- 启动二级缓存 -->
				<property name="hibernate.cache.use_second_level_cache">true</property>
				<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
			
			<!-- 配置需要二级缓存的类 -->
				<class-cache usage="read-only" class="demo3_lazy.Address"/>




2、hibernate的对象状态
①临时态:
没有在数据库中有任何的记录,普通的为刚创建出来的对象数据


特点:
1、没有OID(对象的主键值)
2、数据库中没有对应的记录
3、任何的修改操作的不会反映到数据库
4、临时对象不在一级缓存


②持久态:
保存数据在数据库中,并且在一级缓存中

特点:
1、有OID(对象的主键值)
2、数据库中有对应的记录
3、任何的修改操作的会反映到数据库
4、持久化对象在一级缓存


③游离态:
把对象在一级缓存中清除


特点:
1、有OID(对象的主键值)
2、数据库中有对应的记录
3、任何的修改操作的不会反映到数据库
4、游离对象不在一级缓存


④删除态:
把对象进行删除,或者变成垃圾回收

特点:
1、有OID(对象的主键值)
2、数据库中没有对应的记录
3、任何的修改操作的不会反映到数据库

4、删除对象不在一级缓存



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值