hibernate

Posted jentary

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hibernate相关的知识,希望对你有一定的参考价值。

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.1.8.Final</version>
</dependency>

<!-- for JPA, use hibernate-entitymanager instead of hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.1.8.Final</version>
</dependency>



<!-- mysql驱动包依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
<!-- alibaba数据源依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.11</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.26</version>
</dependency>

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
    
      <property name="connection.username">root</property>
      <property name="connection.password">root</property>
      <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
      <property name="connection.url">jdbc:mysql://localhost:3306/test</property>
      
      <property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
      <!-- 控制台打印 -->
      <property name="show_sql">true</property>
    
      <property name="format_sql">true</property>
      <!-- 生成表的策略 -->
      <property name="hbm2ddl.auto">update</property>
      
      <!-- 设置数据库事务的隔离级别  2读已提交,mysql默认的事务隔离级别默认是可重复读,oracle 默认是2 -->
      <property name="hibernate.connection.isolation">2</property>
      
      <!-- 以下两项对mysql无效  对oracle有效 -->
      <!-- 设置jdbc的statement  读取数据的时候每次从数据库中取出的记录条数 -->
      <property name="hibernate.jdbc.fetch_size">100</property>
      <!-- 批量操作的时候批次大小 -->
      <property name="jdbc.batch_size">30</property>
      
      <!-- <mapping resource="com/model/User.hbm.xml"/>
      <mapping resource="com/model/Customer.hbm.xml"/>
      <mapping resource="com/model/Orders.hbm.xml"/> -->
      
      <!-- <mapping resource="com/one2one/Manager.hbm.xml"/>
      <mapping resource="com/one2one/Department.hbm.xml"/> -->
      
      <!-- <mapping resource="com/many2many/Role.hbm.xml"/>
      <mapping resource="com/many2many/Menu.hbm.xml"/> -->
      
      <!-- 注解 -->
      <mapping class="com.annotation.Department"/>
      <mapping class="com.annotation.People"/>
    </session-factory>
</hibernate-configuration>
package com.test;


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.sql.Blob;
import java.util.Date;

import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.junit.Before;

import com.model.User;

/**
 * hibernate  对象的状态
 * 1持久化      在session缓存中       持久化对象id不能修改    在persist()之前有ID则不会执行  将会抛出异常    save()之前不会执行,不会抛出异常
 * 2临时    不在session缓存中
 * 3游离
 * 4删除
 * load不使用该对象不会执行sql,会返回一个代理对象,延迟加载 ,若数据表中没有数据使用代理对象时,会抛异常        get会立即加载对象
 * load 可能会抛出lazyInitiaLizationException,关闭session后调用该代理对象
 * 
 * update   跟新持久化对象  不需要显示调用  session.update    更新游离对象时显示调用 session.update,把游离对象编程持久对象
 * 
 * 在session中不能有两个 OID一样的对象也就是数据库中ID一样的两条数据
 * 
 * session.evict   把对象从缓存中移除
 * 
 * Hibernate.dowork  里调用jdbc里的  connection调用存储过程  
 * 
 * hibernate 把持久化类分为两种
 * 1  值类型 没有OID不能单独持久化   生命周期跟随持久化类
 * 2  entity 实体类型
 * 
 * worker对象里有变量  pay(值类型)对象
 * 
 * 类级别的检索策略   <class name="com.one2one.Department" table="DEPARTMENT" lazy="true">
 * 1立即检索lazy="false"
 * 2延迟检索  在使用具体的属性   除了ID外 
 * 
 * 检索  只对load方法有效
 * 
 * 一对多 和多对多 的检索策略   默认true    用到多的时候才加载
 * lazy = extra    增强的延迟检索,  会尽可能延迟集合初始化的时机
 * <set name="orders" table="ORDERS" inverse="true" order-by="ID desc" lazy="true">
 * 
 * 
 * set元素 的batch-size 属性:设定一次初始化set集合的数量  批量查询集合的个数
 * 
 * set 集合的fetch属性   1  默认值为 select   正常方式初始化set     取值为subselect  通过子查询的方式查询所有set集合 会覆盖batch-size 
 * 
 * Hibernate.initialize(对象);  初始化的时候强制调用
 * @author Administrator
 *
 */
public class Test {
    
    
    private static SessionFactory sessionFactory;

    @Before
    public void setUp() throws Exception {
        System.out.println("test");
        
        // A SessionFactory is set up once for an application!
        final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
                .configure("hibernate.cfg.xml") // configures settings from hibernate.cfg.xml
                .build();
        try {
            sessionFactory = new MetadataSources( registry ).buildMetadata().buildSessionFactory();
        }
        catch (Exception e) {
            // The registry would be destroyed by the SessionFactory, but we had trouble building the SessionFactory
            // so destroy it manually.
            StandardServiceRegistryBuilder.destroy( registry );
        }
        
        
    }

    @org.junit.Test
    public void test() throws Exception {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        User user = new User();
        //user.setId("11111");
        user.setDate(new Date());
        user.setName("张三");
        /*InputStream stream = new FileInputStream("");
        Blob image = Hibernate.getLobCreator(session).createBlob(stream, stream.available());*/
        
        
        session.save(user);
        //事务提交之前会调用session的flush同步数据库和缓存(一级缓存)
        //执行hql  或qbc查询会先进行flush
        //若ID是由数据库生成的  调用save  会立即执行insert
        //session.refresh(user);//强制执行一条select  保证把数据最新的数据刷新到对象缓存中
        //clear清理缓存
        session.getTransaction().commit();
        session.close();


        
    }

}
//先插入主表  再插入从表    否则效率低   会多出多条update语句(因为外键不知道  所以先插入null  插入主表后才知道外键)
        //
        Orders orders = session.get(Orders.class, 1);
        
        //使用该对象时  才会去查询    (延迟加载)
        Customer customer = orders.getCustomer();
        
        //先删从表再删主表
        
        //在hibernate中通过  inverse属性来决定是由双向关联的哪一方来维护表与表之间的关系
        //inverse = false 由主动方 ,inverse=true由被动方   在没有设置inverse = true的情况下  父子两边都维护
        //在1-n关系中,将n方设为主控方将有助于性能改善
@Test
    public void test(){
        //懒加载异常
        //HQL
        //按索引绑定参数
        //Query q = session.createQuery("from Role where name like ?");
        //q.setString(0, "%aaa%");
        //按名称绑定参数
        Query q = session.createQuery("from Role where name like :myname");
        //方法链式
        q.setString("myname", "张三");
        int pageNo = 3;
        int pageSize = 5;
        //分页查询
        List<Role> roles = q.setFirstResult((pageNo-1)*pageSize).setMaxResults(pageSize).list();
        System.out.println(roles.size());
        
        //命名查询  和Mybatis类似
        /*<!-- <![CDATE[]]> -->
        <!-- Query q = session.getNamedQuery("selectAll") -->
        <!-- <query name="selectAll">FROM Role where name = :name</query> -->*/
        
        //投影查询加select
        /*String hql = "select id,name from Role";
        Query q1 =  session.createQuery(hql);
        List<Object[]> result =q1.list() ;*/
        
        //返回对象  必须有Role(id,name)构造方法
        /*String hql2 = "select new Role(id,name) from Role";
        Query q2 =  session.createQuery(hql2);
        List<Role> result2 =q2.list() ;*/
        
        //select distinct d from Role r left  join fetch Menu
        //fetch  会把子集合都初始化   不用再一条条的查   一般都用fetch
        
        //链接查询  一对多  默认返回对象数组类型    根据配置文件决定多的集合的初始化
        /*String hql3 = "select distinct d from Role r left  join Menu";
        Query q3 =  session.createQuery(hql3);
        List<Role> result2 =q3.list() ;*/
        
        //QBC
        //---------------Criteria 
        Criteria criteria = session.createCriteria(Role.class);
        criteria.add(Restrictions.eq("name", "张三"));
        Role role = (Role) criteria.uniqueResult();
        
        //本地SQL
        
        
    }
//jdbc原生的批量操作是最快的
        
        session.doWork(new Work() {
            
            public void execute(Connection connection) throws SQLException {
                
            }
        });
        

 

一对一

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-7-12 21:07:30 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.one2one.Manager" table="MANAGER">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
       <!--  <one-to-one name="department" class="com.one2one.Department"></one-to-one> -->
       <!-- property-ref="manager" 以manager 的ID关联   如果不写而   是 以Department的ID管理-->
        <!-- 查manager 的时候  会把 department也查出来,  (没有外键的一方) 没有延迟加载-->
        <one-to-one name="department" class="com.one2one.Department" property-ref="manager"></one-to-one>
       
    </class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-7-12 21:07:30 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.one2one.Department" table="DEPARTMENT">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <!-- <one-to-one name="manager" class="com.one2one.Manager"></one-to-one> -->
        
        <!-- 使用many-to-one 的方式映射1对1关系     约束外键唯一 -->
        <!-- 一对一的外键  不能两端都有外键   容易混乱 -->
        <many-to-one name="manager" class="com.one2one.Manager">
          <column name="MAR_ID" unique="true"></column>
        
        </many-to-one>
    </class>
</hibernate-mapping>
package com.one2one;

public class Manager {
    
    private Integer id;
    
    private String name;
    
    private Department department;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }
    
    

}
package com.one2one;

public class Department {
    
    
    private Integer id;
    
    private String name;
    
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Manager getManager() {
        return manager;
    }

    public void setManager(Manager manager) {
        this.manager = manager;
    }

    private Manager manager;
    
    

}

一对多

package com.model;

import java.util.HashSet;
import java.util.Set;


public class Customer {

    private Integer id;
    
    private String name;
    
    private Set<Orders> orders = new HashSet<Orders>();
    

    public Integer getId() {
        return id;
    }


    public void setId(Integer id) {
        this.id = id;
    }


    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }


    public Set<Orders> getOrders() {
        return orders;
    }


    public void setOrders(Set<Orders> orders) {
        this.orders = orders;
    }


    
    
    
    
}
package com.model;


public class Orders {
    
    private Integer id;
    
    private String title;
    
    private String bianhao;
    
    private Customer customer;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getBianhao() {
        return bianhao;
    }

    public void setBianhao(String bianhao) {
        this.bianhao = bianhao;
    }

    public Customer getCustomer() {
        return customer;
    }

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

}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-7-6 21:40:00 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.model.Customer" table="CUSTOMER">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        
        
        <!-- <set name="orders" table="ORDERS" inverse="true" cascade="delete"> -->
        <!-- 设置级联删除 ,删除1的一端会把多的删除 cascade="delete"            inverse="true" 由谁维护关联关系-->
        <!-- order by  里放的是列名 -->
        <set name="orders" table="ORDERS" inverse="true" order-by="ID desc" lazy="true">
           <key column="CUSTOMER_ID"></key>
           <one-to-many class="com.model.Orders"/>
        </set>
        
        
    </class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-7-6 21:40:00 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.model.Orders" table="ORDERS">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="title" type="java.lang.String">
            <column name="TITLE" />
        </property>
        <property name="bianhao" type="java.lang.String">
            <column name="BIANHAO" />
        </property>
        <many-to-one name="customer" class="com.model.Customer">
            <column name="CUSTOMER_ID" />
        </many-to-one>
    </class>
</hibernate-mapping>

多对多

package com.many2many;

public class Menu {
    
    private Integer id;
    
    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    

}
package com.many2many;

import java.util.HashSet;
import java.util.Set;

public class Role {

    private Integer id;
    
    private String name;
    
    
    private Set<Menu> menus = new HashSet<Menu>();

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<Menu> getMenus() {
        return menus;
    }

    public void setMenus(Set<Menu> menus) {
        this.menus = menus;
    }
    
    
    
    
    
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-7-12 22:01:55 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.many2many.Menu" table="MENU">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        
        
        
        
    </class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-7-12 22:01:55 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.many2many.Role" table="ROLE">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        
        <!--单项多对多 中间表     双向多对多   都定义set  中间表必须相同   必须加inverse="true"   由哪一方维护关联关系  -->
        <set name="menus" table="ROLE_MENU">
           <key>
              <!-- 当前表的主键 --> 
              <column name="R_ID"></column>
           </key>
           <many-to-many class="com.many2many.Menu" column="M_ID"></many-to-many>
        </set>
        
    </class>
    <!-- <![CDATE[]]> -->
    <!-- Query q = session.getNamedQuery("selectAll") -->
    <!-- <query name="selectAll">FROM Role where name = :name</query> -->
    
    
</hibernate-mapping>

 
































以上是关于hibernate的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate的HQL多表查询

使用反射在外部JAR / CLASS上调用包含Hibernate事务的方法(Java EE)

Hibernate CriteriaQuery where - ManyToOne 字段

Hibernate + MySQL:如何为数据库和表设置编码 utf-8

hibernate在使用getCurrentSession时提示no session found for current thread

Java类型相互转换byte[]类型,blob类型