文章目录
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&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&characterEncoding=UTF-8&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&characterEncoding=UTF-8&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();
}
}