关于Hinernate三个非常重要的类,配置类(Configuration)、会话工厂类(SessionFactory)、会话类(Session)。
- 配置类:Configuration
配置类主要负责管理Hibernate的配置信息以及启动信息。如:hibernate.cfg.xml和*.hbm.xml。
- 会话工厂类:SessionFactory
会话工厂类(SessionFactory)是生成Session的工厂,它保存了当前数据库中所有的映射关系,他只有一个可选的二级缓存对象,并且是线程安全的。会话工厂类是一个非常重量级对象,他的初始化过程会消耗大量的资源。
- 会话类:Session
会话类Session是数据库持久化操作的核心。通过他可以实现数据库的增删改查操作。它不是线程安全的。
- 使用hibernate创建一个简单的程序:
- hibernate必要的jar包。下载hibernate,lib下面required里面都是不必须的。
- 添加hibernate配置文件: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="connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 数据库连接URL -->
<property name="connection.url">jdbc:mysql://localhost:3306/book</property>
<!-- 数据库连接用户名 -->
<property name="connection.username">sa</property>
<!-- 数据库连接密码 -->
<property name="connection.password">123</property>
<!-- 数据库官方语言 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 输出sql语句 -->
<property name="show_sql">true</property>
<!-- 映射文件.通过xml方式 -->
<mapping resource="com/hbn/bean/Book.hbm.xml"/>
</session-factory>
</hibernate-configuration>
添加HibernateUtil.java
public class HibernateUtil {
/**
* 为每个session提供独立的副本
*/
private static final ThreadLocal<Session> THREAD_LOCAL = new ThreadLocal<Session>();
private static SessionFactory sessionFactory = null;
static {
// 创建sessionFactory
rebuildSessionFactory();
}
/**
* 创建sessionFactory
*/
public static void rebuildSessionFactory() {
Configuration cfg = new Configuration().configure();
try {
// 此方法在4.3中已经过时,采用如下方法:
// sessionFactory = cfg.buildSessionFactory();
sessionFactory = cfg.buildSessionFactory(new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build());
} catch (HibernateException e) {
System.out.println("创建sessionFactory异常:" + e);
e.printStackTrace();
}
}
/**
* 获取sessionFactory对象
*
* @return
*/
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
/**
* 获取session
*
* @return 返回回去的session对象
*/
public static Session getSession() throws HibernateException {
Session session = THREAD_LOCAL.get();
if (null == session || !session.isConnected()) {
if (null == sessionFactory) {
// 创建会话工厂
rebuildSessionFactory();
}
// getCurrentSession会自动关闭
// getCurrentSession创建的session韩剧i绑定在当前线程中
// 使用getCurrentSeesion需要在配置文件中加入<property name="hibernate.current_session_context_class">thread</property>
//session = sessionFactory != null ? sessionFactory.getCurrentSession() : null;
// openSession 不会自动关闭,必须手动关闭
// openSession 创建的session不会绑定在本地中
session = sessionFactory != null ? sessionFactory.openSession() : null;
THREAD_LOCAL.set(session);
}
return session;
}
/**
* 关闭Session
*
* @throws HibernateException
*/
public static void clsoeSession() throws HibernateException {
Session session = THREAD_LOCAL.get();
THREAD_LOCAL.set(null);
if (null != session) {
session.close();
}
}
}
需要注意的是:
- 在创建sessionFactory时候,使用以前的方式cfg.buildSessionFactory()的时候,会提示该方法已过时,这个使用可以采用如下方法:
-
sessionFactory = cfg.buildSessionFactory(new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build());
- 在获取session的时候有两种方式:
- 1、使用sessionFactory.getCurrentSession(),这个方式需要注意的是:
- 获取的session在使用完后会立即自动关闭 。
- 获取的session会绑定在当前线程中。
- 使用这种方式必须在配置文件(hibernate.cfg.xml)中加入:
如果使用的是本地事务(jdbc事务) <property name="hibernate.current_session_context_class">thread</property> or 如果使用的是全局事务(jta事务) <property name="current_session_context_class">jta</property>
不然那会报错:org.hibernate.HibernateException: No CurrentSessionContext configured!
-
2、使用openSession获取session:
-
sesion不会自动关闭,回去手动关闭。
-
openSession创建的 session不绑定在当前线程中。
-
- 1、使用sessionFactory.getCurrentSession(),这个方式需要注意的是:
3.创建一个实体类Book.java:
public class Book implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int id;
private String name;
private double price;
private int count;
private String auth;
private String remark;
public Book() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getCount() {
return count;
}
public void setCount(int count) {
count = count;
}
public String getAuth() {
return auth;
}
public void setAuth(String auth) {
this.auth = auth;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
添加实体类的映射文件:Book.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>
<class name="com.hbn.bean.Book" table="book">
<!-- id值 -->
<id name="id" column="id" type="int">
<generator class="native" />
</id>
<property name="name" type="string">
<column name="name" />
</property>
<property name="price" type="double">
<column name="price" />
</property>
<property name="count" type="int">
<column name="count" />
</property>
<property name="auth" type="string">
<column name="auth" />
</property>
<property name="remark" type="string">
<column name="remark" />
</property>
</class>
</hibernate-mapping>
该配置必须最好是和实体类放在同一目录,及实体类在那,他就在那。
添加后,需要在hibernate.cfg.xml中添加该映射文件,供hibernate加载:
<!-- 映射文件 -->
<mapping resource="com/hbn/bean/Book.hbm.xml"/>
基本创建好后,可以编写一个test来测试啦!
public class TestBook {
@Test
public void test() {
Book book = new Book();
book.setName("hibernate");
book.setAuth("mrk");
book.setCount(1);
book.setPrice(12.5);
book.setRemark("hibernate Test");
// 使用hibernate
Session session = null;
try {
session = HibernateUtil.getSession();
session.beginTransaction();
session.save(book);
session.getTransaction().commit();
System.out.println("保存成功!");
} catch (Exception e) {
System.err.println("保存失败:" + e);
e.printStackTrace();
if (null != session) {
session.getTransaction().rollback();
}
} finally {
HibernateUtil.clsoeSession();
}
}
}
运行结果:
INFO: HHH000397: Using ASTQueryTranslatorFactory
Hibernate: insert into book (name, price, count, auth, remark) values (?, ?, ?, ?, ?)
六月 22, 2016 11:23:17 下午 org.hibernate.engine.jdbc.spi.SqlExceptionHelper$StandardWarningHandler logWarning
WARN: SQL Warning Code: 1265, SQLState: 01000
六月 22, 2016 11:23:17 下午 org.hibernate.engine.jdbc.spi.SqlExceptionHelper$StandardWarningHandler logWarning
WARN: Data truncated for column 'price' at row 1
保存成功!
hibernate第一次坑太多,使用注解的时候如果出现 unkown entity...检查下你注解使用的Entity是不是hibernate的,如果是请换位javax.xxx.entity的。