Hibernate基本使用随手

required里面的jar包,jpa包,日志包

hibernate在自行配制数据库表的时候,注意定义的方言要和对应的数据库版本一致

实体类的映射文件(ORM):(.hbm.xml)实体类和数据库表的映射以及字段之间的映射和主键的生成册略等
  hibernatemapping ---class (name table) ----property(name colum)/id(name colum---generator(class(native)))

核心配置文件,文件名hibernate.cfg.xml放在src下面,
        根标签configuration,内容写在sessionfactory中,

        数据库文件的property,name以及value;
        hibernate的基础信息的配置(sql显示和格式化,方言设定,自动创建表的ddl语言(update等));
        映射文集那的引入(mapping resource)

核心API:

Configuration:有configure()方法,加载src下的核心配置文件

SessionFactory:重点,使用configuration的对象创建buildSessionFactory对象。
    
    创建过程中,根据配置文件中的数据库配置,到数据库里面根据映射
    关系创建表,但是要在核心配置文件里面加上ddl配置一般值update
    但是创建表,此过程比较耗费资源,
    一般来说一个项目创建一个sessionFactory对象,实现方式,写一个工具类,使用静态代码块实行一次即可。建议一个项目创建一个sessionFactory对象


Session :重点:类似于jdbc中的connection,通过sessionFactory的openSession打开
    
    可以调用sesion里面的不同的方法,实现crud操作
    添加:save,saveOrUpdate,update
    修改:update
    删除:delete
    根据id查询:get,load
    数据库操作对象:createQuery(),createSQLQuery()
    条件查询:createCriteria

    session对象单线程对象
    所以不能其他共用,只能用自己的

Transaction:
    事务,通过session的beginTransaction()进行开启
    
    操作:提交commit

扫描二维码关注公众号,回复: 2297780 查看本文章

         回滚:rollback();

    事务的特性:acid:原子性(全部一体,要么都执行要么都不执行),
              一致性(前后数据一致),
             隔离性(数据之间不影响),
             持久性 (事务提交,数据库生效)


实体类(持久化类)编写的规则:

    实体类里面的属性要是私有的
    私有属性要使用公开的get读和set写方法进行操作
    要求实体类里面有一个唯一的属性作为唯一值,一般都是用id
    实体类里面的属性不适用基本数据类型,建议使用包装类(因为对应内容的初始化以及一些操作都会方便很多,特别是0和null的作用;除了int为Integer;char和Character其余的都是大写)


hibernate的主键生成策略:
    
    要求实体类重点的属性作为唯一值,主键可以不同的生成策略

    生成策略有很多值

    主要记住:native和uuid
    
    increment:增量为1
    identity:数据库支持自动增长:
    sequence:支持序列,mysql不支持
    native:根据所用的数据库,选择不同的值
    uuid:使用了UUID算法来生程标识符,自动生成一个唯一的32为的16进制字符串,作为
        主键,一般用于代理主键

    使用uuid生成策略,实体类中的id必须是一个String字符串类型


关于实体类的操作CRUD (核心概念:状态转换加上操作)
    对实体类的crud

    添加:session.save(xxxx);

          User user = new User();
            user.setUid(1);//设置id是没有效果的
          user.setUsername("zhangsan");
            user.setPassword("1234");
          user.setAddress("japan");
        session.save(user);


    

    根据id查询:session.get()   session.get(User.class,1);

    
    修改:(三部)session.Update()
        先根据id查询,然后再进行修改。
        User user = session.get(User.class,1);
            user.setUsername("懂法");//状态转换,将数据库的对象架设到了实体类中
            //先找到uid,根据uid进行修改
                session.update(user);

        //修改也可以定义类再放入参数,调用修改,但是,如果属性值没有设定的话
            //那么其余字段会变成空,所以一般先查再改

    删除:调用session.delete();
        //第一种方式,建议使用,先查再删除(将数据库的对象架空到后台进行删除然后同步到数据库)
        //        User user = session.get(User.class,1);
        //        session.delete(user);

        //第二种方法:向数据库传入参数进行删除
                User user = new User();
                   user.setUid(3);
                   session.delete(user);


重点:实体类对象的状态(概念)

    三种状态
    
    瞬时态:对象里面没有id值,对象和session没有关联。(一般都save做新添加的操作)

    游离态:对象里面有id值,对象和session有关联。(一般都是查出来的)

    托管态:对象里面有id值,对象和session没有关联。(比如通过传入参数含id的改删方式)


     
    常见的一个操作实体类的方法

    saveOrUpdate();//即可添加也可修改

    //实体类是瞬时状态的时候,该方法做的是添加操作
        User user = new User();
        user.setUsername("jack");
        user.setPassword("520");
        user.setAddress("朝鲜");

        session.saveOrUpdate(user);

    

    //实体类是托管态状态的时候,该方法做的是修改操作
        User user = new User();
        user.setUid(5);
        user.setUsername("jackson");
        user.setPassword("520");
        user.setAddress("阿尔巴尼亚");

        session.saveOrUpdate(user);

    //实体类是持久态状态的时候,该方法做的是修改
        User user = session.get(User.class,5);
        user.setUsername("jace");

        session.saveOrUpdate(user);
    


缓存:数据一般存在数据,数据库是文件系统,操作的时候一般会用流的方式,效率慢
    把数据存到内存中不需要使用流的方式,可以直接读取内存中的数据
    把数据放到内存中,提高读取的效率
    
hibernate的一级缓存
    hibernate框架提供很多优化的方式
    hibernate中的缓存就是一种优化方式
    
    hibernate的缓存分为:一级,二级。

    特点:
        hibernate的一级缓存是默认打开的,
        该一级缓存有一定的使用范围,是session的范围(session的创建到关闭)
        一级缓存中存取的数据必须是持久态的数据

    二级缓存已经不用的,用替代技术redis
    二级缓存打开需要打开,使用范围使整个项目,sessionFactory


    
    一级缓存的执行过程:先查询一级缓存,没有则查询数据库,返回持久态的数据
            将该持久态的数据放入到一级缓存中(存入的方式:非整个对象,而是将整个对象存进去,然后给定一个空间,取一个名字;判断的时候通过id值判断进行数据判断,将零散的值组成一个新的对象进行返回);在查询第二次,先查一级缓存,如果一级缓存中有相同的数据,直接在一级缓存取出;
    
    

一级缓存的特性:
    1.持久态会自动更新数据库。

    User user = session.get(User.class,4);
        user.setUsername("tanweiwei");
        //无需调用update,当commit之后自动更新数据到数据库
        tx.commit();

    该特性执行原理:
        创建了session之后会分为两个区
    
        一级缓存区:将查询出来的对象放入到缓存区

        快照区(副本):将查询出来的对象放入到对应快照区


        当修改了持久态的时候,会修改一级缓存区的内容,不会修改一级缓存的快照区的内容。

        最后提交事务的时候,将一级缓存区和快照区的内容进行比较,如果不同,那么会更新到数据库。

hibernate关于事务的操作:
    
    1。事务:事务是一组操作要么都成功

    事务的特性

    不考虑隔离性:产生:脏读,不可重复读,虚读

    
    设置事务的隔离级别,mysql默认的隔离级别:repeatable read

    

    hibernate的事务隔离级别:
        1表示read uncommited isolation
        2表示read comminted isolation
        
        4. repeatable read isolation
        8.Serializable isolation

        
    事务的规范写法:
        结构
        
        try{
          开启事务
          提交事务
        }cacth(){
          回滚事务
        }finally{
          关闭
        }

    SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;

        try {
            sessionFactory = HibernateUtils.getSessionFactory();
            session = sessionFactory.openSession();
            //开启
            tx= session.beginTransaction();

            User user = session.get(User.class,4);
            user.setUsername("he");
            session.update(user);

            //设定一个异常
            int a = 10/0;

            //提交
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            //回滚
            tx.rollback();
        } finally {
            session.close();
            sessionFactory.close();
        }

    hibernate也可以设置事务的隔离级别,在property中设定
    <property name="hibernate.connection.isolation">4</property>

hibernate绑定session。
    
    保证session的唯一性;

    1.session类似与jdbc的connection,之前使用线程的threadLocal

    2.框架帮助与本地线程绑定session,底层已经实现,按照结构配置即可

    3.获取本地线程session
      (1)在hibernate核心配置文件中配置
         <!--配置线程锁好的session-->
        <property name="hibernate.current_session_context_class">thread</property>

      (2)调用sessionFactory的方法得到
        //得到的是与本地线程绑定的session
        return sessionFactory.getCurrentSession();
    此时无需手工关闭session了因为会随着线程技术而关闭,如果关闭的话可能会有异常

额外的API
查询:
Query对象查询所有记录
    不需要sql,但是需要HQL(hibernate query language)与普通sql相似
    区别:普通的sql操作的是数据库的表和字段
          使用hql操作的是实体类和属性:

    查询所有的hql语句
    Query 实体类名
    
    使用:创建Query对象,调用query对象里面的方法得到结果

    Query query = session.createQuery("from User");//括号里面是hql(from 实体类名字)
            List<User> list = query.list();
            for (User user:list){
                System.out.println(user);
            }
          

Criteria对象
    也能进行查询,但是使用这个方法使用这个对象的时候,不需要写sql语句,直接调用方法实现。
    实习过程:
        创建对象
        调用方法得到结果
    
        Criteria criteria = session.createCriteria(User.class);
            List<User> list = criteria.list();
            for (User user:list){
                System.out.println(user);
            }

SQLQuery对象

    使用hibernate的时候,也可以调用底层sql实现

    过程与前两种相似

         SQLQuery sqlQuery = session.createSQLQuery("select * from t_user");
            //返回的时候,默认里面每部分是数组结构,要用数组接收
            List<Object[]> list = sqlQuery.list();
            for (Object[] objects:list){
                System.out.println(Arrays.toString(objects));
            }

        优化,返回的时候每部分是对象的方式
        SQLQuery sqlQuery = session.createSQLQuery("select * from t_user");
            //优化,返回的list中每部分是对象的形式
            sqlQuery.addEntity(User.class);
            List<User> list = sqlQuery.list();
            for (User user:list){
                System.out.println(user);
            }
    

表与表之间的关系

    一对多:分类和商品的关系,一个分类里面有多个商品,一个商品只能属于一个分类
        客户和联系人
        客户:与公司有业务往来的,一
        联系人:公司里面的员工,多

        公司和公司员工的关系

        通过外键建立关系。(建表的时候,建表原则)

    多对多:订单和商品,
        用户和角色
             
        多对多需要创建第三张表,对应关系,该表中至少有两个字段作为外键,分别指向两个表的主键。

    一对一:夫妻制


一对多的操作:
    映射配置:
        创建实体类:客户,联系人

        实体类之间互相表示
            在客户实体类里面表示多个联系人
                一个客户里面有多个联系人

    //在一个客户里面表示多个联系人,一个客户有多个联系人
    //hibernate要求使用集合表示多的数据,必须使用set集合
    private Set<LinkMan> setLinkMan = new HashSet<LinkMan>();
    public Set<LinkMan> getSetLinkMan() {
        return setLinkMan;
    }
    public void setSetLinkMan(Set<LinkMan> setLinkMan) {
        this.setLinkMan = setLinkMan;
    }


            在联系人实体类里面表示所属客户
                一个联系人只能属于一个客户

    private Customer customer;
    public Customer getCustomer() {
        return customer;
    }
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

            配置映射关系,一个实体类对应一个映射文件

                在客户文件中要表示所有联系人

 <!--表示所属联系人-->
       <set name="setLinkMan">
           <!--一对多建表,有外键
                hibernate机制,双向维护外键,都要配置外键
                column是外键名称可自定义
            -->
           <key column="clid">
           </key>
           <one-to-many class="cn.it.entity.LinkMan"></one-to-many>
       </set>

                在联系人映射文件中要表示所属的客户
       <!--表示联系人所属客户-->
       <many-to-one name="customer" class="cn.it.entity.Customer" column="clid"></many-to-one>
                
            创建核心配置文件,引入ORM映射文件
        
    级联操作:
        级联操做主要有:
            
        级联保存:添加一个客户,为这个客户添加多个联系人


      复杂方法:  //添加一个客户,为这个客户添加一个联系人
            //操作
            //1.创建客户和联系人
            Customer customer = new Customer();
            customer.setCustName("传智");
            customer.setCustLevel("vip");
            customer.setCustSource("网络");
            customer.setCustPhone("110");
            customer.setCustMobile("999");

            LinkMan linkMan = new LinkMan();
            linkMan.setLkm_name("lucy");
            linkMan.setLkm_gender("男");
            linkMan.setLkm_phone("911");

            //2.在客户表示联系人,在联系人白哦是客户

            //建立客户对象和联系人对象关系
            //把联系人对象放到客户对象的set里
            customer.getSetLinkMan().add(linkMan);
            //把客户对象放到联系人里面
            linkMan.setCustomer(customer);
            //保存到数据库
            session.save(customer);
            session.save(linkMan);

    简单方法:
        一般根据客户添加联系人,修改一下映射文件
客户映射文件中:set里面加上一个属性:cascade="save-update"
        创建客户和对象,只需要把联系人放到客户里面就可以了,最终只需要保存客户就可以了。
        //添加一个客户,为这个客户添加一个联系人
            //操作
            //1.创建客户和联系人
            Customer customer = new Customer();
            customer.setCustName("百度");
            customer.setCustLevel("普通客户");
            customer.setCustSource("网络");
            customer.setCustPhone("110");
            customer.setCustMobile("999");

            LinkMan linkMan = new LinkMan();
            linkMan.setLkm_name("小宏");
            linkMan.setLkm_gender("男");
            linkMan.setLkm_phone("911");

            //2.把联系人放到客户里面就ok
            customer.getSetLinkMan().add(linkMan);
            //3.保存到数据库
            session.save(customer);

        
        级联删除:
    
        删除客户,以及客户的联系人。

        1.在客户的映射文件中 set标签中配置cascde加上 ,delete

            先根据id查出再删除
        //1.根据id查询对象
            Customer customer = session.get(Customer.class,2);
            //2.调用方法删除
            session.delete(customer);
            执行的过程5步,先查客户再查联系人,再置空外键,再删除联系人,删除客户


        一对多的修改的操所:
        让联系人改客户

        利用一级缓存的同步更新,但是新能会变差(hibernate会有双向维护外键,修改两次外键,解决方案,让其中一方放弃外键维护,一般是非外键持有方,即一的一方)
        //1.根据id查出对应联系人,根据id查客户
            Customer baidu = session.get(Customer.class,2);
            LinkMan lucy = session.get(LinkMan.class,1);
            //2.设置持久态对象的值
            //把联系人放到客户里
            baidu.getSetLinkMan().add(lucy);
            //把客户放到联系人里面
            lucy.setCustomer(baidu);

inverse属性        优化:实现外键维护放弃,配置映射文件,在set上加上inverse属性,默认值为false,改成true,提高性能


多对多的操作:

    多对多映射配置
        
        用户和角色

        一。创建实体类:用户,角色,

        二。让两个实体类之间互相表示
            
          一个用户里表示所有角色set
    //一个用户有多个角色
    private Set<Role> setRole = new HashSet<Role>();
    public Set<Role> getSetRole() {
        return setRole;
    }
    public void setSetRole(Set<Role> setRole) {
        this.setRole = setRole;
    }

          一个角色里表示所哟有用户set
    //一个角色中有多个用户
    private Set<User> setUser = new HashSet<User>();
    public Set<User> getSetUser() {
        return setUser;
    }
    public void setSetUser(Set<User> setUser) {
        this.setUser = setUser;
    }


        三。配置映射文件关系
                  基本配置
          配置多对多关系
userxml:
    <!--table表示第三张表的名称-->
       <set name="setRole" table="user_role" >
           <!--key表示当前映射文件在第三张表外键名称-->
        <key column="userid"></key>
           <!--class:角色实体类全路径
                column:角色在第三张表外键的名称(双向维护)
           -->
           <many-to-many class="cn.it.manytomany.Role" column="roleid"></many-to-many>
       </set>

    
rolexml:

    <set name="setUser" table="user_role" >
            <key column="roleid"></key>
            <many-to-many class="cn.it.manytomany.User" column="userid"></many-to-many>
        </set>

        
                      
        四。核心配置文件引入映射


    多对多级联保存(用的不多)

        根据用户保存角色
        
        配置,cascade,代码实现即可

        User user1 = new User();
            user1.setUser_name("lucy");
            user1.setUser_password("123");

            User user2 = new User();
            user2.setUser_name("mary");
            user2.setUser_password("456");

            Role r1 = new Role();
            r1.setRole_name("总经理");
            r1.setRole_memo("总经理");

            Role r2 = new Role();
            r2.setRole_name("秘书");
            r2.setRole_memo("秘书");

            Role r3 = new Role();
            r3.setRole_name("保安");
            r3.setRole_memo("保安");

            //2.建立关系,把角色放到用户里面区
            //user1---r1/r2
            user1.getSetRole().add(r1);
            user1.getSetRole().add(r2);

            //user1---r2/r3
            user2.getSetRole().add(r2);
            user2.getSetRole().add(r3);

            //3.保存用户
            session.save(user1);
            session.save(user2);    


    多对多级联删除(了解)
       在set标签上面添加cascade的delete
       但是删除的时候,会影响其他的多对多


    多对多维护第三张表的关系
       1.通过第三章表维护关系
    
       2.让某个用户有某个角色
        根据id查询用户和角色

        把角色对象放到用户set

        //让lucy有经济人角色
            //查询lucy和经济人
            User lucy = session.get(User.class, 1);
            Role role = session.get(Role.class, 1);

            //把角色放到用户的set
            lucy.getSetRole().add(role);


       3.让某个用户没有某个角色
        根据id查询用户和角色

        从set集合里面把角色移除

        //让某用户没有角色
                //查询lucy和经济人
            User user = session.get(User.class, 2);
            Role role = session.get(Role.class, 3);

            //从用户里面把角色去掉
            user.getSetRole().remove(role);


hibernate查询的方式

    1.对象导航查询
        根据id查询出某个客户,再查询这个客户里面所有的联系人就可以通过对象
    2.OID查询
        根据id查询某一条记录,返回对象
    3.hql查询
        Query对象,写hql        
    4.QBC查询
        criteria对象
    5.本地sql查询
        SQLQuery普通sql查询


    

1.对象导航查询
        根据id查询出某个客户,再查询这个客户里面所有的联系人就可以通过对象(如一对多的查询)

        //查询cid为1的客户,再查询客户里里面所有联系人
            Customer customer = session.get(Customer.class,1);
            //再查询这个客户里面所有联系人
            //直接得到客户里面联系人的set集合
            Set<LinkMan> linkMEN = customer.getSetLinkMan();

            System.out.println(linkMEN.size());   


 
2.OID查询
    根据id查询某一条记录,返回对象
    Customer customer = session.get(Customer.class,1);
    

3.hql查询
    Query对象,写hql

        创建Query对象,写hql语句,调用query对象里面的方法得到结果
    
    常用的hql语句
    
    查询所有:from 实体类名称

        Query query = session.createQuery("from Customer");
            List<Customer> list = query.list();
            for (Customer customer:list){
                System.out.println(customer.getCid());
            }
        
        
    条件查询:from 实体类名 where 实体类属性名称=?and 实体类属性名称=?
          from 实体类名 where 实体类属性名称 like ?

        Query query = session.createQuery("from Customer NN where NN.cid=? and NN.custName=?");
            query.setParameter(0,1);
            query.setParameter(1,"传智");

            List<Customer> list = query.list();
            for (Customer customer:list){
                System.out.println(customer.getCid());
            }    

注意:hibernate 4.1之后对于HQL中查询参数的占位符做了改进,?改为?0,?1等      
        Query query = session.createQuery("from Customer NN where  NN.custName like ?0");
            query.setParameter(0,"%传%");

            List<Customer> list = query.list();
            for (Customer customer:list){
                System.out.println(customer.getCid());
            }   
    

    排序查询:from 实体类名 order by 实体类属性名称 asc/desc
       
       Query query = session.createQuery("from Customer order by cid desc");
            List<Customer> list = query.list();
            for (Customer customer:list){
                System.out.println(customer.getCid());
            }

    分页查询:
        在hql中不能使用limit,Query中封装了两个方法实现分页

        Query query = session.createQuery("from Customer ");
            //设置分页数据
            query.setFirstResult(0);//开始未知
            query.setMaxResults(3);//设置每页记录数
            
            List<Customer> list = query.list();
            for (Customer customer:list){
                System.out.println(customer.getCid());
            }


    投影查询:查询部分字段的值,就称投影查询
        select 实体类的属性名,实体类的属性名(不可以写*)from 实体类名
        Query query = session.createQuery("select cid, custName from Customer ");
            List<Object> list = query.list();
            for (Object object:list){
                System.out.println(object);
            }
       

    聚集函数使用:    
        count sum avg max min

       select count(*) from 实体类名

        Query query = session.createQuery("select count(*) from Customer ");
            //调用方法得到结果
            //query对象里面有方法,直接返回对象形式
            Object obj = query.uniqueResult();
            Long ll = (Long)obj;
            int couts = ll.intValue();
            System.out.println(obj);
            System.out.println(couts);
            
    
4.QBC查询
    criteria对象

    使用QBC的时候也有上查询:

    查询所有:
        Criteria criteria =session.createCriteria(Customer.class);
            List<Customer> list = criteria.list();
            for (Customer customer:list){
                System.out.println(customer.getCustName());
            }

    条件:
         Criteria criteria =session.createCriteria(Customer.class);
            //设置条件值
            criteria.add(Restrictions.eq("cid",1));
            criteria.add(Restrictions.eq("custName","传智"));
            List<Customer> list = criteria.list();
            for (Customer customer:list){
                System.out.println(customer.getCustName());
            }

     criteria.add(Restrictions.like("custName","%智%"));
       

    排序
    Criteria criteria =session.createCriteria(Customer.class);
            //设置排序规则
            criteria.addOrder(Order.desc("cid"));
            List<Customer> list = criteria.list();
            for (Customer customer:list){
                System.out.println(customer.getCustName());
            }

    分页:当前页减一乘以每页记录数
    Criteria criteria =session.createCriteria(Customer.class);
            //设置分页参数规则
            criteria.setFirstResult(0);//起始位置
            criteria.setMaxResults(3);
            List<Customer> list = criteria.list();
            for (Customer customer:list){
                System.out.println(customer.getCustName());
            }

    统计
        Criteria criteria =session.createCriteria(Customer.class);
            //设置参数规则
            criteria.setProjection(Projections.rowCount());
            Object obj = criteria.uniqueResult();
            System.out.println(obj);

    离线:可以不用session也可以创建Criteria
      
       DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);
            //最终执行时才需要session
            Criteria criteria = detachedCriteria.getExecutableCriteria(session);
            List<Customer> list = criteria.list();
            for (Customer customer:list){
                System.out.println(customer.getCustName());
            }


        使用框架的时候,要调用session实现功能;离线对象可以抽离出来在任意未知拼接,然后传入dao执行
    

5.本地sql查询
    SQLQuery普通sql查询    

    
HQL多表查询:    
        
        内
            内链接的写法:链接客户表和联系人
            from Customer c inner join c.setLinkMan

        Query query = session.createQuery("from Customer c inner join c.setLinkMan");
            List list= query.list();//list里面是数组的形式
            System.out.println(list.size());
            

        左外:list里是数组
        Query query = session.createQuery("from Customer c left outer join  c.setLinkMan");
            List list= query.list();
            System.out.println(list.size());

        右外

        迫切内链接:
              与内链接的底层都一样都是inner join;区别在于放回的list每部分是对象(HQL多了一个fetch而已)
        Query query = session.createQuery("from Customer c inner join fetch c.setLinkMan");
            List list= query.list();
            System.out.println(list.size());

        迫切左外链接:list里是对象
        Query query = session.createQuery("from Customer c left outer join fetch c.setLinkMan");
            List list= query.list();
            System.out.println(list.size());


hibernate里面检索的策略

    立即检索
        根据id,用get,一调用get马上发送语句查询数据库


    延迟检索
        根据id,用load,调用load方法不会马上发送语句查询数据,只有得到对象里面的值的时候才会发送语句去查询数据库。
        
        //延迟加载,不会马上zhi发送sql,返回对象里面只有id值
            //得到对象里面不是id的其他值才会发送语句
            Customer customer = session.load(Customer.class,1);
            System.out.println(customer.getCid());
            System.out.println(customer.getCustName());

        

        延迟的分类:
        类级别延迟:根据id查询返回的实体类对象,调用load不会马上发送sql
            

        关联级别的延迟:
            查某个客户,再查所有联系人
        Customer customer = session.get(Customer.class,1);
            //未发送语句,默认的优化方式
            Set<LinkMan> linkMEN = customer.getSetLinkMan();
            //发送语句
            System.out.println(linkMEN.size());

            修改方式:
            通过映射文件中配置;客户映射文件

            set  
                lazy
                    false 不延迟
                    true  延迟 默认
                    extra 极懒 已经淘汰(要啥给啥,不要不给)

                fetch 值一般都是select默认

批量抓取:
    查询所有客户,返回list集合,便利list集合,得到每个客户的所有联系人。
    通过批量抓取优化。

    //低性能,发送多条sql
    Criteria criteria =  session.createCriteria(Customer.class);
            List<Customer> list = criteria.list();
            for (Customer customer :list){
                System.out.println(customer.getCustName()+":"+customer.getCid());
                Set<LinkMan> setLinkMan = customer.getSetLinkMan();
                for (LinkMan linkMan:setLinkMan){
                    System.out.println(linkMan.getLkm_id()+":"+linkMan.getLkm_name());
                }
            }

    //优化,批量抓取
    在客户的set标签里: batch-size="整数值越大效率越高"
    减少语句量的发送
            


                

    

    

二级缓存用于管理对象,二级缓存实在应用程序级别的SessionFactory=======================

默认关闭的


    

        


 

猜你喜欢

转载自blog.csdn.net/qq_42755868/article/details/81143695