才高行厚的hibernate(3)---对象状态&常用接口

来源:互联网 发布:php会员信息管理系统 编辑:程序博客网 时间:2024/05/18 15:08

三种对象状态

三种状态的区别
transient:内存中一个对象,没ID,缓存中也没有
persistent:内存中有,缓存中有,数据库只有(ID) 
detached:内存有,缓存没有,数据库有数据,有ID
三种状态的转换,使用session操作

注意:session是非线程安全的,每次业务需要重新new一个,实体类可以实现Lifeeyele或Interceptor来监听过程事件

核心开发接口

创建两个类,使用注解指定关系:
person类省略setter和getter方法
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;@Entitypublic class Person {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private int id;@Columnprivate 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;@Entitypublic class Pro {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private int aid;@ManyToOne@JoinColumn(name = "personid")// 如果没有@ForeignKey则会按照数据库自动生成的外键索引命名@ForeignKey(name = "fperson")private Person person;@Columnprivate 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 {@BeforeClasspublic static void setUpBeforeClass() throws Exception {// Configuration cfg = new// Configuration();-->对配置文件的实例化,hibernate.properties// Configuration cfg = new// Configuration().configure()-->对默认xml配置文件的初始化,hibernate.cfg.xmlConfiguration cfg = new Configuration().configure("hibernate.xml");// 对自定义名称的xml文件初始化,只能位于classess路径下// 在hibernate4以后需要使用这种方法创建sessionfactoryServiceRegistry 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();// 每次都是新的,需要closetx = 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()

对应SQLbetween子句

Restrictions.like()

对应SQLlike子句

Restrictions.in()

对应SQLin子句

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'







原创粉丝点击