Hibernate提供了很多API用来尽心与数据库的交互包括保存,更新,删除等等。我们这里来测试一下:
首先依然是Hibernate的配置文件:
<?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>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!-- Drop and re-create the database schema on startup
<property name="hbm2ddl.auto">update</property>
-->
<mapping resource="com/smile/hibernate/Student.hbm.xml"/>
<mapping class="com.smile.hibernate.Teacher"/>
</session-factory>
</hibernate-configuration>
对应的实例对象:
Student.java:
package com.smile.hibernate;
public class Student {
private int id;
private String name;
private int age;
private String sex;
private boolean good;
public boolean isGood() {
return good;
}
public void setGood(boolean good) {
this.good = good;
}
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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
Teacher.java:
package com.smile.hibernate;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Transient;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Loader;
@Entity
@DynamicUpdate(value=true)
public class Teacher {
private int id;
private String name;
private String title;
private String yourWifeName;
private Date birthDate;
private boolean good;
private Gender gender;
@Enumerated(EnumType.STRING)
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public boolean isGood() {
return good;
}
public void setGood(boolean good) {
this.good = good;
}
@Transient
public String getYourWifeName() {
return yourWifeName;
}
public void setYourWifeName(String yourWifeName) {
this.yourWifeName = yourWifeName;
}
@Id
@GeneratedValue
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 getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
}
建立一个JUnit的测试类来进行测试:
package com.smile.hibernate;
import java.util.Date;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import com.smile.hibernate.Student;
import com.smile.hibernate.Teacher;
import com.smile.hibernate.util.HibernateUtil;
public class HibernateCoreAPITest {
private static SessionFactory sessionFactory;
@BeforeClass
public static void beforeClass() {
sessionFactory = HibernateUtil.getSessionFactory();
}
@AfterClass
public static void afterClass() {
sessionFactory.close();
}
@Test
public void testTeacherSave() {
Teacher t = new Teacher();
t.setName("t1");
t.setTitle("middle");
t.setBirthDate(new Date());
//目前t是一个transient对象
//Session session = sessionFactory.openSession();
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
session.save(t);
//t被持久化
Session session2 = sessionFactory.getCurrentSession();
System.out.println(session == session2);
//这时候session和session2是同一个对象
session.getTransaction().commit();
Session session3 = sessionFactory.getCurrentSession();
//当session的事务commit之后再得到的session就已经不是同一个了
System.out.println(session == session3);
}
@Test
public void testSaveStudent() {
Student s = new Student();
s.setName("s1");
s.setAge(19);
s.setSex("M");
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
session.save(s);
System.out.println(s.getId());
session.getTransaction().commit();
System.out.println(s.getId());
}
@Test
public void testSaveWith3State() {
Teacher t = new Teacher();
t.setName("t1");
t.setTitle("middle");
t.setBirthDate(new Date());
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
session.save(t);
//这时候虽然已经持久化 但是还没有更新到数据库 形成的是脏数据
System.out.println(t.getId());
session.getTransaction().commit();
//这时候真正更新了
System.out.println(t.getId());
}
@Test
public void testDelete() {
Teacher t = new Teacher();
t.setName("t1");
t.setTitle("middle");
t.setBirthDate(new Date());
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
session.save(t);
System.out.println(t.getId());
session.getTransaction().commit();
Session session2 = sessionFactory.getCurrentSession();
session2.beginTransaction();
session2.delete(t);
session2.getTransaction().commit();
//detached对象 还是可以取到的 使用save或者saveOrUpdate方法可以进行持久化
System.out.println(t.getId());
}
@Test
public void testDelete2() {
Teacher t = new Teacher();
t.setId(3);
Session session2 = sessionFactory.getCurrentSession();
session2.beginTransaction();
session2.delete(t);
session2.getTransaction().commit();
}
@Test
public void testLoad() {
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
//此时的类为代理类 具体原理参考设计模式动态代理 这里的t只加载了主键 别的属性并未加载
Teacher t = (Teacher)session.load(Teacher.class, 1);
System.out.println(t.getId());
//当前未执行sql语句
session.getTransaction().commit();
System.out.println(t.getClass());
//class com.smile.hibernate.Teacher_$$_jvst927_0
//此时执行sql语句
System.out.println(t.getName());
//抛出异常org.hibernate.LazyInitializationException: could not initialize proxy
//因为在执行load的时候并未真正的执行sql语句 这时候session已经commit了 这时候要去执行的时候已经找不到session了 所以会报错
}
@Test
public void testGet() {
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Teacher t = (Teacher)session.get(Teacher.class, 1);
//与load不同 此时就已执行sql语句
System.out.println(t.getId());
session.getTransaction().commit();
System.out.println(t.getClass());
//class com.smile.hibernate.Teacher
System.out.println(t.getName());
//由于get方法会直接执行sql 所以这里的t已经在commit之前加载完毕 所以不会报错
}
@Test
public void testUpdate1() {
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Teacher t = (Teacher)session.get(Teacher.class, 1);
//persistent形式对象
session.getTransaction().commit();
//commit之后变成了detached 但是这时候有id 所以下边再update还是可以找到
t.setName("zhanglaoshi");
Session session2 = sessionFactory.getCurrentSession();
session2.beginTransaction();
session2.update(t);
session2.getTransaction().commit();
}
@Test
public void testUpdate2() {
//transient对象 没有id更新会出错
Teacher t = new Teacher();
t.setName("zhanglaoshi");
Session session2 = sessionFactory.getCurrentSession();
session2.beginTransaction();
session2.update(t);
//更新出错 因为没有找到id
session2.getTransaction().commit();
}
@Test
public void testUpdate3() {
//transient对象 由于 有id可以从数据库找到 就可以更新 detached /游离
Teacher t = new Teacher();
t.setId(1);
t.setName("zhanglaoshi");
Session session2 = sessionFactory.getCurrentSession();
session2.beginTransaction();
session2.update(t);
session2.getTransaction().commit();
}
@Test
public void testUpdate4() {
//persistent对象只要有变化 内存与数据库同步 发更新指令
//默认为所有字段全部更新 设置不全部分性 可设置列的annotation为@DynamicUpdate(value=true)或者xml中配置dynamic-update="true"
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Teacher t = (Teacher)session.get(Teacher.class, 1);
t.setName("zhangsan3");
session.getTransaction().commit();
}
@Test
public void testUpdate5() {
//默认为所有字段全部更新 设置xml文件或者Annotation dynamic-update=true属性只更新指定字段 并且如果没有变化时不更新
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Student s = (Student)session.get(Student.class, 1);
s.setName("zhangsan5");
session.getTransaction().commit();
//commit之后 对象编程detached 与数据库关联已消失 所以设置的dynamic-update属性无法与数据库检查 下边的update语句全部更新
s.setName("z4");
Session session2 = sessionFactory.getCurrentSession();
session2.beginTransaction();
session2.update(s);
session2.getTransaction().commit();
}
@Test
public void testUpdate6() {
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Student s = (Student)session.get(Student.class, 1);
s.setName("zhangsan6");
//持久化的对象 设置名称可以
session.getTransaction().commit();
//游离态的对象设置
s.setName("z4");
Session session2 = sessionFactory.getCurrentSession();
session2.beginTransaction();
//merge之前有一次数据库查询的操作 会对update数据进行比较 这时候查到id 就不会全部更新
session2.merge(s);
session2.getTransaction().commit();
}
@Test
public void testUpdate7() {
//使用HQL(EJBQJ)语句进行更新 是推荐使用的形式
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
//此事update后边跟的Student为类名 而不是数据库表名
Query q = session.createQuery("update Student s set s.name='z5' where s.id = 1");
q.executeUpdate();
session.getTransaction().commit();
}
@Test
public void testSaveOrUpdate() {
//根据对象的三种状态 transient persistent detached来判断是执行save还是update
Teacher t = new Teacher();
t.setName("t1");
t.setTitle("middle");
t.setBirthDate(new Date());
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
session.saveOrUpdate(t);
session.getTransaction().commit();
t.setName("t2");
Session session2 = sessionFactory.getCurrentSession();
session2.beginTransaction();
session2.saveOrUpdate(t);
session2.getTransaction().commit();
}
@Test
public void testClear() {
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Teacher t = (Teacher)session.load(Teacher.class, 1);
System.out.println(t.getName());
//清理缓存中数据 下次取值依旧从数据库取
session.clear();
Teacher t2 = (Teacher)session.load(Teacher.class, 1);
System.out.println(t2.getName());
session.getTransaction().commit();
}
@Test
public void testFlush() {
Session session = sessionFactory.getCurrentSession();
// session.setFlushMode(flushMode); //设置flush模式
session.beginTransaction();
Teacher t = (Teacher)session.load(Teacher.class, 1);
t.setName("tttt");
session.flush(); //强行即时同步数据库数据
// session.clear(); //清除对象 不再跟数据库同步
t.setName("ttttt");
session.getTransaction().commit(); //commit时发出update语句
}
//创建表
@Test
public void testSchemaExport() {
//第一个参数是表示是否打印sql语句 第二个参数表示是否执行sql语句
new SchemaExport(new Configuration().configure()).create(false, true);
}
public static void main(String[] args) {
beforeClass();
}
}
一个创建SessionFactory的工具类:
package com.smile.hibernate.util;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
Configuration cfg = new Configuration().configure();
SessionFactory sc = cfg.buildSessionFactory(new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build());
return sc;
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}