Hibernate入门(2):基本使用

 Hibernate 基本使用


在应用程序中使用 Hibernate 框架的基本步骤如下:

1)将 Hibernate 相关依赖库导入项目中(详见 http://blog.csdn.net/al_assad/article/details/77887263 );
2)创建POJO(持久化实体)类,对于数据库中某个表映射为实体
3)创建配置文件( hibernate.cfg.xml ),配置 数据库连接参数,选用数据库引擎 等的配置
4)创建检索或存储持久对象的类(实际使用POJO的逻辑类);

※ 其中对于 POJO 的配置推荐使用注解进行配置,当然也可以使用该POJO独立的xml配置进行配置,但是这种方法会减低项目的可维护性,所以还是推荐使用直接在 POJO 中进行注解配置;



简单示例

以下结合一个简单示例, 来讲解各个步骤,示例说明 :
本示例使用的 hibernate 版本为 5.2
使用的数据库为 MySQL 5.5;
数据库名“ioganes“,使用其中的 ”users“数据表作为示例,结构如下:

  由于 Hibernate 底层使用 JDBC 连接数据库,所以项目依赖中要导入 mysql-connector-java.jar,下载地址: https://dev.mysql.com/downloads/connector/j/

工程结构示意:

 

1)持久化实体类 POJO

demo.Users.java
 
package demo;
import javax.persistence.*;
import java.util.Date;

@Entity                
@Table(name="users")   

public class Users {
   
    @Id                
    @GeneratedValue(strategy= GenerationType.IDENTITY)  
    @Column(name="user_id")   
    private int id;

    @Column(name="user_name")
    private String name;

    @Column(name="user_password")
    private String password;

    @Column(name="create_date")
    @Temporal(TemporalType.DATE)
    private Date createDate;

    @Column(name="user_icon")
    private String icon;

    //省略所有属性的 get、set方法
}


持久化实体类(PO)类本身是一个持久化JavaBean(POJO),用于映射关系型数据库中的某个表单的数据为类对象,在POJO中使用相应的持久化注解用于标注各项持久化标注;
在新版本的hibernate中,提倡使用持久化注解来代替传统的持久化映射配置文件,这样可以增强代码的可读性;

以下是以上示例中出现的标注的解释:
@Entity :声明该类是一个 Hibernate 持久化实体(PO);
@Table:指定该类映射的表,此处映射到 users 表;
@Id: 指定该类的标识属性,即可以唯一标识该类的属性,通常映射到数据表的主键字段;
@GeneratedValue:指定主键的生成策略,这里strategy属性指定为  IDENTITY,即自动增长的主键生成策略,关于这部分详见下;
@Column:指定该类属性映射到数据表的相应字段名(不设置默认使用该属性名称);



2)配置文件

hibernate.cfg.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <!--设置数据库连接参数-->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <!--连接数据库的驱动-->
        <property name="connection.url">jdbc:mysql://localhost/iogames</property> <!--连接数据库的URL-->
        <property name="connection.username">root</property>                <!--连接数据库的用户名-->
        <property name="connection.password">mysql1994assad</property>      <!--连接数据库的密码-->

        <!--设置C3P0数据源参数-->
        <property name="hibernate.c3p0.max_size">20</property> <!--连接池的最大连接数-->
        <property name="hibernate.c3p0.min_size">1</property>  <!--连接池的最大连接数-->
        <property name="hibernate.c3p0.timeout">5000</property> <!--连接池里连接的超时时长-->
        <property name="hibernate.c3p0.max_statements">100</property>  <!--连接池最大缓存存放statement数量-->
        <property name="hibernate.c3p0.idle_test_period">3000</property>
        <property name="hibernate.c3p0.acquire_increment">2</property>
        <property name="hibernate.c3p0.validate">true</property>

        <!--设置数据库方言,本示例中使用 mysql5.5 方言-->
        <property name="dialect">org.hibernate.dialect.MySQL55Dialect</property>
        <!--根据需要自动创建数据库-->
        <property name="hbm2ddl.auto">update</property>
        <!--显示 hibernate 持久化操作所生成的 SQL-->
        <property name="show_sql">true</property>
        <!--将 SQL 脚本格式化后再输出-->
        <property name="hibernate.format_sql">true</property>

        <!--罗列所有的 POJO 持久化类名-->
        <mapping class="demo.Users" />

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

hibernate.cfg.xml 配置文件用于配置数据库连接映射等信息的配置文件,默认放置在项目src目录下,默认命名为" hibernate.cfg.xml  ",当运行构造上下文对象时,会自动调用该文件(当然也可以显式调用),当项目存在调用多个数据库时,可以将其使用多个映射配置文件,在构造上下文对象时显式调用相应文件即可;

以上的配置文件使用了 Hibernate 推荐的 c3p0 数据源代替传统的 DriverManager 来连接数据库,有助于保证最好的的数据库连接性能;


3)操作类

demo.UserManager.java
package demo;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import java.util.Date;

public class UserManager {
    public static void main(String[] args){
        //根据配置文件创建连接注册对象
        StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
                .configure("hibernate.cfg.xml")
                .build();
        //以连接注册对象创建 SessionFactory 对象
        SessionFactory sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
        try{
            //创建一个Session会话对象
            Session session = sessionFactory.openSession();
            //开始事务
            Transaction tran = session.beginTransaction();

            //创建一个Users对象,这部分为实际的数据库CRDU操作区域
            Users user = new Users();
            user.setName("Al-assad");
            user.setPassword("123");
            user.setCreateDate(new Date());
            user.setIcon("1");

            //会话对象保存User,事务提交
            session.save(user);
            tran.commit();

            //关闭 Session、 SessionFactory 连接
            session.close();
            sessionFactory.close();

        }catch(Exception ex){
            StandardServiceRegistryBuilder.destroy(registry);
        }
    }
}


其中关于 Sessionfactory,Session,Transaction 等主要数据库操作对象的解释,可以参见: http://blog.csdn.net/al_assad/article/details/77887263 - 结构体系

对于以上代码的优化,可以拆分出一个 HibernateUtil 专门用管理Session,如下:

HibernateUtil.java

import org.hibernate.*;
import org.hibernate.service.*;
import org.hibernate.boot.registry.*;
import org.hibernate.cfg.*;

public class HibernateUtil{
	public static SessionFactory sessionFactory;
	static{
		try{
			//根据配置文件创建连接注册对象
		     StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
                .configure("hibernate.cfg.xml")
                .build();
             //以连接注册对象创建 SessionFactory 对象
			 sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
		}catch (Throwable ex){
			throw new ExceptionInInitializerError(ex);
		}
	}

	// ThreadLocal可以隔离多个线程的数据共享,因此不再需要对线程同步
	public static final ThreadLocal<Session> session = new ThreadLocal<Session>();

	public static Session currentSession() throws HibernateException{
		Session s = session.get();
		// 如果该线程还没有Session,则创建一个新的Session
		if (s == null){
			s = sessionFactory.openSession();
			// 将获得的Session变量存储在ThreadLocal变量session里
			session.set(s);
		}
		return s;
	}

	public static void closeSession() throws HibernateException{
		Session s = session.get();
		if (s != null)
			s.close();
		session.set(null);
	}
}

UserManager.java
 
public class UserManager {  
    public static void main(String[] args){
            //创建一个Session会话对象
            Session session = HibernateUitl.currentSession();
            //开始事务
            Transaction tran = session.beginTransaction();
            //创建一个Users对象,这部分为实际的数据库CRDU操作区域
            Users user = new Users();
            user.setName("Al-assad");
            user.setPassword("123");
            user.setCreateDate(new Date());
            user.setIcon("1");
            //会话对象保存User,事务提交
            session.save(user);
            tran.commit();
            //关闭Session
            SessionUtil.closeSession();
    }
}




持久化对象操作


持久化对象的状态

实际使用持久化对象 PO 过程中,要先获取 Session 对象,POJO 只有在 Session 的管理下才能完成对数据库的访问,PO 与 Session 的关联关系有以下3种:
  • 瞬态:PO 实例与 Session 从未关联过,此事 PO 实例处于瞬态;
  • 持久化:PO 实例与 Session 关联起来,该示例对应到数据库记录,则该实例处于持久化态;
  • 脱管态:PO 实例曾经与 Session 关联过,但是由于 Session 关闭等原因,PO 实例脱离了 Session 的托管,此时该实例处于脱管态;

改变持久化对象状态的方法

① 持久化实体
将瞬态对象转变为持久化对象,使用 Session 对象的 save(), persist() 方法;
Users user = new User();
user.setName("assad");
session.save(user);
②根据主键加载持久化实体
可以通过Session 的 get() ,load() 方法根据主键加载一个实体,不同的是如果指定主键的实体不存在,get返回null,load抛出一个HibernateException;
User user = session.get(User.class,"20140302");
③更新持久化实体

User user = session.get(User.class,"20140302");
user.setName("assad");
session.flush();
④更新托管主体
对于一个已经脱离了 Session 管理的实体,当程序修改了托管对象的状态后,需要显式地使用新的 Session 来保存这些修改,可以使用 Session 对象的 update(),merge(),updateOrSave() 方法进行保存修改的实体;
update 方法会直接将该对象持久化,如果该对象曾经实体化过,使用update,如果没有,使用save,不确定时,使用 updateOrSave;
merge 方法区别于 update,不会直接持久化该对象,而是向将该对象拷贝一个副本,将该副本持久化,但是原来的对象不持久化,也不重新关联Session;
Session sess1 = sessionFactory.openSession();
User user = sess1.get(User.class,"20140302");
sess1.close();

user.setName("assad");
Session sess2 = sessionFactory.openSession();
sess2.update(user);
⑤删除持久化实体
可以使用 Session 的 delete 方法删除持久化实体,一旦删除该持久化实体,其对应的数据表记录也会被删除;

User user = session.get(User.class,"20140302");
session.delete(user);


 事务操作


Hibernate 的事务操作是通过对 Session 对象的 Transaction 对象来实现的;

事务的提交

 public static void main(String[] args){
            Session session = HibernateUitl.currentSession();
            Transaction tran = session.beginTransaction();   //开始事务
     
            //CRUD操作
            Users user = new Users();
            user.setName("Al-assad");
            user.setPassword("123");
            session.save(user);
     
            tran.commit();   //事务提交
            SessionUtil.closeSession();
    }

事务的回滚

 public static void main(String[] args){
            Session session = HibernateUitl.currentSession();
            Transaction tran = session.beginTransaction();   //开始事务
     
            //CRUD操作
            Users user = new Users();
            user.setName("Al-assad");
            user.setPassword("123");
                
            if(flag) {   //回滚条件
                tran.rollback();    //事务回滚
            }   
                
            session.save(user);
            tran.commit();   //事务提交
            SessionUtil.closeSession();
    }


关于 Transaction 的更多用法,包括设置超时、获取 transaction 状态等,参见:  http://docs.jboss.org/hibernate/orm/5.2/javadocs/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值