Hibernate学习

ORM将java类映射成表

1.如何使用?

  • 导入相关依赖
  • 创建Hibernate配置文件
  • 创建实体类
  • 创建实体类-关键映射文件
  • 调用Hibernate API完成操作

2.具体使用 -实操

1)创建maven工程,pom.xml

 <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</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>
    </dependencies>

2)在resources目录下创建hibernate.cfg.xml文件

<?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">123456</property>
        <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/hibernateTest?useUnicode=true&amp;characterEncoding=UTF-8</property>
        <!--c3p0-->
        <property name="hibernate.c3p0.acquire_increment">10</property><!--不够了自己增加10-->
        <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.MySQLDialect</property>

        <!--打印sql-->
        <property name="show_sql">true</property>
        <!--格式化sql-->
        <property name="format_sql">true</property>
        <!--是否自动生成数据表-->
        <property name="hibernate.hbm2ddl.auto">create</property>
    </session-factory>
</hibernate-configuration>

3)创建实体类

@Data
//除了用@Data外,还可以用@Setter,@Getter,来生成对应的表
public class Customer {
    private int id;
    private String name;
    private int age;
    private Set<Order> orders;//一个客户对应多个订单,一对多关系
}
@Data
public class Order {
    private int oid;
    private String name;
    private Customer customer;//多个订单对应一个用户
}

4)创建实体关系映射文件(关键)
customer.xml

<?xml version="1.0"?>
<!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.entry.Customer" table="customer">
        <id name="id" type="java.lang.Integer"><!--主键映射-->
                <column name="id"></column><!--主键的字段-->
                <generator class="identity"></generator><!--identity主键自增-->
        </id>
        <!--name字段-->
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>
		<!--一对多关联查询-->
        <set name="orders" table="order">
            <key column="oid"></key>
            <one-to-many class="com.entry.Order"></one-to-many>
        </set>
    </class>
</hibernate-mapping>
  • set标签来配置实体类中的集合属性order
  • name实体类属性名
  • table表名
  • key外键
  • one-to-many与集合泛型的实体类

order.xml

<?xml version="1.0"?>
<!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.entry.Order" table="Order">
        <id name="oid" type="java.lang.Integer"><!--主键映射-->
            <column name="id"></column><!--主键的字段-->
            <generator class="identity"></generator><!--identity主键自增-->
        </id>
        <!--name字段-->
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>
        <!--多对一关联查询     column="cid"为Order表的外键 -->
        <many-to-one name="customer" class="com.entry.Customer" column="cid"></many-to-one>
    </class>
</hibernate-mapping>
  • many-to-one 配置实体类对应的对象属性
  • name 属性名
  • class 属性对应的类
  • column 外键

5)实体关系映射文件注册到hibernate.cfg.xml文件中

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

6)使用Hibernate API

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();
        //使用Hibernate操作数据库,都要开启事务,得到事务对象
        Transaction transaction = session.getTransaction();

        //开启事务
        transaction.begin();

        People p=new People();
        p.setAge(12);
        p.setPname("lqm");

        //把对象添加到数据库中
        session.save(p);

        //提交事务
        transaction.commit();

        //关闭Session
        session.close();


    }
}

7)pom.xml中添加扫描xml的插件,不然扫描不到xml

<!--扫描dao层的xml文件-->
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>

3.Hibernate级联操作-说明

1)一对多关系
一个客户对应多个订单,一个订单对应一个客户
2)多对多关系
学生选课:一门课程可以被多个学生选择,一个学生可以选择多门课程

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

比如:
在这里插入图片描述

4.Hibernate实现一对多-实操

Customer.java

@Data
//除了用@Data外,还可以用@Setter,@Getter,来生成对应的表
public class Customer {
    private Integer id;
    private String name;
    private Set<Orders> orders;//一个客户对应多个订单,一对多关系
}

Orders.java

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

xml中配置
customer.xml

<?xml version="1.0"?>
<!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.entry.Customer" table="customer">
        <id name="id" type="java.lang.Integer"><!--主键映射-->
                <column name="id"></column><!--主键的字段-->
                <generator class="identity"></generator><!--identity主键自增-->
        </id>
        <!--name字段-->
        <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.entry.Orders"></one-to-many>
        </set>
    </class>
</hibernate-mapping>
  • set标签来配置实体类中的集合属性order
  • name实体类属性名
  • table表名
  • key外键
  • one-to-many与集合泛型的实体类

Order.xml中配置添加

<?xml version="1.0"?>
<!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.entry.Orders" table="Orders">
        <id name="id" type="java.lang.Integer"><!--主键映射-->
            <column name="id"></column><!--主键的字段-->
            <generator class="identity"></generator><!--identity主键自增-->
        </id>
        <!--name字段-->
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>

        <!--多对一关联查询     column="cid"为Order表的外键 -->
        <many-to-one name="customer" class="com.entry.Customer" column="cid"></many-to-one>
    </class>
</hibernate-mapping>
  • many-to-one 配置实体类对应的对象属性
  • name 属性名
  • class 属性对应的类
  • column 外键

hibernate.cfg.xml中添加,扫描注解

<mapping resource="com/entry/Customer.xml"></mapping>
<mapping resource="com/entry/Order.xml"></mapping>

测试

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();
        //使用Hibernate操作数据库,都要开启事务,得到事务对象
        Transaction transaction = session.getTransaction();
        //开启事务
        transaction.begin();
        //用户
        Customer customer=new Customer();
        customer.setName("lqm");
        //订单
        Orders order1=new Orders();
        order1.setName("订单1");
        //建立关联关系
        order1.setCustomer(customer);
        //把对象添加到数据库中
        session.save(customer);
        session.save(order1);
        //提交事务
        transaction.commit();
        //关闭Session
        session.close();
    }
}

其中
建立关联关系
order1.setCustomer(customer); 将customer存进order里面
在这里插入图片描述

orders中就能看到cid外键有customer的id了,这样一对多关联关系建立起来了

5.级联关系–多对多–实操

先创建中间表

在这里插入图片描述

Account.java

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

Account.xml

<?xml version="1.0"?>
<!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.entry.Account" table="account">
        <id name="id" type="java.lang.Integer"><!--主键映射-->
            <column name="id"></column><!--主键的字段-->
            <generator class="identity"></generator><!--identity主键自增-->
        </id>
        <!--name字段-->
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>
        <!--多对多关联查询 中间表-->
        <set name="courses" table="account_course">
            <key column="aid"></key> <!--aid对应account在中间表的外键-->
            <many-to-many class="com.entry.Course" column="cid"></many-to-many><!--cid对应course在中间表的外键-->
        </set>
    </class>
</hibernate-mapping>

Course.java

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

Course.xml

<!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.entry.Course" table="course">
        <id name="id" type="java.lang.Integer"><!--主键映射-->
            <column name="id"></column><!--主键的字段-->
            <generator class="identity"></generator><!--identity主键自增-->
        </id>
        <!--name字段-->
        <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.entry.Account" column="aid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

hibernate.cfg.xml中添加关联映射

 <mapping resource="com/entry/Account.xml"></mapping>
 <mapping resource="com/entry/Course.xml"></mapping>

测试

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();
        //使用Hibernate操作数据库,都要开启事务,得到事务对象
        Transaction transaction = session.getTransaction();
        //开启事务
        transaction.begin();

        Course course=new Course();
        course.setName("Java");

        Account account=new Account();
        account.setName("张三");

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

        account.setCourses(courses);

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

        //提交事务
        transaction.commit();

        //关闭Session
        session.close();

    }
}

你会发现后台打印了3条sql语句:
在这里插入图片描述
数据库中也有了相应的数据
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.Hibernate延迟加载

1.延迟加载可以看作是一种优化机制,根据具体的需求,自动选择要执行的sql数量

(set那里写lazy=true,或者可以设置lazy=extra,是比true更懒惰的一种加载方式,或者说是更加智能的加载方式)

比如:查询id为15的customer,如果还需要查询id=15的customer的orders的话,就需要先查询有没有id=15的customer,如果有就会 再去查id=15的customer的orders。这样就是两条sql语句。

说明:开启延时加载后,查询id=15的customer是一条sql,如果需要查询从表信息的话,就是主表和从表信息都查询,那就是两条sql。
         关闭延时加载后,查询id=15的customer是两条sql,主表和从表都去查了一遍。如果关联到从表时,查询还是两条sql。
  • no-proxy:当调用方法需要访问customer的成员变量时,发送sql语句查询Customer,否则不查询。
  • proxy:无论调用方法是否需要访问customer的成员变量,都发送sql语句查询Customer。

7.Hibernate配置详解

Hibernate.cfg.xml中配置详解:
在这里插入图片描述

在这里插入图片描述
实体关系映射文件
比如:
在这里插入图片描述

在这里插入图片描述
比如:
在这里插入图片描述
除此之外还有下面的属性:
在这里插入图片描述
在这里插入图片描述
还有where属性,比如where id=6

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值