搭建Hibernate的开发环境【解决Session线程不安全的问题】

本文详细介绍如何在Maven项目中引入Hibernate依赖,并配置数据源,创建实体类及映射文件,最终通过JUnit测试验证配置正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1,导入Hibernate的jar包,我这里新建的是Maven项目,因此首先须要加入关于Hibernate的依赖,由于我们还须要与数据库打交道。因此还须要加入数据库以及数据源的依赖jar包,以下是我的pom.xml文件的内容:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <hibernate.version>4.1.7.Final</hibernate.version>
    <druid.version>1.0.12</druid.version>
    <mysql.version>5.1.18</mysql.version>
</properties>

<dependencies>
   <dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>4.12</version>
     <scope>test</scope>
   </dependency>
   <!-- hibernate4 -->
   <dependency>
       <groupId>org.hibernate</groupId>
       <artifactId>hibernate-core</artifactId>
       <version>${hibernate.version}</version>
   </dependency>
   <!--Druid连接池包 -->
   <dependency>
       <groupId>com.alibaba</groupId>
       <artifactId>druid</artifactId>
       <version>${druid.version}</version>
   </dependency>
   <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
       <version>${mysql.version}</version>
   </dependency>
</dependencies>

2,在src/main/resources文件夹下新建一个hibernate.cfg.xml的文件。里面我们主要配置数据源:

<hibernate-configuration>
    <session-factory>
        <!-- 数据库连接设置 -->
        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>
        <property name="connection.username">root</property>
        <property name="connection.password">admin</property>
        <!-- SQL方言 -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <!-- 在控制台打印出运行的SQL语句 -->
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>
        <!-- 是否格式化打印出来的SQL -->
        <property name="format_sql">true</property>
        <!-- 将映射文件转换为数据库定义语言 -->
        <!-- Drop and re-create the database schema on startup -->
        <!-- web项目启动时怎么操作表结构:更新、删除重建 -->
        <property name="hbm2ddl.auto">update</property>
        <!-- 映射文件 -->
        <mapping resource="student.hbm.xml" />
    </session-factory>
</hibernate-configuration>

3,我们这里新建一个Student的实体类。而且也在src/main/resources文件夹下创建一个映射文件:student.hbm.xml 
Student.java

package com.ecjtu.hibernate.entity;

import java.io.Serializable;
import java.util.Date;

public class Student implements Serializable {

    private static final long serialVersionUID = 1L;

    private String major;
    private Long id;
    private String name;
    private String sex;
    private Integer age;
    private Date birthday;

    public Student() {
    }

    public Student(String major, Long id, String name, String sex, int age,
            Date birthday) {
        super();
        this.major = major;
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.birthday = birthday;
    }

    //省略掉getter/setter

    @Override
    public String toString() {

        return "Student[Major:" + getMajor() + " Id:" + getId() + " Name:"
                + getName() + " sex:" + getSex() + " Age:" + getAge()
                + " birthday:" + getBirthday() + "]";
    }
}

student.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 package="com.ecjtu.hibernate.entity">
    <class name="Student" table="TAB_STUDENT">
        <id name="id" column="id">
            <!-- 主键生成机制:自增长 -->
            <generator class="increment"/>
        </id>
        <!-- 属性字段 -->
        <property name="major"/>
        <property name="name"/>
        <property name="sex"/>
        <property name="age"/>
        <property name="birthday"/>
    </class>
</hibernate-mapping>

4,建好这些之后基本上也就大功告成了,接下来就能够測试了。在src/test/java以下新建一个測试类HibernateTest.java

package com.ecjtu.hibernate.Test;

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Before;
import org.junit.Test;

import com.ecjtu.hibernate.entity.Student;

/**
 * @ClassName: HibernateTest
 * @Description: Hibernate測试
 * @author Zhouxh
 * @date 2017年2月19日
 */
public class HibernateTest {

    private SessionFactory sessionFactory;

    @SuppressWarnings({ "deprecation"})
    @Before
    public void init(){
        //1.创建配置对象
        Configuration configuration=new Configuration();
        //2.读取配置文件,參数可为空。Document。File,配置文件的路径或者URL
        //HibernateTest/src/main/resources/hibernate.cfg.xml
        configuration.configure();
        //3.依据配置文件,创建一级缓存(sessionFactory)
        sessionFactory=configuration.buildSessionFactory();
    }

    @Test
    public void test(){
        /**
         * 建立与数据库的连接
         * 映射文件,映射对象
         * session  代码与数据库之间的会话
         */
        //4.创建Session。打开会话
        Session session=sessionFactory.openSession();
        //5.开启事物
        Transaction transaction=session.beginTransaction();
        Student student=new Student("软件工程", 1000L, "李四", "男", 34, new Date(System.currentTimeMillis()));
        session.save(student);
        //6.事物的提交
        transaction.commit();
        //7.session的关闭
        session.close();
    }
}

 5,运行完Junit单元測试成功了就可以。这时控制台也会打出insert into语句,这就说明我们的配置没有问题了。

 

6,封装HibernateSessionFactory工具类

由于Session是线程不安全的。

为了保证当前线程仅仅有一个session对象,而且当前线程中的Session不能让其它线程来訪问,须要将获取Session的方法进行封装。为了保证Session的线程安全性。

须要将Session放到ThreadLocal中,ThreadLocal为线程本地变量 
HibernateSessionFactory.java,主要是为了维护Session的创建和关闭

package com.ecjtu.hibernate.util;

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

/**
 * @ClassName: HibernateSessionFactory
 * @Description: 封装一个创建Session的工厂而且得到Session的方法
 * @author Zhouxh
 * @date 2017年2月20日
 */
@SuppressWarnings("deprecation")
public class HibernateSessionFactory {
    //hibernate.cfg.xml文件的位置
    //private static String configFile = "hibernate.cfg.xml";

    private static SessionFactory factory;

    // 用于存放Session,该对象是线程安全的。仅仅有当前线程才可訪问
    private static ThreadLocal<Session> threadLocal;

    static {
        Configuration config = new Configuration( );
        // 无參默认系统去找src以下的hibernate.cfg.xml"
        config.configure();
        // 重量级:该实例对象的构造和销毁消耗系统资源,所以一般在应用程序启动的时候就构造实例对象,
        // 一般一个数据库相应一个SessionFactory的实例对象,
        // 假设要訪问多个数据库,就须要创建多个该实例对象。

        factory = config.buildSessionFactory();
        threadLocal = new ThreadLocal<Session>();
    }

    /**
     * @Title: getSession
     * @Description: 获取Session
     * @return
     * @throws
     */
    public static Session getSession() {
        // 该方法底层是一个map实现的,Key为当前线程的对象,value为Session
        // 假设当前线程没有打开过Session,那么就返回空,意味着我们须要去创建一个Session,
        // 保证了一个线程里面相应一个Session
        Session session = threadLocal.get();
        // 第一个为空的话,第二个表达式不会运行,避免了空指针
        // session为空而且或者他没有被打开过就去创建
        if (session == null || !session.isOpen()) {
            session = factory.openSession();
            // 该方法底层通过Map来保存的,调用该方法会自己主动帮你创建一个map出来。
            // 并通过key-value保存Session到map中,获取session的时候通过key去取的话
            // 不同的key就会返回不同的session
            threadLocal.set(session);
        }
        return session;
    }

    /**
     * @Title: closeSession
     * @Description: 关闭Session
     * @throws
     */
    public static void closeSession() {
        Session session = threadLocal.get();
        threadLocal.set(null);
        if (session != null) {
            session.close();
        }
    }
}

到这里。Hibernate复习的第一部分也就结束了。主要就是简介一下Hibernate的使用和主要的一些信息。

最后附上一张Hibernate的内置映射类型,也就是Hibernate的类型—Java类型—标准SQL类型三者之间的相应关系:


原文来源:

http://www.cnblogs.com/zhchoutai/p/8592563.html#3926052

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值