Hibernate框架2022年篇详解

Hibernate

主流ORM框架Object Relation Mapper对象映射,将面向对象映射成面向关系

如何使用

1、导入相关依赖

2、创建Hibernate配置文件

3、创建实体类

4、创建实体类-关系映射文件

5、调用Hibernate Api 完成操作

具体操作

1、创建Maven工程

2、导入依赖pom.xml

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.19</version>
</dependency>

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

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.10</version>
</dependency>

3、在resources创建配置文件hibernate.cfg.xml

核心配置:session-factory

SessionFactory:针对单个数据库映射经过编译的内存镜像文件,将数据库转换为一个java可以识别的镜像文件。

构建SessionFactory非常耗费资源,所以通常一个工程只需要创建一个SessionFactory。

<?xml version='1.0' encoding='gb2312'?>
<!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">111111</property>
      <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
      <property name="connection.url">jdbc:mysql://localhost:3306/lianxi?useUnicode=true&amp;characterEncoding=UTF-8</property>

<!--      C3P0-->
      <property name="hibernate.c3p0.acquire_increment">10</property>
      <property name="hibernate.c3p0.idle_test_period">10000</property>
      <property name="hibernate.c3p0.timeout">5000</property>
      <property name="hibernate.c3p0.max_size">30</property>
      <property name="hibernate.c3p0.min_size">5</property>
      <property name="hibernate.c3p0.max_statements">10</property>

<!--      数据库方言-->
      <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>

<!--      打印SQL-->
      <property name="show_sql">true</property>

<!--      格式化SQL-->
      <property name="format_sql">true</property>

<!--      自动生成数据表-->
      <property name="hibernate.hbm2ddl.auto">update</property>
  </session-factory>
</hibernate-configuration>

3、创建两个实体类

package com.syj.entity;

import lombok.Data;

import java.util.Set;

@Data
public class Customer {
    private Integer id;
    private String name;
    private Set<Orders> orders;
}
package com.syj.entity;

import lombok.Data;

@Data
public class Orders {
    private Integer id;
    private String name;
    private Customer customer;
}

4、创建实体关系映射文件

package com.syj.entity;

import lombok.Data;

@Data
public class People {
    private Integer id;
    private String name;
    private Double money;
}

5、实体关系映射文件注册到Hibernate的配置文件中。

<!--        注册实体关系映射文件-->
        <mapping resource="com/syj/entity/People.hbm.xml"></mapping>

6、使用HibernateApi 完成数据操作。

package com.syj.test;

import com.syj.entity.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class Test {
    public static void main(String[] args) {
        //创建    Configuration
        Configuration configuration = new Configuration().configure();

//        获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();

//        获取Session
        Session session = sessionFactory.openSession();
        People people = new People();
        people.setName("张三");
        people.setMoney(1000.0);
        session.save(people);
        session.beginTransaction().commit();
        session.close();
    }


}

7、pom.xml需要配置resource.

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
</build>

Hibernate级联操作

1、一对多关系

客户和订单:每个客户可以购买多个产品,生成多个订单,但是一个订单只能属于一个客户,所以客户是一,订单是多。

数据库的一方是主表,多的一方是从表,通过主外键关系来维护

package com.syj.entity;

import lombok.Data;

import java.util.Set;

@Data
public class Customer {
    private Integer id;
    private String name;
    private Set<Orders> orders;
}

package com.syj.entity;

import lombok.Data;

@Data
public class Orders {
    private Integer id;
    private String name;
    private Customer customer;
}

2、多对多关系

学生选课:一门课程可以被多个学生选择,一个学生可以选择多个课程,学生多 ,课程也是多。

数据库中的是通过两个一对多关系来维护的,学生和课程都是主表,额外增加一张中间表作为从表,两张主表和中间表都是一对多关系。

package com.syj.entity;

import lombok.Data;

import java.util.Set;

@Data
public class Account {
    private Integer id;
    private String name;
    private Set<Course> courses;
}
package com.syj.entity;

import lombok.Data;

import java.util.Set;

@Data
public class Course {
    private Integer id;
    private String name;
    private Set<Account> accounts;
}

Java和数据库对于这两种关系的体现两种不同的方式,Hibernate框架的作用就是将这两种方式进行转换和映射。

Hibernate实现一对多

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.syj.entity.Customer" table="customer">
        <id name="id" type="java.lang.Integer">
            <column name="id"></column>
            <generator class="identity"></generator>
        </id>

        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>

        <set name="orders" table="orders">
            <key column="cid"></key>
            <one-to-many class="com.syj.entity.Orders"></one-to-many>
        </set>
    </class>
</hibernate-mapping>
  • Set标签来配置实体类中的集合属性orsers

  • name 实体类属性名

  • table表明

  • key外键

  • one-to-many 与集合泛型的实体类对应

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <class name="com.syj.entity.Orders" table="orders">
            <id name="id" type="java.lang.Integer">
                <column name="id"></column>
                <generator class="identity"></generator>
            </id>
    
            <property name="name" type="java.lang.String">
                <column name="name"></column>
            </property>
    
            <many-to-one name="customer" class="com.syj.entity.Customer" column="cid"></many-to-one>
        </class>
    </hibernate-mapping>
    
  • many-to-one配置实体类对应的对象属性

  • name 属性名

  • class 属性对应的类

  • columm 外键

需要在Hibernate配置文件中进行注册

<!--        注册实体关系映射文件-->
        <mapping resource="com/syj/entity/Customer.hbm.xml"></mapping>
        <mapping resource="com/syj/entity/Orders.hbm.xml"></mapping>

一对多 Hibernate APl

package com.syj.test;


import com.syj.entity.Customer;
import com.syj.entity.Orders;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class Test2 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //  获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();

        //获取Session
        Session session = sessionFactory.openSession();
        //创建Customer对象
        Customer customer =  new Customer();
        customer.setName("张三");

        //创建Orders
        Orders orders = new Orders();
        orders.setName("订单1");

        //建立关联关系
        orders.setCustomer(customer);

        //保存
        session.save(customer);
        session.save(orders);

        //提交事务
        session.beginTransaction().commit();
        //关闭session
        session.close();

    }
}

多对多

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.syj.entity.Account" table="t_account">
        <id name="id" type="java.lang.Integer">
            <column name="id"></column>
            <generator class="identity"></generator>
        </id>

        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>

        <set name="courses" table="account_course">
            <key column="aid"></key>
            <many-to-many class="com.syj.entity.Course" column="cid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.syj.entity.Course" table="t_course">
        <id name="id" type="java.lang.Integer">
            <column name="id"></column>
            <generator class="identity"></generator>
        </id>

        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>

        <set name="accounts" table="account_course">
            <key column="cid"></key>
            <many-to-many class="com.syj.entity.Account" column="aid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

name 实体类对应的集合属性名

table中间表名

key外键

many-to-many 与集合泛型的实体类对应

column属性与中间表的外键字段名对应。

注册Hibernate配置文件中

<!--        注册实体关系映射文件-->
<mapping resource="com/syj/entity/Account.hbm.xml"></mapping>
<mapping resource="com/syj/entity/Course.hbm.xml"></mapping>

多对多 Hibernate APl

package com.syj.test;


import com.syj.entity.Account;
import com.syj.entity.Course;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

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

public class Test3 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //  获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取Session
        Session session = sessionFactory.openSession();

        //创建Course对象
        Course course = new Course();
        course.setName("Java");

        //创建Account对象
        Account account = new Account();
        account.setName("张三");

        Set<Course> courses = new HashSet<>();
        courses.add(course);

        account.setCourses(courses);
        session.save(course);
        session.save(account);

        session.beginTransaction().commit();
        session.close();
    }


}

Hibernate 延迟加载

延迟加载,懒加载,惰性加载

使用延迟加载可以提高程序的运行效率,Java程序与数据库的交互的频次越低,程序运行的效率就越高,所以我们应该尽量减少 Java程序与数据库的交互次数,Hibernate延迟加载就很好的做到了这一点。

客户和订单,当我们查询客户对象的时,因为有级联设置,所以会将对应的以订单信息一并查询出来,这样的话就需要发送两条SQL语句,分别去查询客户信息和订单信息。

延迟加载思路是:当我们查询客户的时候,如果没有访问订单数据,只发送一条 SQL 语句查询客户信息,如果需要访问 订单数据,则发送两条SQL。

延迟加载可以看做是一种优化的机制,根据具体的需要求,自动选择要执行的 SQL 语句数量。

一对多

package com.syj.entity;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import java.util.Set;

@Getter
@Setter
public class Customer {
    private Integer id;
    private String name;
    private Set<Orders> orders;

    @Override
    public String toString() {
        return "Customer{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
package com.syj.entity;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import java.util.Set;

@Getter
@Setter
public class Account {
    private Integer id;
    private String name;
    private Set<Course> courses;
}

查询 Customer,对orders 进行延迟加载设置,在Customer.hbm.xml进行设置,延迟加载默认开启。

<set name="orders" table="orders" lazy="true">
    <key column="cid"></key>
    <one-to-many class="com.syj.entity.Orders"></one-to-many>
</set>

2、查询Customer

一条SQL

package com.syj.test;

import com.syj.entity.Customer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class Test4 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //  获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取Session
        Session session = sessionFactory.openSession();

        Customer customer = session.get(Customer.class,1);
        System.out.println(customer);
        session.close();

    }
}

两条SQL

   package com.syj.test;

import com.syj.entity.Customer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class Test4 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //  获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取Session
        Session session = sessionFactory.openSession();
   Customer customer = session.get(Customer.class,1);
    System.out.println(customer.getOrders());
    session.close();

}
}

lazy除了可以设置true 和flase 之外还可以设置extra,extra是比true更加懒惰的一中加载方式,或者说更加智能的一中加载方式,通过列子看区别:

查询Customer对象,打印对象对应的orders集合的长度

<set name="orders" table="orders" lazy="extra">
    <key column="cid"></key>
    <one-to-many class="com.syj.entity.Orders"></one-to-many>
</set>
   package com.syj.test;

import com.syj.entity.Customer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class Test4 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //  获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取Session
        Session session = sessionFactory.openSession();
   Customer customer = session.get(Customer.class,1);
    System.out.println(customer.getOrders().size());
    session.close();

}
}

也可以通过Orders来设置Customer的延迟加载,orders.hbm.xml中进行设置

<many-to-one name="customer" class="com.syj.entity.Customer" column="cid" lazy="proxy"></many-to-one>
package com.syj.test;

import com.syj.entity.Customer;
import com.syj.entity.Orders;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class Test5 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //  获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取Session
        Session session = sessionFactory.openSession();

        Orders orders = session.get(Orders.class,1);
        System.out.println(orders.getCustomer());
        session.close();

    }
}

no-proxy:当前调用方法需要访问customer的成员变量时,发送SQL语句查询customer,否则不查询。

proxy:无论调用方法是否需要访问customer的成员变量,都会发送SQL语句查询customer。

多对多

查询Course,加载对应的Accont,默认延迟加载开启。

package com.syj.entity;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import java.util.Set;

@Getter
@Setter
public class Course {
    private Integer id;
    private String name;
    private Set<Account> accounts;

    @Override
    public String toString() {
        return "Course{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
package com.syj.entity;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import java.util.Set;

@Getter
@Setter
public class Account {
    private Integer id;
    private String name;
    private Set<Course> courses;

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
<set name="accounts" table="account_course" lazy="true">
    <key column="cid"></key>
    <many-to-many class="com.syj.entity.Account" column="aid"></many-to-many>
</set>
package com.syj.test;

import com.syj.entity.Course;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class Test6 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //  获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取Session
        Session session = sessionFactory.openSession();

        Course course = session.get(Course.class,5);
        System.out.println(course);
         System.out.println(course.getAccounts());
        session.close();
    }
}

Hibernate 配置文件

  • Hibernate .xml
  • hbm.xml

Hibernate.xml详情信息

Hibernate .xml配置Hibernate 的全局环境

<?xml version='1.0'?>
<!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">111111</property>
      <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
      <property name="connection.url">jdbc:mysql://localhost:3306/lianxi?useSSL=false&amp;characterEncoding=UTF-8&amp;serverTimezone=UTC</property>

<!--      C3P0-->
      <property name="hibernate.c3p0.acquire_increment">10</property>
      <property name="hibernate.c3p0.idle_test_period">10000</property>
      <property name="hibernate.c3p0.timeout">5000</property>
      <property name="hibernate.c3p0.max_size">30</property>
      <property name="hibernate.c3p0.min_size">5</property>
      <property name="hibernate.c3p0.max_statements">10</property>

<!--      数据库方言-->
      <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>

<!--      打印SQL-->
      <property name="show_sql">true</property>

<!--      格式化SQL-->
      <property name="format_sql">true</property>

<!--      自动生成数据表-->
      <property name="hibernate.hbm2ddl.auto">update</property>

<!--        注册实体关系映射文件-->
        <mapping resource="com/syj/entity/People.hbm.xml"></mapping>
        <mapping resource="com/syj/entity/Customer.hbm.xml"></mapping>
        <mapping resource="com/syj/entity/Orders.hbm.xml"></mapping>
        <mapping resource="com/syj/entity/Account.hbm.xml"></mapping>
        <mapping resource="com/syj/entity/Course.hbm.xml"></mapping>
  </session-factory>
</hibernate-configuration>

1、数据库的基本信息

  <property name="connection.username">root</property>
      <property name="connection.password">111111</property>
      <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
      <property name="connection.url">jdbc:mysql://localhost:3306/lianxi?useSSL=false&amp;characterEncoding=UTF-8&amp;serverTimezone=UTC</property>

2、集成C3P0,设置数据库连接池信息

      <property name="hibernate.c3p0.acquire_increment">10</property>
      <property name="hibernate.c3p0.idle_test_period">10000</property>
      <property name="hibernate.c3p0.timeout">5000</property>
      <property name="hibernate.c3p0.max_size">30</property>
      <property name="hibernate.c3p0.min_size">5</property>
      <property name="hibernate.c3p0.max_statements">10</property>

3、Hibernate 的基本信息

<!--      数据库方言-->
      <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>

<!--      打印SQL-->
      <property name="show_sql">true</property>

<!--      格式化SQL-->
      <property name="format_sql">true</property>

<!--      自动生成数据表-->
      <property name="hibernate.hbm2ddl.auto">update</property>
  • ubdate:动态创作表,如果表存在,侧直接使用,如果表不存在,则创建。

  • create:无论表是否存在,都会重新创建。

  • create-drop:初始化创作表,程序结束时删除表

  • validate:校验实体关系映射文件和数据表是否对应,不能对应直接报错

4、注册实体关系映射文件

<!--        注册实体关系映射文件-->
        <mapping resource="com/syj/entity/People.hbm.xml"></mapping>
        <mapping resource="com/syj/entity/Customer.hbm.xml"></mapping>
        <mapping resource="com/syj/entity/Orders.hbm.xml"></mapping>
        <mapping resource="com/syj/entity/Account.hbm.xml"></mapping>
        <mapping resource="com/syj/entity/Course.hbm.xml"></mapping>

实体关系映射文件详情信息

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.syj.entity.Account" table="t_account">
        <id name="id" type="java.lang.Integer">
            <column name="id"></column>
            <generator class="identity"></generator>
        </id>

        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>

        <set name="courses" table="account_course">
            <key column="aid"></key>
            <many-to-many class="com.syj.entity.Course" column="cid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

属性

  • package:给class节点对应的实体类统一设置包名,此处设置包名,class的name属性就可以省略包名

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping package="com.syj.entity">
        <class name="Account" table="t_account">
            <id name="id" type="java.lang.Integer">
                <column name="id"></column>
                <generator class="identity"></generator>
            </id>
    
            <property name="name" type="java.lang.String">
                <column name="name"></column>
            </property>
    
            <set name="courses" table="account_course">
                <key column="aid"></key>
                <many-to-many class="com.syj.entity.Course" column="cid"></many-to-many>
            </set>
        </class>
    </hibernate-mapping>
    
  • schema:数据库schema的名称

  • catalog:数据库catalog的名称

  • default-cascade:默认的级联关系,默认为none

  • default-access:Hibernate用来访问属性的策略

  • default-lazy:指定了未明确注明lazy属性的java属性和集合类,Hibernate会采用什么样的加载风格默认为true

  • auto-import:指定我们是否可以在查询语句中使用非去全名,默认为true,如果项目中有同名的持久化类,最好在这两个类的对应映射文件中配置为flase。

class属性

  • name:实体类名
  • table:数据表名
  • schema:数据库schema的名称,会覆盖Hibernate-mapping的schema
  • catalog:数据库catalog的名称,会覆盖Hibernate-mapping的catalog
  • proxy:指定一个接口,在延迟加载时作为代理使用
  • dynamic-update:动态更新
  • dynamic-install:动态添加
  • where:查询时给SQL添加where条件

id属性

  • name:实体类属性名
  • type:实体类属性数据类型

此处可以设置两种类型的数据:Java数据类型或者Hibernate 映射类型。

实体类的属性数据类型必须与数据表对应的字段数据类型一致

int 对应 int,String对应varchar

如何进行映射?

Java数据类型映射到Hibernate 映射类型,再由Hibernate 映射类型映射到SQL数据类型

Java------->Hibernate --------->SQL

  • column:数据库的主键字段名

  • generator:主键生成策略

    1、hilo算法

    2、increment:Hibernate 自增

    3、identity:数据库自增

    4、native:本地策略,根据底层数据库自动选择主键的生成策略

    5、uuid:hex算法

    6、select 算法

property属性

  • name:实体类的属性名
  • column:数据表的字段名
  • type:数据类型
  • update:该字段是否可以修改,默认为true
  • insert:该字段是否可以添加,默认为true
  • lazy:延迟加载策略

实体关系映射文件属性

1、inverse

2、customer 和Orders 是一对多关系,一个customer 对应多个Orders ,实体类中用一个set集合来表示对应的orders.

package com.syj.entity;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import java.util.Set;

@Getter
@Setter
public class Customer {
    private Integer id;
    private String name;
    private Set<Orders> orders;

    @Override
    public String toString() {
        return "Customer{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

3、customer .hbm.xml:中使用set标签来配置映射关系。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.syj.entity.Customer" table="customer">
        <id name="id" type="java.lang.Integer">
            <column name="id"></column>
            <generator class="identity"></generator>
        </id>

        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>

        <set name="orders" table="orders" lazy="true">
            <key column="cid"></key>
            <one-to-many class="com.syj.entity.Orders"></one-to-many>
        </set>
    </class>
</hibernate-mapping>
package com.syj.entity;

import lombok.Data;

@Data
public class Orders {
    private Integer id;
    private String name;
    private Customer customer;
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.syj.entity.Orders" table="orders">
        <id name="id" type="java.lang.Integer">
            <column name="id"></column>
            <generator class="identity"></generator>
        </id>

        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>

        <many-to-one name="customer" class="com.syj.entity.Customer" column="cid" lazy="proxy"></many-to-one>
    </class>
</hibernate-mapping>

inverse:属性来设置是否将维护权交给对方,默认为false不交出维护权,双方都在维护,将他设置为true,表示customer放弃维护。

cascade:用来设置级联操作

Hibernate HQL

HQL: Hibernate Query Language, 是Hibernate 框架提供的一种查询机制,它和SQL类似,不同的是HQL是面向对象的查询语句,让开发者能够以面向对象的思想来编写查询语句,对Java编程是一种好友好的方式。

HQL不能直接参与数据库的交互,中间层语言。

Java–>HQL–>Hibernate —>SQL—>DB

HQL只能完成查询、修改、删除,新增是无法操作的。

1、查询对象

查询表中所有数据,自动完成对象的封装,返回List集合

HQL进行查询,from关键字后面不能写表名,必须写表对应的实体类名。

package com.syj.test;

import com.syj.entity.Course;
import com.syj.entity.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;

import java.util.List;

public class Test7 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取Session
        Session session = sessionFactory.openSession();

        String hql = "from People";
        Query query = session.createQuery(hql);
        List<People> list  = query.list();
        for (People people : list){
            System.out.println(people);
        }
        session.close();
    }
}

2、分页查询

HQL分页查询可以通过调用query的方法 来完成。

1、setFirstResult()设置起始下标

2、setMaxResult()设置截取长度

package com.syj.test;

import com.syj.entity.Course;
import com.syj.entity.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;

import java.util.List;

public class Test7 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取Session
        Session session = sessionFactory.openSession();
        
        String  hql = "from People";
        Query query = session.createQuery(hql);
        query.setFirstResult(1);
        query.setMaxResults(3);
        List<People> list  = query.list();
        for (People people : list){
            System.out.println(people);
        }
        session.close();
    }
}

3、where条件查询

HQL 直接追加 where关键字作为查询条件,与SQL没有区别。

package com.syj.test;

import com.syj.entity.Course;
import com.syj.entity.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;

import java.util.List;

public class Test7 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取Session
        Session session = sessionFactory.openSession();

        String  hql = "from People where id = 3";
        Query query = session.createQuery(hql);
        People people = (People)query.list().get(0);
        System.out.println(people);


        session.close();
    }
}

query.list()返回一个集合,此时集合中只有一个对象,通过下标0取出该对象

如果查出from People where id = 0没有的话

String  hql = "from People where id = 0";
Query query = session.createQuery(hql);
People people = (People)query.list().stream().unordered();
System.out.println(people);

不会抛异常

4、模糊查询

查询名称包含“三”的所有记录,

package com.syj.test;

import com.syj.entity.Course;
import com.syj.entity.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;

import java.util.List;

public class Test7 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取Session
        Session session = sessionFactory.openSession();

        String  hql = "from People where name like '%七%'";
        Query query = session.createQuery(hql);
        List<People> list  = query.list();
        for (People people : list){
            System.out.println(people);
        }
        session.close();
    }
}

5、order by

按照id进行排序

package com.syj.test;

import com.syj.entity.Course;
import com.syj.entity.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;

import java.util.List;

public class Test7 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取Session
        Session session = sessionFactory.openSession();

        String  hql = "from People order by id desc";
        Query query = session.createQuery(hql);
        List<People> list  = query.list();
        for (People people : list){
            System.out.println(people);
        }
        session.close();
    }
}

asc升序排列,desc降序排列

6、查询实体对象的属性

package com.syj.test;

import com.syj.entity.Course;
import com.syj.entity.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;

import java.util.List;

public class Test7 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取Session
        Session session = sessionFactory.openSession();

        String  hql = "select name from  People where id = 1";
        Query query = session.createQuery(hql);
        String name = (String)query.uniqueResult();
        System.out.println(name);
        session.close();
    }
}

7、占位符

package com.syj.test;

import com.syj.entity.Course;
import com.syj.entity.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;

import java.util.List;

public class Test7 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取Session
        Session session = sessionFactory.openSession();

        String  hql = "from People where name = :name";
        Query query = session.createQuery(hql);
        query.setString("name","张三");
        List<People> list = query.list();
        for (People people : list){
            System.out.println(people);
        }

        session.close();
    }
}

8、级联查询

package com.syj.test;

import com.syj.entity.Course;
import com.syj.entity.Customer;
import com.syj.entity.Orders;
import com.syj.entity.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;

import java.util.List;

public class Test7 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取Session
        Session session = sessionFactory.openSession();


        String  hql = "from Customer where name = :name";
        Query query = session.createQuery(hql);
        query.setString("name","张三");
        Customer customer = (Customer)query.uniqueResult();
        String hql2 = "from Orders where customer = :customer";
        Query query2 = session.createQuery(hql2);
        query2.setEntity("customer",customer);
        List<Orders> list = query2.list();
        for (Orders orders : list){
            System.out.println(orders);
        }

        session.close();
    }
}
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
3.6.10.Final 2012-02-09 3.6.9.Final 2011-12-15 3.6.8.Final 2011-10-27 3.6.7.Final 2011-08-17 3.6.6.Final 2011-07-21 3.6.5.Final 2011-06-09 3.6.4.Final 2011-05-05 3.6.3.Final 2011-04-06 3.6.2.Final 2011-03-10 3.6.1.Final 2011-02-03 3.6.0.Final 2010-10-14 3.6.0.CR2 2010-09-29 3.6.0.CR1 2010-09-16 3.5.6-Final 2010-09-15 3.6.0.Beta4 2010-09-02 3.5.5-Final 2010-08-18 3.6.0.Beta3 2010-08-18 3.6.0.Beta2 2010-08-04 3.5.4-Final 2010-07-22 3.6.0.Beta1 2010-07-21 3.5.3-Final 2010-06-17 3.5.2-Final 2010-05-14 3.5.1-Final 2010-04-15 3.5.0-Final 2010-03-31 3.5.0-CR-2 2010-02-25 3.5.0-CR-1 2010-02-10 3.5.0-Beta-4 2010-01-29 3.5.0-Beta-3 2010-01-14 3.5.0-Beta-2 2009-11-03 3.5.0.Beta-1 2009-08-21 3.3.2.GA 2009-06-24 3.2.7.ga 2009-06-03 3.3.1.GA 2008-09-11 3.3.0.SP1 2008-08-20 3.3.0.GA 2008-08-15 3.3.0.cr2 2008-08-01 3.3.0.cr1 2008-04-29 3.2.6.ga 2008-02-07 3.2.5.ga 2007-07-31 3.2.4.sp1 2007-05-18 3.2.4.ga 2007-05-09 3.2.3.ga 2007-04-02 3.2.2.ga 2007-01-24 3.2.1.ga 2006-11-17 3.2.0.ga 2006-10-16 3.2.0.cr5 2006-10-05 3.2.0.cr4 2006-08-25 3.2.0.cr3 2006-07-06 3.2 cr2 2006-05-06 3.2 cr1 2006-03-27 3.1.3 2006-03-20 3.2 alpha2 2006-03-16 3.2 alpha1 2006-03-01 3.1.2 2006-01-28 3.1.1 2006-01-18 3.1 2005-12-12 3.1 rc1 2005-12-12 3.1 rc3 2005-11-18 3.1 rc2 2005-10-17 3.1 beta 3 2005-09-13 3.1 beta2 2005-08-16 3.1 beta1 2005-07-21 3.1 alpha1 2005-06-24 3.0.5 2005-05-25 3.0.4 2005-05-23 3.0.3 2005-05-08 3.0.2 2005-04-27 3.0.1 2005-04-18 3.0 final 2005-03-31 3.0 rc 1 2005-02-28 3.0 beta 4 2005-02-11 3.0 beta 3 2005-01-30 3.0 beta 2 2005-01-24 3.0 beta 1 2004-12-20 3.0 alpha 2004-08-23

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SuperProgMan.SYJ

你的鼓励将是我创作更大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值