hibernate总结

  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", "高数"));
方法2
cri.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中查找,然后从二级缓存中查找,再从数据库中查找

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章