Hibernate 快速入门

原视频内容以及资料来自 b 站:https://www.bilibili.com/medialist/play/ml1025729445/p1
hibernate 在 idea 中文件快速生成博客:https://blog.csdn.net/qq_34197553/article/details/77718925

具体操作

创建 Maven 工程,pom.xml

 <dependencies>

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

        <!--jdbc-->

        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!--hibernate-->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.4.15.Final</version>
        </dependency>

    </dependencies>

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


hibernate.cfg.xml
核心配置:session-factory
SessionFactory:针对单个数据库映射经过编译的内存镜像文件,将数据库转换为一个 Java 可以识别的。
构建 SessionFactory 非常小号资源,所以通常一个工程只需要创建一个 SessionFactory。

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <!--核心配置,配置文件标签的-->
    <session-factory>
        <!--配置数据库的连接信息-->
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>

        <property name="connection.url">jdbc:mysql://localhost:3306/jt_db</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>


        <!--连接池 C3P0-->
        <property name="hibernate.c3p0.acquire_increment">10</property>
        <!--释放资源时间的限制-->
        <property name="hibernate.c3p0.idle_test_period">1000</property>
        <!--超时设置-->
        <property name="hibernate.c3p0.timeout">5000</property>
        <!--最大连接数-->
        <property name="hibernate.c3p0.max_size">30</property>
        <!--最小连接数-->
        <property name="hibernate.c3p0.min_size">5</property>
        <!--statements最大线程数-->
        <property name="hibernate.c3p0.max_statements">10</property>

        <!--数据库方言-->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</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>

新建一个实体类:

@Data
public class User {
    private Integer id;
    private String username;
    private String password;


}

创建关系映射文件 User.hbm.xml

<?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.tedu.entity.User" table="user" schema="jt_db">
        <id name="id" column="id" type="java.lang.Integer">
            <generator class="identity"></generator>
        </id>
        <property name="username" column="username" type="java.lang.String"/>
        <property name="password" column="password" type="java.lang.String"/>
    </class>
</hibernate-mapping>

实体关系映射文件注册到 hibernate 配置文件中

 <mapping resource="User.hbm.xml"/>

创建测试类测试结果

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

        System.out.println(configuration);

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

        //获取session
        Session session = sessionFactory.openSession();

        User user=new User();
        user.setUsername("王八");
        user.setPassword("1024");
        session.save(user);
        // 开启事务
        Transaction transaction = session.beginTransaction();
        //提交事务
        transaction.commit();
        // 关闭
        session.close();
        sessionFactory.close();
    }
}
Hibernate 级联操作

数据库的表结构
一对多
customer 表
在这里插入图片描述
orders 表
在这里插入图片描述

多对多
t_account 表
在这里插入图片描述
t_course 表
在这里插入图片描述
中间表 account_course
在这里插入图片描述

1.一对多的关系
客户和订单:每个客户可以购买多个产品,生成多个订单,但是一个订单只能属于-一个客户,所以客户是一,订单是多。数据库中一的

在这里插入图片描述

一 方是主表, 多的- -方时候从表,通过主外键关系来维护。

面向对象中

@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class Customer {

    private Integer id;
    private String name;
    private Set<Orders> ordersSet;

}
@Data
public class Orders {

    private Integer id;
    private String name;
    private int cid;
    private Customer customer;
}

hibernate 实现一对多
Customer.hbm.xml 文件

<?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.tedu.entity.Customer" table="customer" schema="jt_db">
        <!--配置主键-->
       <id name="id" type="java.lang.Integer">
           <column name="id"></column>
           <!--主键自增-->
           <generator class="identity"></generator>
       </id>
        <!--配置字段-->
        <property name="name" column="name" type="java.lang.String"/>
        
        <!--配置一对多的关系-->
        <set name="ordersSet" table="orders">
            <key column="cid"></key>
            <!--一对多关系-->
            <one-to-many class="com.tedu.entity.Orders"></one-to-many>
        </set>
        
    </class>
</hibernate-mapping>
  • set 标签来配置实体类中的集合属性 ordersSet
  • name 实体类属性名
  • table 表名
  • key 外键
  • one-to-many 与集合泛型的实体类对应

Orders.hbm.xml 文件

<?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.tedu.entity.Orders" table="orders" schema="jt_db">
        <id name="id" column="id" type="java.lang.Integer">
            <generator class="identity"></generator>
        </id>
        <property name="name" column="name" type="java.lang.String"/>


        <many-to-one name="customer" class="com.tedu.entity.Customer" column="cid"></many-to-one>
    </class>
</hibernate-mapping>
  • many-to-one 配置实体类对应的对象属性
  • name 属性名
  • class 属性对应的类
  • column 外键字段
    在 Hibernate 配置文件进行注册
    新建测试类
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.close();
        sessionFactory.close();
    }
}

2、多对多关系
学生选课:一门课程可以被多个学生选择,-个学生可以选择多门课程,学生是多,课程也是多。
数据库中是通过两个一对多关系来维护的,学生和课程都是主表,额外增加一张中间表作为从表,两张主表和中间表都是一对多关系。
在这里插入图片描述
面向对象中

@Data
public class TAccount {
    private int id;
    private String name;
    private Set<TCourse> courseSet;
}

@Data
public class TCourse {
    private int id;
    private String name;
    private Set<TAccount> accountSet;

}

Hibernate 实现多对多
TAccount.hbm.xml

<?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.tedu.entity.TAccount" table="t_account" schema="jt_db">
        <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="courseSet" table="account_course">
            <key column="aid"></key>
            <many-to-many class="com.tedu.entity.TCourse" column="cid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

TCourse.hbm.xml

<?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.tedu.entity.TCourse" table="t_course" schema="jt_db">
        <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="accountSet" table="account_course">
            <key column="cid"></key>
            <many-to-many class="com.tedu.entity.TAccount" column="aid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>
  • name 实体类对应集合的属性名
  • table 中间表
  • key 外键
  • many-to-many 与集合泛型的实体类对应
  • clumn 属性雨中间表的外字段名对应
    注入 Hibernate 配置文件
    测试类
public class Test3 {
    public static void main(String[] args) {

        Configuration configuration =new Configuration().configure();

        SessionFactory sessionFactory = configuration.buildSessionFactory();

        Session session = sessionFactory.openSession();

        TAccount tAccoun = new TAccount();

        tAccoun.setName("张三");

        TCourse tCourse =new TCourse();
        tCourse.setName("python");

        Set<TCourse> tCourses=new HashSet<>();
        tCourses.add(tCourse);
        tAccoun.setCourseSet(tCourses);

        session.save(tCourse);
        session.save(tAccoun);

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

        sessionFactory.close();
    }
}

Hibernate 延迟加载

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

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

延迟加载的思路是:当我们查询客户的时候,如果没有访问订单数据,只发送一条SQL语句查询客户信
息,如果需要访问订单数据,则发送两条SQL。.
延迟加载可以看作是一种优化机制,根据具体的需求,自动选择要执行的SQL语句数量。

一对多关系

首先修改两个 pojo 对象

@Getter
@Setter
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class Customer {

    private Integer id;
    private String name;
    private Set<Orders> ordersSet;

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

@Getter
@Setter
public class Orders {

    private Integer id;
    private String name;
    private int cid;
    private Customer customer;

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

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

 <!--配置一对多的关系-->
        <set name="ordersSet" table="orders" lazy="true">
            <key column="cid"></key>
            <!--一对多关系-->
            <one-to-many class="com.tedu.entity.Orders"></one-to-many>
        </set>

2、查询 Customer

public class Test4 {
    public static void main(String[] args) {



    Configuration configuration =new Configuration().configure();

    SessionFactory sessionFactory = configuration.buildSessionFactory();

    Session session = sessionFactory.openSession();


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



    }

}

在这里插入图片描述
查询 Orders

Configuration configuration =new Configuration().configure();

    SessionFactory sessionFactory = configuration.buildSessionFactory();

    Session session = sessionFactory.openSession();


        Customer customer = session.get(Customer.class, 16);
        System.out.println(customer.getOrdersSet());

3、将延迟加载关闭
在这里插入图片描述
测试代码


    Configuration configuration =new Configuration().configure();

    SessionFactory sessionFactory = configuration.buildSessionFactory();

    Session session = sessionFactory.openSession();


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

在这里插入图片描述
lazy除了可以设置true和false之外,还可以设置extra, extra是比true更加懶惰的一种加载方式,或者说是更加智能的-种加载方式,通过例子看区别:
查询Customer对象,打印该对象对应的orders集合的长度

 Configuration configuration =new Configuration().configure();

    SessionFactory sessionFactory = configuration.buildSessionFactory();

    Session session = sessionFactory.openSession();


        Customer customer = session.get(Customer.class, 16);
        System.out.println(customer.getOrdersSet().size());

在这里插入图片描述
也可以通过Orders来设置Customer的延迟加载,orders.hbm.xml 中进行设置。

        <many-to-one name="customer" class="com.tedu.entity.Customer" column="cid" lazy="proxy"></many-to-one>
public class Test5 {

    public static void main(String[] args) {
        Configuration configuration =new Configuration().configure();

        SessionFactory sessionFactory = configuration.buildSessionFactory();

        Session session = sessionFactory.openSession();

        Orders orders = session.get(Orders.class, 24);
        System.out.println(orders);
    }

}

在这里插入图片描述
查询 Costomer对象

Configuration configuration =new Configuration().configure();

        SessionFactory sessionFactory = configuration.buildSessionFactory();

        Session session = sessionFactory.openSession();

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

在这里插入图片描述
no-proxy:当调用方法需要访问customer的成员变量时,发送SQL语句查询Customer,否则不查询。

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

多对多查询

1.修改两个 pojo 对象

@Getter
@Setter
public class TAccount {
    private int id;
    private String name;
    private Set<TCourse> courseSet;

    @Override
    public String toString() {
        return "TAccount{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
@Setter
@Getter
public class TCourse {
    private int id;
    private String name;
    private Set<TAccount> accountSet;

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

查询TCourse,加载对应的TAccount,默认延迟加载开启。

<set name="accountSet" table="account_course" lazy="true">
            <key column="cid"></key>
            <many-to-many class="com.tedu.entity.TAccount" column="aid"></many-to-many>
  </set>
public class Test6 {

    public static void main(String[] args) {
        Configuration configuration =new Configuration().configure();

        SessionFactory sessionFactory = configuration.buildSessionFactory();

        Session session = sessionFactory.openSession();

        TCourse tCourse = session.get(TCourse.class, 4);
        System.out.println(tCourse);
    }

}

在这里插入图片描述
修改为 false

<set name="accountSet" table="account_course" lazy="false">
            <key column="cid"></key>
            <many-to-many class="com.tedu.entity.TAccount" column="aid"></many-to-many>
        </set>

测试结果
在这里插入图片描述

查询TAccount,加载对应的TCourse,默认延迟加载开启。

 <set name="courseSet" table="account_course" lazy="true">
            <key column="aid"></key>
            <many-to-many class="com.tedu.entity.TCourse" column="cid"></many-to-many>
        </set>
public class Test7 {

    public static void main(String[] args) {
        Configuration configuration =new Configuration().configure();

        SessionFactory sessionFactory = configuration.buildSessionFactory();

        Session session = sessionFactory.openSession();
        TAccount tAccount = session.get(TAccount.class, 4);

        System.out.println(tAccount);
    }

}

在这里插入图片描述

Hibernate 配置文件

1.hibernate.cfg.xml

hibernate.xml配置Hibernate的全局环境。

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <!--核心配置,配置文件标签的-->
    <session-factory>
        <!--配置数据库的连接信息-->
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>

        <property name="connection.url">jdbc:mysql://localhost:3306/jt_db</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>


        <!--连接池 C3P0-->
        <property name="hibernate.c3p0.acquire_increment">10</property>
        <!--释放资源时间的限制-->
        <property name="hibernate.c3p0.idle_test_period">1000</property>
        <!--超时设置-->
        <property name="hibernate.c3p0.timeout">5000</property>
        <!--最大连接数-->
        <property name="hibernate.c3p0.max_size">30</property>
        <!--最小连接数-->
        <property name="hibernate.c3p0.min_size">5</property>
        <!--statements最大线程数-->
        <property name="hibernate.c3p0.max_statements">10</property>

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

        <!--打印sql语句-->
        <property name="show_sql">true</property>
        <!--格式化sql语句-->
        <property name="format_sql">true</property>

        <!--是否自动生成数据表-->
        <property name="hibernate.hbm2ddl.auto">update</property>
        <mapping resource="Customer.hbm.xml"/>
        <mapping class="com.tedu.entity.Customer"/>
        <mapping class="com.tedu.entity.Orders"/>
        <mapping resource="Orders.hbm.xml"/>
        <mapping class="com.tedu.entity.User"/>
        <mapping resource="User.hbm.xml"/>
        <mapping resource="Account.hbm.xml"/>
        <mapping class="com.tedu.entity.Account"/>
        <mapping class="com.tedu.entity.TAccount"/>
        <mapping resource="TAccount.hbm.xml"/>
        <mapping resource="TCourse.hbm.xml"/>
        <mapping class="com.tedu.entity.TCourse"/>
    </session-factory>

</hibernate-configuration>
  1. 数据库的基本信息
 <property name="connection.username">root</property>
 <property name="connection.password">root</property>
 <property name="connection.url">jdbc:mysql://localhost:3306/jt_db</property>
 <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
  1. 集成C3p0,设置数据库连接信息
        <!--连接池 C3P0-->
        <property name="hibernate.c3p0.acquire_increment">10</property>
        <!--释放资源时间的限制-->
        <property name="hibernate.c3p0.idle_test_period">1000</property>
        <!--超时设置-->
        <property name="hibernate.c3p0.timeout">5000</property>
        <!--最大连接数-->
        <property name="hibernate.c3p0.max_size">30</property>
        <!--最小连接数-->
        <property name="hibernate.c3p0.min_size">5</property>
        <!--statements最大线程数-->
        <property name="hibernate.c3p0.max_statements">10</property>
  1. Hibernate 基本信息
       <!--数据库方言-->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <!--打印sql语句-->
        <property name="show_sql">true</property>
        <!--格式化sql语句-->
        <property name="format_sql">true</property>

        <!--是否自动生成数据表-->
        <property name="hibernate.hbm2ddl.auto">update</property>
  • update:动态创建表,如果表存在,则直接使用,如果不存在则创建。
  • create:无论表是否存在,都会重新创建。
  • create-drop:初始化创建表,程序结束后删除表。
  • validate:校验实体关系映射文件和数据表是否对应,不能对应直接报错
  1. 注册实体关系映射文件
        <mapping resource="Customer.hbm.xml"/>
        <mapping class="com.tedu.entity.Customer"/>
        <mapping class="com.tedu.entity.Orders"/>
        <mapping resource="Orders.hbm.xml"/>
        <mapping class="com.tedu.entity.User"/>
        <mapping resource="User.hbm.xml"/>
        <mapping resource="Account.hbm.xml"/>
        <mapping class="com.tedu.entity.Account"/>
        <mapping class="com.tedu.entity.TAccount"/>
        <mapping resource="TAccount.hbm.xml"/>
        <mapping resource="TCourse.hbm.xml"/>
        <mapping class="com.tedu.entity.TCourse"/>
实体关系映射文件
<?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.tedu.entity.Customer" table="customer" schema="jt_db">
        <!--配置主键-->
       <id name="id" type="java.lang.Integer">
           <column name="id"></column>
           <!--主键自增-->
           <generator class="identity"></generator>
       </id>
        <!--配置字段-->
        <property name="name" column="name" type="java.lang.String" />
        
        <!--配置一对多的关系-->
        <set name="ordersSet" table="orders" lazy="extra">
            <key column="cid"></key>
            <!--一对多关系-->
            <one-to-many class="com.tedu.entity.Orders"></one-to-many>
        </set>
        
    </class>
</hibernate-mapping>
hibernate-mapping 属性
  • package: 给class节点对应的实体类统一 设置包名,此处设置包名,class的name属性就可以省略包名。
    在这里插入图片描述
  • schema:数据库schema的名称
  • catalog:数据库catalog的名称
  • default-cascade:默认的级联关系,默认为none
  • default-access: Hibernate 用来访问属性的策略
  • default-lazy:指定了未明确注明lazy属性的Java属性和集合类,Hibernate 会采用什么样的加载风格,默认为true
  • auto-import:指定我们是否可以在查询语句中使用非全限定类名,默认为true,如果项目中有两
    个同名的持久化类,最好在这两个类的对应映射文件中配置为false
class 属性
  • name:实体类名
  • table:数据表名
  • schema:数据库schema的名称,会覆盖hibernate-mapping的schema
  • catalog:数据库catalog的名称,会覆盖hibernate-mapping的catalog
  • proxy:指定一个 按口,在处迟加载时作为代理使用
  • dynamic-update:动态更新
  • dynamic-insert:动态添加

测试动态添加:dynamic-insert
测试代码

public class Test8 {

    public static void main(String[] args) {
        Configuration configuration =new Configuration().configure();

        SessionFactory sessionFactory = configuration.buildSessionFactory();

        Session session = sessionFactory.openSession();

        User user =new User();
        user.setUsername("章泽天");

        session.save(user);
        session.close();
    }

}

修改之前
在这里插入图片描述

<class name="com.tedu.entity.User" table="user" schema="jt_db" dynamic-insert="true">

修改之后
在这里插入图片描述
测试动态更新:dynamic-update
测试代码

public class Test8 {

    public static void main(String[] args) {
        Configuration configuration =new Configuration().configure();

        SessionFactory sessionFactory = configuration.buildSessionFactory();

        Session session = sessionFactory.openSession();

        User user = session.get(User.class, 5);

        user.setPassword("66666");
        session.update(user);
        session.beginTransaction().commit();
        session.close();

    }

}

修改之前
在这里插入图片描述
修改之后

<class name="com.tedu.entity.User" table="user" schema="jt_db"
           dynamic-update="true"
           dynamic-insert="true">

在这里插入图片描述

  • where:查询时给SQL 添加 where 条件
    测试代码:
public class Test8 {

    public static void main(String[] args) {
        Configuration configuration =new Configuration().configure();

        SessionFactory sessionFactory = configuration.buildSessionFactory();

        Session session = sessionFactory.openSession();

        String hql = "from User";
        Query query = session.createQuery(hql);

        List<User> list = query.list();
        for (User user : list) {
            System.out.println(user);
        }

        session.close();
    }

}

测试结果之前
在这里插入图片描述
测试结果之后

 <class name="com.tedu.entity.User" table="user" schema="jt_db"
           dynamic-update="true"
           dynamic-insert="true"
    where="id=6"
    >

在这里插入图片描述

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:实体类属性名
  • type:实体类属性数据类型
  • column:数据表的主键字段
  • update:该字段是否可以修改,默认为true
  • insert:该字段是否可以添加,默认为true
  • lazy:延迟加载策略
实体关系映射文件属性

1、inverse
Customer和Orders是一对多关系,一个Customer对应多个Orders, 实体类中用一个set集合来表.
示对应的Orders。

测试代码:

public class Test9 {

    public static void main(String[] args) {
        Configuration configuration =new Configuration().configure();

        SessionFactory sessionFactory = configuration.buildSessionFactory();

        Session session = sessionFactory.openSession();

        Customer customer = new Customer();

        customer.setName("张三");

        Orders orders1 = new Orders();

        orders1.setName("订单1");
        orders1.setCustomer(customer);

        Orders orders2 = new Orders();

        orders2.setName("订单2");
        orders2.setCustomer(customer);

        session.save(customer);
        session.save(orders1);
        session.save(orders2);

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

}

在这里插入图片描述
添加如下代码

  Set<Orders> orders =new HashSet<>();
        orders.add(orders1);
        orders.add(orders2);
        customer.setOrdersSet(orders);

在这里插入图片描述
在这里插入图片描述
因为Customer和Orders都在维护一对多关系,所以会重复设置主外键约束关系。

如何避免这种情况?
1、在Java代码中去掉一 方维护关系代码。
2、通过配置来解决。

  <!--配置一对多的关系-->
        <set name="ordersSet" table="orders" lazy="extra" inverse="true">
            <key column="cid"></key>
            <!--一对多关系-->
            <one-to-many class="com.tedu.entity.Orders"></one-to-many>
        </set>

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

cascade:用来设置级联操作

1.代码的方式实现级联的删除操作

public class Test10 {

    public static void main(String[] args) {
        Configuration configuration =new Configuration().configure();

        SessionFactory sessionFactory = configuration.buildSessionFactory();

        Session session = sessionFactory.openSession();

        Customer customer = session.get(Customer.class, 20);

        Iterator<Orders> iterator =customer.getOrdersSet().iterator();

        while ((iterator.hasNext())){
            session.delete(iterator.next());
        }
        session.delete(customer);

        session.beginTransaction().commit();

        session.close();

    }

}

实体关系映射文件中设置cascade值完成级联删除。

<!--配置一对多的关系-->
        <set name="ordersSet" table="orders" lazy="extra" inverse="true" cascade="delete">
            <key column="cid"></key>
            <!--一对多关系-->
            <one-to-many class="com.tedu.entity.Orders"></one-to-many>
        </set>
public class Test10 {

    public static void main(String[] args) {
        Configuration configuration =new Configuration().configure();

        SessionFactory sessionFactory = configuration.buildSessionFactory();

        Session session = sessionFactory.openSession();

        Customer customer = session.get(Customer.class, 21);

//        Iterator<Orders> iterator =customer.getOrdersSet().iterator();
//
//        while ((iterator.hasNext())){
//            session.delete(iterator.next());
//        }
        session.delete(customer);

        session.beginTransaction().commit();

        session.close();

    }

}

Hibernate HQL

HQL: Hibernate Query Language,是Hibernate框架提供的一种查询机制,它和SQL类似,不同的是HQL是面向对象的查询语句,让开发者能够以面向对象的思想来编写查询语句,对Java编程是一种
好友好的方式。
HQL不能直接参与数据库的交互,中间层语言。
Java-- HQL-- Hibernte— SQL-- DB
HQL只能完成查询、修改、删除,新增是无法操作的。

1、查询对象
查询表中所有数据,自动完成对象的封装,返回List集合。
HQL进行查询,from 关键字后面不能写表名,必须写表对应的实体类名。

Configuration configuration = new Configuration().configure();

        SessionFactory sessionFactory = configuration.buildSessionFactory();

        Session session = sessionFactory.openSession();

      String hql = "from User";
        Query query = session.createQuery(hql);

        List<User> list = query.list();

        for (User user : list) {
            System.out.println(user);
        }
        session.beginTransaction().commit();
        session.close();

2、分页查询
HQL分页查询可以通过调用query的方法来完成。
1、setFirstResult()设置起始下标
2、setMaxResults() 设置截取长度

// 分页查询
        String hql = "from User";

        Query query = session.createQuery(hql);
        query.setFirstResult(1);
        query.setMaxResults(3);

		 List<User> list = query.list();
        for (User user : list) {
            System.out.println(user);
        }

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

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

// where 条件查询语句

        String hql = "from User where id = 5";

        Query query = session.createQuery(hql);

        User user = (User) query.list().get(0);
       
        System.out.println(user);

查询不存在的id时不会抛出异常,而是返回一个 null 值

 // where 条件查询语句

        String hql = "from User where id = 5";

        Query query = session.createQuery(hql);
        User user = (User) query.uniqueResult();
        System.out.println(user);

4、模糊查询
查询名称包含“章”的所有记录

// 模糊查询
        String hql = "from User where username like '%章%'";
        Query query = session.createQuery(hql);
		 List<User> list = query.list();
        for (User user : list) {
            System.out.println(user);
        }

5、order by
按照id进行排序

//排序
        String hql = "from User order by id desc ";
        Query query = session.createQuery(hql);
        
         List<User> list = query.list();
        for (User user : list) {
            System.out.println(user);
        }

asc是生序排列,desc 是降序排列。

6、查询实体对象的属性

 // 查询属性
        String hql ="select username from User where id= 6 ";
        Query query = session.createQuery(hql);
        String  user = (String) query.uniqueResult();
        System.out.println(user);

7、查询总数

// 查询总数
        String hql = "select count(*) from User ";
        Query query = session.createQuery(hql);
        Long count = (Long) query.uniqueResult();
        System.out.println(count);

8、占位符

   String hql = "from User where username=:name";

        Query query = session.createQuery(hql);
        query.setString("name", "章泽天");



        List<User> list = query.list();
        for (User user : list) {
            System.out.println(user);
        }

8、级联查询

        String hql1 = "from Customer where name = :name";

        Query query1 = session.createQuery(hql1);
        query1.setString("name","张三");
        Customer customer = (Customer) query1.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);
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

光头小小强007

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

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

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

打赏作者

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

抵扣说明:

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

余额充值