Hibernate入门2

来源:互联网 发布:知乎 红楼梦 情榜 编辑:程序博客网 时间:2024/06/03 06:33

*瞬时对象(Transient Objects)使用new 操作符初始化的对象不是立刻就持久的。它们的状态是瞬时的,也就是说它们没有任何跟数据库表相关联的行为,只要应用不再引用这些对象(不再被任何其它对象所引用),它们的状态将会丢失,并由垃圾回收机制回收。

*持久化对象(Persist Objects)持久实例是任何具有数据库标识的实例。它有持久化管理器Session统一管理,持久实例是在事务中进行操作的——它们的状态在事务结束时同数据库进行同步。当事务提交时,通过执行SQLINSERTUPDATEDELETE语句把内存中的状态同步到数据库中。

*离线对象(Detached Objects)Session关闭之后,持久化对象就变为离线对象。离线表示这个对象不能再与数据库保持同步,它们不再受Hibernate管理。

 

 

 

*transient状态的特征?没在缓存中,没任何对象引用

          在数据库中没有与之匹配的数据

          没有纳入session的管理

        

*persistent状态的特征?在缓存中,有对象引用

          persistent状态的对象在数据库中有与之匹配的数据(uuid是没有的)

          纳入了session的管理(save的时候放到缓存一份,放到了sessionmapping)

          在清理缓存(脏数据检查)的时候,会和数据库同步

        

*detached状态的特征?从缓存中清了,没有任何对象引用

          在数据库中有与之匹配的数据

          没有纳入session的管理

 

Hibernate_session:

工具类:HibernateUtils

 

/**

*使SessionFactory只初始一次

*/

public class HibernateUtils {

   

    private static SessionFactory factory;

   

    //调用类的static只初始化一次,因此factory只有一个

    static {

       try{

           Configuration cfg = new Configuration().configure();

           factory = cfg.buildSessionFactory();

       }catch(Exception e){

           e.printStackTrace();

       }

    }

   

    public static SessionFactory getSessionFactory(){

       return factory;

    }

   

    public static Session getSession(){

       return factory.openSession();

    }

   

    public static void closeSession(Session session){

       if(session != null){

           if(session.isOpen()){

              session.close();

           }

       }

    }

 

}

 

* junit简介:(建源代码目录,放测试类***Test)

    编写测试类xxxTest,需要继承TestCase

    编写单元测试方法,测试方法必须以test开头,测试方法不能含有参数和返回值,如:

     public void testHello1() {}

   最好单元测试的代码单独建立一个目录(建立一个源代码文件),但运行的时候class还是放在一起的。

    setUp():公用的东西可以放在这个方法里,相当于Servlet中的init();

   

 

* SessionFactory:一个重量级对象,和二级缓存绑定.通常只创建一次。

*session:不要声明成成员变量,不是线程安全的,不要多线程来用,通常一个业务对以一个session,一个方法对应一个session,请求完毕,session关闭,事务关闭。

 

*三个状态:

public void testSave1(){

       Session session = null;

       User  user = null;

       Transaction tx = null;

       try{

           session = HibernateUtils.getSession();

           tx = session.beginTransaction();

          

           //Transient 瞬时状态,不会序列化

           user = new User();

           user.setName("李四");

           user.setPassword("123456");

           user.setCreateTime(new Date());

           user.setExpireTime(new Date());

          

           //persistent 状态:当属性发生改变,commit的时候Hibernate会自动和数据库同步,自动同步:不用显示写update

           //所以数据库中存放的是:王五

           session.save(user);//save之后必须要有id,此时是hibernate提供的,没去数据库取

          

           user.setName("王五");

           //uuid状态:commit之前数据库没有数据,commit之后清理缓存,sql到数据库. Commit后会脏数据检查,所以会发insertupdate两条语句

           tx.commit();

          

       }catch(Exception e){

           e.printStackTrace();

           tx.rollback();

       }finally{

           HibernateUtils.closeSession(session);

       }

       //detached状态

       user.setName(“张三”); 要把user变成这个函数的成员变量

       /**

       *user:update

*/

//此时数据库变化:王五变为张三

 

}

 

 

/**

     * get方法,查不到会返回null

     */

    public void testReadByGetMethod(){

       Session session = null;

       try{

           session = HibernateUtils.getSession();

           session.beginTransaction();

          

 

           //马上发查询sql,加载User对象;根据iduser,id要实现序列化的

           User user = (User)session.get(User.class,"402881e42302c687012302c689720001");

           System.out.println("User.Name:"+user.getName());

          

           //persistent状态,属性改变时,Hibernate自动和数据库同步,不用显示update

           user.setName("郭杰"); //查出来的name改为郭杰,数据库里也为郭杰,其他字段保持不变

           session.getTransaction().commit();

       }catch(Exception e){

           e.printStackTrace();

           session.getTransaction().rollback();

       }finally{

           HibernateUtils.closeSession(session);

       }

}

 

/**

     * get方法2

     */

    public void testReadByGetMethod2(){

       Session session = null;

       try{

           session = HibernateUtils.getSession();

           session.beginTransaction();

          

           //马上发出sql,加载User对象;查不到会返回null

           User user = (User)session.get(User.class,"0001");

           System.out.println(user);//null

       }catch(Exception e){

           e.printStackTrace();

           session.getTransaction().rollback();

       }finally{

           HibernateUtils.closeSession(session);

       }

}

 

/**

     * Load方法

     */

 

public void testReadByLoadMethod(){

       Session session = null;

       try{

           session = HibernateUtils.getSession();

           session.beginTransaction();

          

           //不会发出sqlload只有真正使用的时候才加载(lazy),下面要输出了才加载(发出sql) get的区别

           //延迟加载实现原理:CGLIB动态代理方式

           User user = (User)session.load(User.class,"402881e422e421500122e421528a0001");//此时user对象为代理对象,下面要用了才去真正查询

           System.out.println("User.Name:"+user.getName());

          

           //persistent状态,属性改变时,Hibernate自动和数据库同步

           user.setName("郭杰");

           session.getTransaction().commit();

       }catch(Exception e){

           e.printStackTrace();

           session.getTransaction().rollback();

       }finally{

           HibernateUtils.closeSession(session);

       }

}

/**

     * Load:注意和get的两个区别:1load延迟加载,2、无数据时load报错

     */

 

public void testReadByLoadMethod2(){

       Session session = null;

       try{

           session = HibernateUtils.getSession();

           session.beginTransaction();

           // load只有真正使用的时候才加载(lazy),下面要输入才发sql,get的区别

           //数据库中没有这个id的时候load会抛出异常 get的第二个区别

           User user = (User)session.load(User.class,"0001");

           //下面注释掉不会抛出异常,因为没发sql,即没load

           //没注释掉会报错,但是仍显示绿色条,因为没向上抛.见下面的catch语句

           //System.out.println("User.Name:"+user.getName());

       }catch(Exception e){

           e.printStackTrace();

           session.getTransaction().rollback();

           //下面那句注释掉就会显示绿色,只有往上抛了才显示红色

           throw new java.lang.RuntimeException();

       }finally{

           HibernateUtils.closeSession(session);

       }

}

 

    /**

     * update

     */

    public void testUpdate1() {

       Session session = null;

       try {

           session = HibernateUtils.getSession();

           session.beginTransaction();

          

           //手动构造的detached状态的对象,因为new的时候id是数据库中已存在的,所以detached状态。New的时候如果数据库中没有为Transient瞬时状态

           //结果没设置的属性都变成了null

           //所以一般先加载(get load)上来,再修改,就像上面的例子

           User user = new User();

           user.setId("402881e422e421500122e421528a0001");//id必须要和数据库中已有的一样,这是hibernate生成的,不能更改

           user.setName("德华");

           session.update(user);//只有detached状态才可以update.

           session.getTransaction().commit();

       }catch(Exception e) {

           e.printStackTrace();

           session.getTransaction().rollback();

       }finally {

           HibernateUtils.closeSession(session);

       }

}

*get load 都是根据主键加载

 

    /**

     * 删除方法,只能删除persistent状态

     */

    public void testDelete1() {

       Session session = null;

       try {

           session = HibernateUtils.getSession();

           session.beginTransaction();

          

           //先加载上来在删除

           User user = (User)session.load(User.class, "402881e422e421500122e421528a0001");

           session.delete(user);//此时user对象transient状态

           session.getTransaction().commit();

       }catch(Exception e) {

           e.printStackTrace();

           session.getTransaction().rollback();

       }finally {

           HibernateUtils.closeSession(session);

       }

   

}

 

 

*了解HibernateCRUD操作

 

*了解getload的区别?

     * get不支持lazyload支持lazy

     * 采用get加载数据,如果没有匹配的数据,返回null,而load则抛出异常

    

*transient状态的特征?瞬时的

     * 在数据库中没有与之匹配的数据

     * 没有纳入session的管理

    

*persistent状态的特征?持久的

     * persistent状态的对象在数据库中有与之匹配的数据(uuid是没有的)

     * 纳入了session的管理

     * 在清理缓存(脏数据检查)的时候,会和数据库同步

    

*detached状态的特征?离线

     * 在数据库中有与之匹配的数据

     * 没有纳入session的管理        

*uuid:save()之后:变成persistent状态,数据库中没数据 commit()之前数据库没有记录,commit()之后清理缓存,发sql,数据库中有记录

 

Query实例:

public class QueryTest extends TestCase {

   

    public void testQuery(){

       Session session = null;

       try{

           session = HibernateUtils.getSession();

           session.beginTransaction();

           //from 后面区分大小写 因为查的是实体类

           String hql = "from User";

           Query query = session.createQuery("from User");

          

           //query的分页,setFirstResult:第几条开始,2:表示第三条 0:表示第一条。后面的表示查询几条

           query.setFirstResult(2);

           query.setMaxResults(2);

          

           List<User> userList = query.list();

           for(User ue: userList){

              System.out.println(ue.getId());

              System.out.println(ue.getName());

           }

           session.getTransaction().commit();

       }catch(Exception e){

           e.printStackTrace();

           session.getTransaction().rollback();

       }finally{

           HibernateUtils.closeSession(session);

       }

    }

 

}

 

*一个OR框架包括:映射(ormapping)Hql、缓存等等。

*OR框架:批量查询可以:Query; 有统计函数、批量修改、批量删除不适合!

*Query接口支持HQL SQL

 

*通过<property>标签将普通属性映射成表字段,所谓普通属性指不包括自定义类、集合和数组等.主键用<id>

 

*注意:如果实体类和实体类中的属性和sql中的关键字重复,必须采用tablecolumn重新命名

 

*实体类的普通属性映射成表字段. 普通属性:输了list map set 数组等

*<class>标签映射成数据库的表,<property>标签普通属性映射成表字段.

 

*主键生成策略:

uuidnativeassigned

 

*hql查询的是实体类

原创粉丝点击