三种对象状态
persistent:内存中有,缓存中有,数据库只有(ID)
detached:内存有,缓存没有,数据库有数据,有ID
核心开发接口
package hibernate.senssic.relevance;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column
private String name;
// 如果不添加mapperBy属性,指定参照外键,则会生成额外的一张表维系两者之间的关系
@OneToMany(mappedBy = "person")
private Set<Pro> pro;
}
Pro类省略setter和getter方法:
package hibernate.senssic.relevance;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import org.hibernate.annotations.ForeignKey;
@Entity
public class Pro {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int aid;
@ManyToOne
@JoinColumn(name = "personid")
// 如果没有@ForeignKey则会按照数据库自动生成的外键索引命名
@ForeignKey(name = "fperson")
private Person person;
@Column
private String address;
}
Configuration类:
package hibernate.test;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.BeforeClass;
import org.junit.Test;
public class Mytest {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
// Configuration cfg = new
// Configuration();-->对配置文件的实例化,hibernate.properties
// Configuration cfg = new
// Configuration().configure()-->对默认xml配置文件的初始化,hibernate.cfg.xml
Configuration cfg = new Configuration().configure("hibernate.xml");// 对自定义名称的xml文件初始化,只能位于classess路径下
// 在hibernate4以后需要使用这种方法创建sessionfactory
ServiceRegistry registry = new ServiceRegistryBuilder().applySettings(
cfg.getProperties()).buildServiceRegistry();
SessionFactory sFactory = cfg.buildSessionFactory(registry);)
}}
SessoinFactory:用来产生和管理Session,通常情况下每个应用只需要一个SessionFactory,除非要访间多个数据库的情况
SessionFactory sFactory = cfg.buildSessionFactory(registry);
//Session session1=sFactory.getCurrentSession();//从上下文找,如果有,用旧的,如果没有,建新的
Session session=sFactory.openSession();//每次都是新的,需要close
/**
* openSession和getCurrentSession的区别
* 1. 采用getCurrentSession()创建的session会绑定到当前线程中,而采用openSession()创建的session则不会
* 采用getCurrentSession()创建的session在commit或rollback时会自动关闭,而采用openSession()创建的session必须手动关闭
* 2、使用getCurrentSession()需要在hibernate.cfg.xml文件中加入如下配置:
* 如果使用的是本地事务(jdbc事务)
* <property name="hibernate.current_session_context_class">thread</property>
* 如果使用的是全局事务(jta事务)
* <property name="hibernate.current_session_context_class">jta</property>
*/
Session
Session session = null;
Transaction tx = null;
try {
session = sFactory.openSession();// 每次都是新的,需要close
tx = session.beginTransaction();// 开启事务
Pro pro = new Pro();
pro.setAddress("计本一班");
pro.setPerson((Person) session.load(Person.class, 1)/*(Person) session.get(Person.class, 1)*/);
session.save(pro);
session.delete(session.get(Pro.class, 1));
Person person=(Person)session.load(Person.class, 1);
person.setName("qiyu");
session.update(person);
//session.saveOrUpdate(person);//如果存在则更新,不存在则新保存
// SchemaExport export = new SchemaExport(cfg);
// export.create(true, true);//自动创建表
//session.clear();//清理session缓存,会清除脏数据的
session.flush();//当session的事务提交后,会强制将内存(session缓存)与数据库同步
tx.commit();// 提交事务
} catch (Exception e) {
tx.rollback();// 回滚事务
e.printStackTrace();
} finally {
if (session != null) {
session.close();// 关闭session
}
}
注意:
i. get与load的区别
1. 不存在对应记录时表现不一样,load抛出异常,get是为null
2. load返回的是代理对象,等到真正用到对象的内容时才发出sql语句
3. get直接从数据库加载,不会延迟
ii. updates
1. 用来更新detached对象,更新完成后转为persistent状态
2. 更新transient对象会报错
3. 更新自己设定id的transient对象可以(数据库有对应记录)
4. persistent状态的对象只要设定(如:t.setName…)不同字段就会发生更新
5. 更新部分更改的字段
a) xml 设定 property 标签的 update 属性,annotation 设定@Column 的 updatable
属性,不过这种方式很少用,因为不灵活
iii. clear方法
1.无论是load还是get,都会首先査找缓存(一级缓存),如果没有,才会去数据库査找,调用
clear()方法可以强制清除session缓存
iv. flush()方法
1. 当session的事务提交后,会强制将内存(session缓存)与数据库同步.默认情况下是session的事务提交(commit)时才同步!
2. session的FlushMode设置,可以设定在什么时候同步缓存与数据库(很少用)
例如: session.setFlushMode(FlushMode.AUTO)
Query:
Query query = session.createQuery("from Person");// 使用hql查询
// 分页查询
query.setFirstResult(0);
query.setMaxResults(2);
List<Person> list = query.list();
for (Person p : list) {
System.out.println(p.getName());
}
另外还有个Criteria 接口更加增加了查询的复杂度
Criteria cr = session.createCriteria(Person.class); //生成一个Criteria对象
cr.add(Restrictions.eq("name", "qiyu"));//等价于where name=‘qiyu’
List list = cr.list();
Student stu = (Student)list.get(0);
System.out.println(stu.getName());
常用的查询限制方法
Restrictions.eq()方法表示equal,即等于的情况。Restrictions类提供了查询限制机制。它提供了许多方法,以实现查询限制。这些方法及其他一些criteria常用查询限制方法列于表中。
Criteria Query常用的查询限制方法
方 法 | 说 明 |
Restrictions.eq() | equal,= |
Restrictions.allEq() | 参数为Map对象,使用key/value进行多个等于的对比,相当于多个Restrictions.eq()的效果 |
Restrictions.gt() | greater-than, > |
Restrictions.lt() | less-than, < |
Restrictions.le() | less-equal, <= |
Restrictions.between() | 对应SQL的between子句 |
Restrictions.like() | 对应SQL的like子句 |
Restrictions.in() | 对应SQL的in子句 |
Restrictions.and() | and关系 |
Restrictions.or() | or关系 |
Restrictions.isNull() | 判断属性是否为空,为空返回true,否则返回false |
Restrictions.isNotNull() | 与Restrictions.isNull()相反 |
Order.asc() | 根据传入的字段进行升序排序 |
Order.desc() | 根据传入的字段进行降序排序 |
MatchMode.EXACT | 字符串精确匹配,相当于“like 'value'” |
MatchMode.ANYWHERE | 字符串在中间位置,相当于“like '%value%'” |
MatchMode.START | 字符串在最前面的位置,相当于“like 'value%'” |
MatchMode.END | 字符串在最后面的位置,相当于“like '%value'” |