Hibernate的工具类的妙用

本文讲述Hibernate的基础配置,和工具类的封装以及简单的CRUD。本文教程基于Maven+Hibernate。


一、开发前的基础配置

1、目录结构

2、 相关配置文件

Maven配置文件pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.point9.service</groupId>
  <artifactId>Hibernate01</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>Hibernate01</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

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

    <!-- for JPA, use hibernate-entitymanager instead of hibernate-core -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>5.2.10.Final</version>
    </dependency>

    <!-- optional -->

    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-osgi</artifactId>
      <version>5.2.10.Final</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-envers</artifactId>
      <version>5.2.10.Final</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-c3p0</artifactId>
      <version>5.2.10.Final</version>
    </dependency>

    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-proxool</artifactId>
      <version>5.2.10.Final</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-infinispan</artifactId>
      <version>5.2.10.Final</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-ehcache</artifactId>
      <version>5.2.10.Final</version>
    </dependency>

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

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.7</version>
    </dependency>
    <!-- slf4j日志框架和log4j 转换包 -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.7</version>
    </dependency>
  </dependencies>

  <build>
    <!-- 把java目录中的配置文件,也能够打包到jar包中。 -->
    <resources>
      <resource>
        <directory>src/main/resources</directory>
      </resource>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <!-- 是否替换资源中的属性-->
        <filtering>false</filtering>
      </resource>
    </resources>

    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
        <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.7.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

实体类文件User.java

package com.point9.pojo;

/**
 *  用户实体类
 */
public class User {

    private Integer id;
    private String username;
    private String password;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public User() {
    }

    public User(Integer id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

实体类的映射文件User.hbm.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.point9.pojo.User" table="t_user">
        <!--必须有主键:让对象和行关联 OID对象标识-->
        <id name="id" column="id">
            <!--主键生成方式-->
            <generator class="identity"/>
        </id>
        <!--属性和字段的映射-->
        <property name="username" column="username"/>
        <property name="password" column="password"/>
    </class>
</hibernate-mapping>

全局配置文件Hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!--数据源-->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost/sz_1809?useUnicode=true&amp;characterEncoding=utf-8</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">root</property>
        <!--扩展属性:必须指向数据库的方言-->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</property>
        <!-- session  通过getCurrentSession()方法得到session对象时,需要配置以下参数 -->
        <property name="current_session_context_class">thread</property>
        <!--在启动时,根据配置更新数据库,数据表存在则不创建,不存在则创建,不存在的字段会创建,不会删除原有字段-->
        <property name="hbm2ddl.auto">update</property>
        <!--显示SQL语句-->
        <property name="hibernate.show_sql">true</property>
        <!--格式化SQL语句-->
        <property name="hibernate.format_sql">true</property>
        <!--注册实体-->
        <mapping resource="com/point9/pojo/User.hbm.xml"></mapping>
    </session-factory>
</hibernate-configuration>

二、正文开始(工具类的封装)

1、HibernateUtils

package com.point9.Utils;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtils {
    private static SessionFactory factory;

    static {
        Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
        factory = configuration.buildSessionFactory();
    }


    public static Session currentSession(){
        return factory.getCurrentSession();
    }

    public static Session openSession(){
        return factory.openSession();
    }
}

2、测试的main函数

package com.point9.service;

import com.point9.Utils.HibernateUtils;
import com.point9.pojo.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.jdbc.Work;
import org.hibernate.query.Query;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * 点九博客
 */
public class App {

    /**
     * 更新用户 测试
     */
    public void updateUser(){
        //第1步:通过工具类得到session对象
        Session session = HibernateUtils.currentSession();
        //第2步:开启事务
        session.beginTransaction();
        //第3步:执行对象操作(传入反射对象,在数据库中得到第二个数据)
        User user = session.get(User.class, 1);
        user.setPassword("333");
        session.update(user);
        //第4步:提交事务
        session.getTransaction().commit();
    }

    /**
     * 删除用户
     */
    public void deleteUser(){
        //第1步:通过工具类得到session对象
        Session session = HibernateUtils.openSession();
        //第2步:开启事务
        Transaction transaction = session.beginTransaction();
        //第五步:执行对象操作(传入反射对象,在数据库中得到第二个数据)
        User user = new User();
        user.setId(3);
        session.delete(user);
        //第3步:提交事务
        transaction.commit();
        //第4步:关闭session
        session.close();
    }

    
    public static void main(String[] args) {
        App app = new App();
        //app.updateUser();//测试数据表中指定记录的更新
        app.deleteUser();//删除用户
    }
}

通过以上操作,我们简单总结一下openSession和getCurrentSession的区别:

1、opensession():一般的crud操作我们用的是这个操作,只有增删改才用到事务,查询不需要。每一次都产生一个新对象。

2、getCurrentSession():如果有多个拥有session的方法互相调用,这个时候就存在多个session对象和多个事务了。保证不了crud操作只在一个session对象和事务中操作。这个时候才会使用到。每次都要在localThread中判断是否有这个对象,有的话直接拿出来用。没有的话,新建一个,与Factory绑定放入LocalThread中。这种方式下的crud操作,全都必须在事务下操作,(并且事务和session是绑定在一起的。)  当使用这种session对象时,事务已提交就自动关闭了,就不用写这个(session.close();)关闭了。不然就会出连接已关闭的错 。

3、getCurrentSession的特别注意!!

  A、在hibernate的配置文件中必须加上这个才能用第二种方式:

        <propertyname="current_session_context_class">thread</property>

  B、不需要写session.close方法,在事务提交的时候会自动关闭(由hibernate内部完成)

4、为什么getCurrentSession的CRUD都需要事务?

      1、因为是一个线程,所以在整个方法中有一个session和一个事务

      2、保证了整个业务操作的安全性 


Web全栈技术交流

点击链接加入群聊【Web全栈交流群】:https://jq.qq.com/?_wv=1027&k=5rnUzsF

QQ群二维码

发布了67 篇原创文章 · 获赞 129 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/Point9/article/details/86096322
今日推荐