hibernate总结

来源:互联网 发布:win2008 mac 绑定 编辑:程序博客网 时间:2024/06/05 16:40
  1. orm:对象映射

  2. 默认值问题
    在数据库中,某个表的某个属性有默认值的情况下。在不用set方法赋值的情况下,默认值不生效为空。需要改动.cfg.xml中表的属性。Dynamic-update=”true”
    举例:

<class name="wyn.hibernate.entity.User" table="user" catalog="book" optimistic-lock="version" dynamic-insert="true">

3 hibernate的一级缓存(session缓存,只支持对象缓存(非list),不支持查询缓存)
(验证:(未开启二级缓存的情况下)先查询全体成员,再查询单个成员(如果再次查 询全体,则执行2次sql语句),最后关闭session。
结果:sql一句只执行一次(查询全体的),查询单个成员时,会先从session中查 找(session中已有全部的成员信息),找到之后就不会再从数据库中寻找。如果 未找到,再从数据库中查找。)举例:
未关闭session时:sql语句只执行一次。
举例:

Query q=session.createQuery("from User");     List<User> users=q.list();     System.out.println("一级缓存测试........................"+users.size());     User user1=(User) session.get(User.class,1);     System.out.println(user1.getUsername());     session.close();关闭session时:sql语句执行2次Query q=session.createQuery("from User");     List<User> users=q.list();     System.out.println("一级缓存测试........................"+users.size());     session.close();     session=sf.openSession();     User user1=(User) session.get(User.class,1);//对象缓存     System.out.println(user1.getUsername());     session.close();

session的3种状态
3.1 临时(瞬时)状态(User user=new User(),不被session关联)
3.2 持久化状态(调用save或者save0rUpdate方法或者直接调用get方法等,并commit)
持久化状态session域中的数据是在被提交时更新(即和数据库中的数据同步),在此之前 连续对某个属性的更改,并不会全部被变为sql语句执行,只会执行最后一条更该语句。
数据存放在sesion中,如果不close()掉,则会一直存在,可以直接使用,一直和session 关联
3.3游离状态(在close()之后,不被session关联)

4 hibernate的延时加载
4.1 Hibernate默认情况下是不会查询所有外键关联的表的数据的(在从表中设置中lazy属性为false就可延时查询外键关联表的数据)(多对一的情况)
在hbm.xml文件中关联外键的表

<many-to-one name="teacher" class="wyn.hibernate.entity1.Teacher" fetch="select" lazy="false"><column name="tid" /></many-to-one>在test(实现类中)的代码:public static void main(String [] args){    Configuration cfg=new Configuration().configure();    ServiceRegistry sr=new ServiceRegistryBuilder()                 .applySettings(cfg.getProperties()).buildServiceRegistry();      //SessionFactory类似数据库库的一个Connection      SessionFactory sf =cfg.buildSessionFactory(sr);    Session session=sf.openSession();    //开启一个事务    Transaction t=session.beginTransaction();    Student s=(Student) session.get(Student.class,1);    t.commit();    System.out.println(s.getName());    session.close();    System.out.println(s.getTeacher().getName());    }

4.2 在主表中,实现延时查询

<set name="students" table="student" inverse="true" lazy="false"        fetch="select">            <key>                <column name="tid" />            </key>            <one-to-many class="wyn.hibernate.entity1.Student"  />  </set>

(一对多,此时这个one并没有layz这个属性,需要在set属性中修改,并且在Teacher这个类中会自动生成private Set students = new HashSet(0);)

5 主表和从表
主表(父表)
在数据库中建立的表格即Table,其中存在主键(primary key)用于与其它表相关联,并且作为在主表中的唯一性标识。
从表(子表)
以主表的主键(primary key)值为外键 (Foreign Key)的表,可以通过外键与主表进行关联查询。从表与主表通过外键进行关联查询。
关系及用法概述
从表数据依赖于主表,一般最后查询数据时把主表与从表进行关联查询。

6 hql(hibernate query language) 跨数据库语言的查询方式
第一种方式

Query q=session.createQuery("from Student where name='王'");//Student是javabean的类名,而不是数据库的表名        List<Student> lists=q.list();        System.out.println(lists.size());

第二种方式

Student student=new Student();        student.setChengji(100.0);        String sql="from Student where 1=1 ";//记得”1=1”后边留空格        if(!student.equals("")||student!=null){            if(student.getChengji()!=null){                sql+=" and chengji='"+student.getChengji()+"'";            }//记得’and’之前留空格            Query q1=session.createQuery(sql);            List<Student> lists1=q1.list();            System.out.println(lists1.size());

第三种方式,根据位置绑定数据/根据名称绑定数据

Query q1=session.createQuery("from Student where chengji=? //根据位置        and kecheng=:a ");//根据名称        q1.setDouble(0, 100.0);        q1.setString("a", "高数");        List<Student> lists1=q1.list();        System.out.println(lists1.size());第四种方式 分页查询Query q1=session.createQuery("from Student where chengji=?  and kecheng=:a ");        q1.setFirstResult(0);//从查询结果中的哪一行开始结算        q1.setMaxResults(8);//从查询结果中取出多少行结算        q1.setDouble(0, 100.0);        q1.setString("a", "高数");        List<Student> lists1=q1.list();        for(Student student:lists1){            System.out.println(student.getName());        }        System.out.println(lists1.size());

7 Hbc javabean的查询方式
Cri.add//后面添加约束条件(就像sql中where条件后的语句)
第一种方式(等值查询)

Criteria cri=session.createCriteria(Student.class);        cri.add(Restrictions.eq("kecheng", "高数"));//等值查询        List<Student> lists=cri.list();//查询结过、果被封装成javabean        System.out.println(lists.get(1).getName());

第二种方式(模糊查询)

Criteria cri=session.createCriteria(Student.class);cri.add(Restrictions.like("kecheng", "高%"));        List<Student> lists=cri.list();//查询结过果被封装成javabean        System.out.println(lists.size());        for(Student student:lists){            System.out.println(student.getName());        }

第三种方式 between

cri.add(Restrictions.between("id", 0, 10));

第四种方式 in

cri.add(Restrictions.in("kecheng", new String[]{"高数 ","java"}));

第五种方式 组合查询条件

方法1第五种方式 组合查询条件cri.add(Restrictions.like("name", "王%"));        cri.add(Restrictions.eq("kecheng", "高数"));方法2cri.add(Restrictions.and(Restrictions.like("name"," 王%"),Restrictions.eq("kecheng", "高数")));方法3 cri.add(Restrictions.or(Restrictions.like("name", "     王%"),Restrictions.eq("kecheng", "java")));//andor的区别:and满足所有条件的行,or每一个满足条件的  行集合        List<Student> lists=cri.list();//查询结过果被封装成javabean        System.out.println(lists.size());        for(Student student:lists){            System.out.println(student.getName());        }

7 <!--是否将运行期生成的SQL输出到日志以供调试-->
<property name="hibernate.show_sql">true</property>

8 hibernate的数据库连接池
8.1导入jar包(3个c3p0包)
8.2 在hibernate.cfg.xml中配置数据库连接池必要的配置

<!--****************** 【连接池配置】****************** -->        <!-- 配置连接驱动管理类 -->        <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionPro<!--是否将运行期生成的SQL输出到日志以供调试-->vider</property>        <!-- 配置连接池参数信息 -->        <!-- 连接池中数据库连接的最小数目 -->        <property name="hibernate.c3p0.min_size">2</property>        <!--连接池中数据库连接的最大数目? -->        <property name="hibernate.c3p0.max_size">4</property>        <!-- 获得连接的超时时间,如果超过这个时间,会抛出异常,单位毫秒 -->         <property name="hibernate.c3p0.timeout">5000</property>        <!-- 可以被缓存的PreparedStatement实例的最大数目。        缓存适量的PreparedStatement实例,能够大大提高Hibernate的性能。 -->        <property name="hibernate.c3p0.max_statements">10</property>        <!-- 在使数据库连接自动生效之前处于空闲状态的时间,以秒为单位 -->        <property name="hibernate.c3p0.idle_test_period">30000</property>        <!-- 当连接池里面的连接用完的时候,C3P0一下获取的新的连接数 -->         <property name="hibernate.c3p0.acquire_increment">2</property>

9 hibernate二级缓存(sessionFactory缓存,支持可插拔式的缓存,支持查询缓存)
9.1 导二级缓存需要的jar包(3个ehcache包)
9.2 在hibernate.cfg.xml文件中配置开启二级缓存的语句

<!--****************** 【二级缓存配置】****************** -->        <!-- 开启二级缓存 -->        <property name="hibernate.cache.use_second_level_cache">true</property>        <!-- 开启查询缓存 -->        <property name="hibernate.cache.use_query_cache">true</property>         <!-- 二级缓存的提供类 在hibernate4.0版本以后我们都是配置这个属性来指定二级缓存的提供类-->        <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>        <!-- 二级缓存配置文件的位置 -->        <property name="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</property>

9.3 在数据库中对象的映射xml文件中配置语句

<!-- 配置二级缓存开启的条件 -->        <cache usage="read-write"/> 

9.4 在调用sql语句的后面开启二级缓存

 Query q=session.createQuery("from User").setCacheable(true);     List<User> users=q.list();     System.out.println("一级缓存测试........................"+users.size());     session.close();     session=sf.openSession();     Query q2=session.createQuery("from User").setCacheable(true);//开启自己的二级缓存,从上面语句的二级缓存中查询值     List<User> users1=q2.list();     System.out.println("一级缓存测试2........................"+users1.size());     /*User user1=(User) session.get(User.class,1);     System.out.println(user1.getUsername());*/     session.close();

10 当hibernate通过id访问数据库对象的时候,先从session中查找,然后从二级缓存中查找,再从数据库中查找

0 0
原创粉丝点击