3.1 连接 Hibernate 和数据库

我们学习了如何使用 Maven 将 Hibernate 连接到我们的应用程序,以及如何使用注释将表映射到类。现在下一个问题出现了——我们如何从数据库中读取对象或将它们保存在那里?

没那么快。首先,你还需要处理三件事:

  • 配置数据库连接
  • 设置休眠
  • 使用 EntityManager

Hibernate 对您的应用程序完全隐藏了对数据库的操作,但是为了避免任何过度操作,必须正确配置它。你不能跳过这个阶段——否则 Hibernate 如何知道将对象保存到哪个数据库?

可以通过三种方式配置 Hibernate 并提供数据库信息

  • 使用属性文件
  • 使用 hibernate.cfg.xml 文件
  • 使用配置 bean 方法

而且虽然我最喜欢最后一个,但是你肯定会遇到这三个,所以我们在这里将三个都分析一下。

3.2 在数据库中授权

让我们从最重要的 - 数据库连接开始。为此,您需要提供数据以便 Hibernate 可以登录到所需的数据库。

属性文件配置
休眠.properties
hibernate.dialect= org.hibernate.dialect.Oracle9Dialect
hibernate.connection.driver_class= oracle.jdbc.driver.OracleDriver
hibernate.connection.url= jdbc:oracle:thin:@localhost:1521:supershop
hibernate.connection.username=root
hibernate.connection.password=secret
hibernate.show_sql=true
hibernate.hbm2ddl=update

可以以xml文件的形式设置相同的设置:

基于 XML 的配置
休眠配置文件
<hibernate-configuration>
	<session-factory>

    	<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
    	<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
    	<property name="connection.url">jdbc:oracle:thin:@localhost:1521:supershop</property>
    	<property name="connection.username">root</property>
    	<property name="connection.password">secret</property>
    	<property name="hibernate.show_sql ">true</property>
    	<property name="hbm2ddl.auto">update</property>

	</session-factory>
</hibernate-configuration>

在这两个示例中,我们看到具有相同值的相同设置。只是第一个示例将它们表示为属性文件,第二个示例表示为xml 文件

这些设置分为三组:

  1. 指定 DBMS 的类型
    • 指定方言(DBMS 类型),例如 Oracle 9.0
    • 指定用于使用此 DBMS 的 JDBC 驱动程序的名称
  2. 在数据库中指定授权数据
    • 数据库地址
    • 用户名
    • 密码
  3. 配置休眠引擎
    • hibernate.show_sql- Hibernate 将在控制台中复制它执行的所有请求
    • hbm2ddl.auto- Hibernate 将在必要时更改数据库结构

还有第三种设置配置的方法 - 通过 bins。一般是和Spring配合使用,所以我们学习SpringFramework的时候再看。

3.3 获取会话工厂

下一步是获取 SessionFactory 对象。做这件事有很多种方法:

第一种方法是使用 hibernate.properties 文件

为此,您只需编写以下代码:

SessionFactory sessionFactory = new Configuration().buildSessionFactory();

如果在当前项目目录下没有找到hibernate.properties文件,则会抛出异常。

第二种方式是使用 hibernate.cfg.xml 进行配置

SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

如果您编写这样的代码,那么hibernate.cfg.xml. 如果没有找到这样的文件,该方法buildSessionFactory()将抛出异常。

第三种方式是手动设置配置文件

有时在开发过程中有必要切换到测试基地或更改一些其他设置以使用基地,为此您可以手动设置配置文件:

SessionFactory sessionFactory = new Configuration().configure("hibernate-dev.cfg.xml").buildSessionFactory();

方法四——我们使用自定义的 hibernate.properties 文件:

ClassLoader classLoader = Thread.currentThread().getClassLoader();

Properties properties = new Properties();
properties.load(classLoader.getResourceAsStream("hibernate-dev.properties"));

SessionFactory sessionFactory = new Configuration()
            .addProperties(properties)
            .buildSessionFactory();

最后,您可以简单地将所有必要的参数直接缝入代码中:

Properties properties = new Properties();
properties.put(Environment.DRIVER, "com.mysql.jdbc.Driver");
properties.put(Environment.URL, "jdbc:mysql://localhost:3306/supershop");
properties.put(Environment.USER, "root");
properties.put(Environment.PASS, "password");

SessionFactory sessionFactory = new Configuration()
            .setProperties(properties)
            .buildSessionFactory();

3.4 指定在哪里寻找实体类

但这还不是全部。当我们在 Hibernate 中配置一个SessionFactory对象时,这个SessionFactory会检查数据库中是否存在所有具有所需列类型的所需表。

为了让SessionFactory能够做到这一点,它需要传递一个实体类列表,它需要映射到数据库。

可以通过三种方式传递实体类列表:

方法一。添加hibernate.cfg.xml一行:

<mapping class="class-qualified-name" />

例子:

<mapping class="com.codegym.data.User" />
<mapping class="com.codegym.data.Employee" />
<mapping class="com.codegym.data.Task" />

方法二。调用Configuration对象上的方法addAnnotatedClass()。例子:

SessionFactory sessionFactory = new Configuration()
   	.configure()
   	.addAnnotatedClass(com.codegym.data.User.class)
   	.buildSessionFactory();

如果有很多类,那么你可以将它们添加到整个包中:

SessionFactory sessionFactory = new Configuration()
   	.configure()
   	.addPackage("com.codegym.data")
   	.buildSessionFactory();

3.5 最后的例子

现在我们已经了解了如何配置 SessionFactory 对象,让我们编写将使用它的代码。

它将包括三个方法:

  1. 配置休眠
  2. 从数据库中获取所有员工的方法
  3. 将新员工保存到数据库的方法

此代码模板看起来像这样:

class EmployeeManager {
    private SessionFactory sessionFactory;

    public void class init() {
    	this.sessionFactory = new Configuration()
        	.configure()
        	.buildSessionFactory();
   }

   public List<Employee> getAllEmployes() {
         try (Session session = sessionFactory.openSession()) {
  	          Query<Employee> query = session.createQuery("from Employee", Employee.class);
    	        return query.list();
         }
   }

   public void addEmployee(Employee employee ) {
     	try (Session session = sessionFactory.openSession()) {
            Transaction transaction = session.beginTransaction();
       	    session.save(employee);
            transaction.commit();
     	}
   }
}

在对数据库执行查询之前,您需要创建一个单独的会话。如果请求是相关的,那么它们可以在同一个会话中执行。如果请求不相关(并且它们之间可以经过几分钟),那么他们需要进行自己的会话。

如果你想从数据库中读取数据或执行复杂的查询,你必须首先创建一个 Query 对象并用它来执行你的查询。

此外,对数据库的每个查询都在其自己的事务中执行。您需要打开它,执行必要的操作,然后关闭(提交)。

在接下来的课程中,我们将更详细地分析这一切是如何工作的。