一,持久化对象:
1,置于session管理下的对象叫做持久化状态
2,新建对象叫做临时状态
3,被session释放的对象叫游离状态
例子:
package basic;
import java.util.Iterator;
import java.util.List;
//导入五大核心接口类包
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
/**
* hibernate基本操作
* @author chengzh
*
*/
public class Test {
//首先声明一个(每个应用只能有一个)数据存储源
private static SessionFactory sessionFactory = null;
static{
//由配置类来构造一个配置文件对象
Configuration config = new Configuration();
//利用配置类对象类构造一个数据存储源,指定配置文件来由buildSessionFactory方法
//构造sessionFactory,必须告诉具体配置文件路径.
sessionFactory = config.configure("basic/hibernate.cfg.xml").buildSessionFactory();
}
public void test1() throws Exception{
//通过sessionFactory得到持久化容器session(相当于JDBC里面获得一个连接)
Session session =sessionFactory.openSession();
//声明一个事务
Transaction tx=null;
try{
//通过session获得一个事务
tx=session.beginTransaction();
//构造一个持久化类的实例,临时状态
Student stu=new Student("zhangshan1",20);
//把对象值存入数据库中,临时状态
session.save(stu);
System.out.println(stu);//持久化状态
stu.setName("wangwu");
// session.delete(stu);//执行delete后,又回到临时状态,只有在持久和游离状态是才能作删除操作
tx.commit();//提交后,对上面操作全部更新
}catch(Exception e){
tx.rollback();
throw e;
}
}
public void saveStudent(Student student) throws Exception{
Session session = sessionFactory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
session.save(student);
tx.commit();
}catch(Exception e){
tx.rollback();
throw e;
}finally{
session.close();
}
}
public void findAllStudent() throws Exception{
Session session = sessionFactory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
//Query查询类也可删除,为HQL语言,对类对象作操作,Student可以加上包名
Query query = session.createQuery("from Student as s order by s.age asc");
List list = query.list();
for(Iterator it = list.iterator();it.hasNext();){
System.out.println(it.next());
}
tx.commit();
}catch(Exception e){
tx.rollback();
throw e;
}finally{
session.close();
}
}
public void findStudent(String name) throws Exception{
Session session = sessionFactory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
//由session得到查询器Query.为HQL语言,对类对象作操作,Student可以加上包名
Query query = session.createQuery("from Student as s where s.name=:stuName order by s.age asc");
query.setString("stuName",name);
//由Query的对象来查询数据库,并且将查询上结果以对象的形式返回.存入集合
List list = query.list();
for(Iterator it = list.iterator();it.hasNext();){
System.out.println(it.next());
}
tx.commit();
}catch(Exception e){
tx.rollback();
throw e;
}finally{
session.close();
}
}
public void loadAndUpdateStudent(Long id) throws Exception{
//根据一个ID号加载一个对象,加载完后会放入session的池中,进入持久化状态
Session session = sessionFactory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
//当池中没数据时对数据库操作,根据ID号,把对象加载到session池中,之后
//都对池作操作.都是持久化状态.
Student student = (Student)session.load(Student.class,id);
//对name进行更新,
//student.setName("new1");
System.out.println(student);
//当做完一个操作后,对缓存进行刷新(把这次操作放在缓存中的结果
//提交到数据库中.使session容器一直处在最新状态.
tx.commit();
session.close();
//游离状态
Session session2 = sessionFactory.openSession();
Transaction tx2 = session2.beginTransaction();
student.setName("lisi");
session2.update(student);//只有从在游离状态时,才能做Update操作.之后下面变成持久状态
tx2.commit();//持久化状态
session2.close();//关闭后又回到游离状态.
}catch(Exception e){
tx.rollback();
throw e;
}finally{
//session.close();
}
}
public void deleteAllStudents() throws Exception {
// 执行delete后,又回到临时状态,只有在持久和游离状态是才能作删除操作
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Query query = session.createQuery("delete Student as s");
query.executeUpdate();
tx.commit();
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
throw e;
} finally {
// No matter what, close the session
session.close();
}
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Test test = new Test();
// Student student = new Student("s1",20);
// test.saveStudent(student);
// test.findAllStudent();
// test.findStudent("s1");
test.loadAndUpdateStudent(new Long(2));
// test.deleteAllStudents();
// test.test1();
//关闭sessionFactory
sessionFactory.close();
}
}
二,五大类型的OID生成方式:
1,sequence :序列化,依赖于数据库,对id号生成有序的数字,xml例子在第一天里面有.
2,increment:由hibernate生成,与数据库无关,每次操作,把最大的ID号自动加1.
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"/home/soft01/heguanhua/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="basic.Student" table="student1">
<id name="id" column="id" type="long">
<generator class="increment"/>
</id>
<property name="name" column="name" type="string"/>
<property name="age" column="age" type="int"/>
</class>
</hibernate-mapping>
3,identity:要求数据库支持自动增长字段.
<?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>
<class name="basic2.Student" table="student1">
<id name="id" column="id" type="long">
<generator class="identity"/>
</id>
<property name="name" column="name" type="string"/>
<property name="age" column="age" type="int"/>
</class>
</hibernate-mapping>
4,assign:表示由程序提供主键的生成.
<?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>
<class name="basic3.Student" table="STUDENT_na1">
<id name="name" column="name" type="string">
<generator class="assigned"/>
</id>
<property name="age" column="age" type="int"/>
</class>
</hibernate-mapping>
5,hilo生成方式:
<?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>
<class name="basic1.Student" table="student1">
<id name="id" column="id" type="long">
<generator class="hilo">
<param name="table">hi_value</param>
<param name="column">next_value</param>
<param name="max_lo">100</param>
</generator>
<!--
<generator class="increment"/>
-->
</id>
<property name="name" column="name" type="string"/>
<property name="age" column="age" type="int"/>
</class>
</hibernate-mapping>
三,一对多的单向关联
数据库的建立:
CREATE TABLE STUDENT2
(
ID bigint primary key,
NAME VARCHAR(20),
AGE int
)
CREATE TABLE Course2
(
ID bigint primary key,
Name VARCHAR(20),
SCORE int,
Student_id bigint not null
);
alter table Course2 add constraint course2_stu2_fk
foreign key(student_id) references student2(id);
hibernate.cfg.xml 和 course.hbm.xml两个文件与双向关联类似.这里不多写.
Student1.hbm.xml文件为:
HYPERLINK "Student1.hbm.xml"HYPERLINK "Student1.hbm.xml"
HYPERLINK "Student1.hbm.xml"<?xml version="1.0"?>
HYPERLINK "Student1.hbm.xml"<!DOCTYPE hibernate-mapping PUBLIC
HYPERLINK "Student1.hbm.xml" "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
HYPERLINK "Student1.hbm.xml" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
HYPERLINK "Student1.hbm.xml"<hibernate-mapping>
HYPERLINK "Student1.hbm.xml" <class name="onetomany.t1.Student" table="student2">
HYPERLINK "Student1.hbm.xml" <id name="id" column="id" type="long">
HYPERLINK "Student1.hbm.xml" <generator class="increment"/>
HYPERLINK "Student1.hbm.xml" </id>
HYPERLINK "Student1.hbm.xml" <property name="name" column="name" type="string"/>
HYPERLINK "Student1.hbm.xml" <property name="age" column="age" type="int"/>
HYPERLINK "Student1.hbm.xml" </class>
HYPERLINK "Student1.hbm.xml"</hibernate-mapping>
Student类与course类缺省,以下是测试类:
package onetomany.t1;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class Test {
private static SessionFactory sessionFactory = null;
static {
Configuration config = new Configuration();
sessionFactory = config.configure("onetomany/t1/hibernate.cfg.xml")
.buildSessionFactory();
}
public void saveStudentAndCourse() throws Exception {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Student student = new Student("t1", 20);
session.save(student);
Course course1 = new Course("math", 60,student);
Course course2 = new Course("english", 90,student);
session.save(course1);
session.save(course2);
tx.commit();
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
throw e;
} finally {
session.close();
}
}
public void saveStudentAndCourseCaseCade() throws Exception {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Student student = new Student("t1", 20);
Course course1 = new Course("math", 60,student);
Course course2 = new Course("english", 90,student);
session.save(course1);
session.save(course2);
tx.commit();
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
throw e;
} finally {
session.close();
}
}
public Student findStudent(Long id) throws Exception{
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Student student = (Student)session.load(Student.class,id);
tx.commit();
return student;
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
throw e;
} finally {
session.close();
}
}
public List findCourseByStudent(Student student) throws Exception{
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Query query = session.createQuery("from Course as c where c.student.id="+student.getId());
List courses = query.list();
tx.commit();
return courses;
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
throw e;
} finally {
session.close();
}
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Test test = new Test();
test.saveStudentAndCourse();
// test.saveStudentAndCourseCaseCade();
Student stu = test.findStudent(new Long(505));
List list = test.findCourseByStudent(stu);
for(Iterator it = list.iterator();it.hasNext();){
Course course = (Course)it.next();
System.out.println(course.getCouseName());
}
sessionFactory.close();
}
}
四,双向一对多关联:
1,HYPERLINK "http://hibernate.cfg.xml/"hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"/home/soft01/heguanhua/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/tarena</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<mapping resource="day2/Student.hbm.xml"/>
<mapping resource="day2/Course.hbm.xml"/>
</session-factory>
</hibernate-configuration>
2,HYPERLINK "http://student.hbm.xml/"student.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"/home/soft01/heguanhua/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="day2.Student" table="student1">
<id name="id" column="id" type="long">
<!-- 由increment生成OID 把表中最大的ID号每次自动加一 -->
<generator class="increment"/>
</id>
<property name="name" column="name" type="string"/>
<property name="age" column="age" type="int"/>
<!-- 双向一对多,用集合来映射多个课程 -->
<!-- name="courses" 学生类中集合 课程名 -->
<!-- lazy="false" :加载学生类的时候,是否加载与学生关联的课程对象,
当值为false时是指需要加载 -->
<!-- cascade :级联更新,当删除或存取学生对象时
把对应关联的课程对象也做删除或存取操作 -->
<!-- inverse的意义:当学生的一方的inverse设置为true,能够或避免
重复的update操作来提升程序性能 -->
<set
name="courses"
lazy="false"
cascade="all-delete-orphan"
inverse="true"
>
<!-- 表示指定course的外键是什么 -->
<key column="Student_id" />
<!-- 指定一对多的对象的类型为course -->
<one-to-many class="day2.Course" />
</set>
</class>
</hibernate-mapping>
3,course.hbm.xml文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"/home/soft01/heguanhua/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="day2.Course" table="course">
<id name="id" column="id" type="long">
<generator class="increment"/>
</id>
<property name="couseName" column="name" type="string"/>
<property name="score" column="SCORE" type="int"/>
<!-- 从课程来说是多对一的关系 -->
<!-- 下面的column: 指定外键 -->
<!-- cascade: 级联更新,保存或更新课程时,同时保存或更新与课程有关联的
学生信息 -->
<!-- class: 学生属性所存取的对象存取的类型 -->
<!-- student属性不能为空 -->
<many-to-one
name="student"
column="Student_id"
cascade="save-update"
class="day2.Student"
not-null="true"
/>
</class>
</hibernate-mapping>
Student持久化对象类:
package day2;
import java.util.*;
public class Student {
//双向关联,由于是一对多的关系,把课程用集合来存取
private Long id;
private String name;
private int age;
private Set courses;
public Student(String name, int age, Set courses) {
super();
// TODO Auto-generated constructor stub
this.name = name;
this.age = age;
this.courses = courses;
}
public Student(){
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
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;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "id "+id+" name "+name+" age"+age;
}
public Set getCourses() {
return courses;
}
public void setCourses(Set courses) {
this.courses = courses;
}
}
5,Course持久化对象类:
package day2;
public class Course {
private Long id;
private String couseName;
private int score;
//在课程来说.是多个课程对一个学生. 把学生当做课程的属性,实现关联
private Student student;
public Course(String couseName, int score) {
super();
// TODO Auto-generated constructor stub
this.couseName = couseName;
this.score = score;
}
public Course(){
}
@Override
public String toString() {
// TODO Auto-generated method stub
return " id "+id+" courseName "+couseName+" score = "+score;
}
public String getCouseName() {
return couseName;
}
public void setCouseName(String couseName) {
this.couseName = couseName;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
}
6,测试类:
package day2;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class Test {
private static SessionFactory sessionFactory = null;
static {
Configuration config = new Configuration();
sessionFactory = config.configure("day2/hibernate.cfg.xml")
.buildSessionFactory();
}
/**
* Student.hbm.xml中将inverse="false",会重复执行多余的SQL语句,因此
* 在映射一多对的双向关联时,应该将inverse设置为true;
*
* @throws Exception
*/
public void saveStudentAndCourseCascade() throws Exception {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
//一对多的关系,一个学生有多个课程.用SET来存取.
Student student = new Student("t3",20, new HashSet());
//添加一个课程
Course course = new Course("math",60);
//设置课程对象,里面的Student属性.
course.setStudent(student);
//添加学生的多个课程到容器当中,这里只添加了一个.
student.getCourses().add(course);
/**提交学生对象到数据库中,查看session池中是否存在有要插入student和
* course对象的相同的值,因为映射文件的Cascade定义了级联操作.把student
* 对象插入时,根据映射文件的定义规则.把与之有关的course对象也相应的加载
* 到数据库和session池中.
*/
session.save(student);
tx.commit();
} catch (Exception e) {
if (tx != null) {
// Something went wrong; discard all partial changes
tx.rollback();
}
e.printStackTrace();
} finally {
// No matter what, close the session
session.close();
}
}
/**
* 注意cascade="all-delete-orphan" ,
表示:
1,保存或更新Student时,级联保存或更新所有关联的Course对象,相当于cascade=“save-update”
2,当删除时,相当于"delete"
3,删除不再和Student对象关联的所有Course对象
* @throws Exception
*/
public void deleteStudent() throws Exception {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Student student = (Student)session.load(Student.class,new Long(12));
// 删除一个持久对象,是指从数据库中删除相关的纪录,此对象变为临时状态,依然在内存中
//把学生删除时,与之关联的课程对象也跟着删除.
session.delete(student);
tx.commit();
System.out.println(student);
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
e.printStackTrace();
} finally {
session.close();
}
}
public void removeCourseFromStudent() throws Exception{
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Student student=(Student)session.load(Student.class,new Long(13));
//把课程对象的值都迭代出来,通过学生类中的课程Set来找出所有的课程.
Course course=(Course)student.getCourses().iterator().next();
//把学生类中的课程记录都删除
student.getCourses().remove(course);
//把课程中的学生对象清空.至此学生与课程完全断连.
course.setStudent(null);
tx.commit();
}catch (Exception e) {
if (tx != null) {
tx.rollback();
}
e.printStackTrace();
} finally {
session.close();
}
}
/**双向一对多关系.
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Test test = new Test();
test.saveStudentAndCourseCascade();
// test.deleteStudent();
// test.removeCourseFromStudent();
sessionFactory.close();
}
}