Hibernate生猛上手
最近,一直在回复总结以前的知识,备忘,毕竟不如烂笔头。
Hibernate是java web的一个持久层框架,提供了高校的对象关系型数据库的持久化服务,将持久化服务从软件特务层完全提取出来。
Hibernate的核心设计理念是ORM(Object Relational Mapping,对象到关系的映射)。ORM的作用是在关系型数据库和java对象之间做一个自动映射,将数据库中的数据表映射成为对象,即是持久化类。然后,便可以以对象的形式操作数据库,减少应用开发过程中的数据持久化的编程任务。Hibernate通过持久化类(*.java)、映射文件(*.hbm.xml)和配置文件(*.cfrg.xml)操作数据库。
以下便是,Hibernate实例了。
一、 Hibernate的获取。
可以通过登录官网www.hibernate.org ,进行下载。也可以通过本文章的链接 http://pan.baidu.com/s/1hqtsRaO 进行下载。
二、 Hibernate开发步骤
1、 创建mysql数据库
如图,我在本地已经创建了一个名为“cyw”的数据库。以下大多以citytable表进行示例。
2、 创建java project
如图,我在本地创建了一个java web工程AirHibernate。
3、 添加jar包
因为我使用的是Hibernate-3.2,所以,在需将lib中的jar包还有Hibernate3.jar包,以及mysql驱动jar包导入java工程之中。
4、 配置Hibernate配置文件hibernate.cfg.xml
注:Hibernate配置文件从形式来讲有两种主要的格式:一种是Java属性文件,即*.properties,这种配置格式主要定义连接各种数据库需要的参数;还有一种是XML格式的文件,这种文档除了可以定义连接各种数据库需要的参数,还可以定义程序中用的映射文件。所以一般情况下使用XML格式的配置文档。
properties形式的配置文件默认文件名是hibernate.properties,一个properties形式的配置文件内容如下所示:
建议在官网了解相关信息,http://docs.jboss.org/hibernate/orm/5.0/quickstart/html/#tutorial-native :
所以,需要在src目录下创建文件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:3306/cyw</property> <!-- 数据库用户名 --> <property name="connection.username">root</property> <!-- 数据库用户密码 --> <property name="connection.password"></property> <!-- Hibernate方言 --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 更新数据库方式 --> <property name="hbm2ddl.auto">update</property> <!-- 显示执行的SQL语句 --> <property name="show_sql">true</property> <!-- 是否格式化sql语句 <property name="format_sql">true</property>--> <!-- 映射文件 --> <mapping resource="com/cyw/data/City.hbm.xml"/> </session-factory> </hibernate-configuration>
其中,对hbm2ddl.auto进行说明一下(有四个值):
create:每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。
create-drop :每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。
update:最常用的属性,第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据 model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等应用第一次运行起来后才会。
validate::启动时验证现有schema与你配置的hibernate是否一致,如果不一致就抛出异常,并不做更新。
5、 编写持久化类
在hibernate中,持久化类是操作的对象。通过对象-关系映射(ORM),用持久化类来描述数据库表结构信息,并且通过操作持久化类来操作数据库表。
package com.cyw.data;
public class CityTable {
private int id;
private String city;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
持久化类要符合基本的JavaBean编码规范,即POJP编程模型:
(1) 实现一个默认的构造函数
(2) 提供一个标识属性(可选)
标识属性一般映射是数据库表的主键字段。
(3) 使用非final类(可选)
(4) 为属性声明访问器(可选)
持久化类属性应为private,并且有其set()和get()方法。
6、 Hibernate映射
在src目录下,创建一个*.hbn.xml映射文件。处理对象映射。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- 对持久化类CityTable的映射配置 schema属性:指定该文件映射表所在的数据库的schema名称 package属性:指定一个包的前缀 --> <hibernate-mapping> <!-- name指定持久化类的全限定类名;table属性是持久化类所映射的数据库表名--> <class name="com.cyw.data.CityTable" table="citytable"> <!-- 持久类的唯一性标识 --> <id name="id" column="id" type="int"> <generator class="native"/><!-- generator定义主键的生成策略 --> </id> <!-- 非主键映射 --> <property name="city" not-null="true" length="20"> <column name="city"></column> </property> <!-- 或者是 <property name="city" column="city" not-null="true" length="20"></property> 另外属性有:unique 该数据库字段是否唯一,为布尔型;lazy 是否延迟抓取,为布尔类型 --> </class> </hibernate-mapping>
7、 业务开发
先是一个工具类,包含增删改查。
package com.cyw.tools;
import java.io.Serializable;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class HibernateUtils {
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
private static SessionFactory sessionFactory = null;
static{
Configuration cfg = new Configuration().configure();
sessionFactory = cfg.buildSessionFactory();
}
/**
* 获取Session
* @return
*/
public static Session getSession(){
Session session = threadLocal.get();
if(session == null || !session.isOpen()){
if(sessionFactory == null){
rebuildSessionFactory();
}
session = (sessionFactory != null)?sessionFactory.openSession():null;
threadLocal.set(session);
}
return session;
}
private static void rebuildSessionFactory() {
Configuration cfg = new Configuration().configure();
sessionFactory = cfg.buildSessionFactory();
}
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
public static void closeSession(){
Session session = (Session)threadLocal.get();
threadLocal.set(null);
if(session != null){
session.close();
}
}
public static void add(Object obj){
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
session.save(obj);
//区别:save()方法如果没有开启事务,它会执行一条插入语句,但之后由于没有提交事务,它又进行
//session.persist(obj);
//回滚了,而persist()方法在没有开启事务的时候,它根本不会去执行,即没有那条插入语句
tx.commit();
}finally{
if(session!=null){
session.close();
}
}
}
//修改
public static void update(Object obj){
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
session.update(obj);
tx.commit();
}finally{
if(session!=null){
session.close();
}
}
}
//删除
public static void delete(Object obj){
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
session.delete(obj);
//session.flush();
tx.commit();
}finally{
if(session!=null){
session.close();
}
}
}
//查找 不需要开启事务
public static Object findById(Class clazz,Serializable id){
Session session = null;
try {
session = HibernateUtils.getSession();
//这里需要区分一下get()与load()的区别,load()不会立即//去访问数据库只有在第一次使用的时候才会去加载(懒加载);
//load方法永远不可能返回空对象(如果不存在,其会产生一个user的子类)具体可以去查资料区别这两个方法
//Object obj = session.load(clazz, id);
Object obj = session.get(clazz, id);
return obj;
}finally{
if(session!=null){
session.close();
}
}
}
}
package com.cyw.main;
import com.cyw.data.CityTable;
import com.cyw.tools.HibernateUtils;
/**
* http://blog.youkuaiyun.com/fb281906011/article/details/17632809
* @author cyw
*
*/
public class Main {
public static void main(String[] args){
// //这里千万注意,不能写成Configuration cfg = new Configuration();否则会报Hibernate Dialect must be explicitly set 错误信息将我们误导
// //;实际上前面我们已经配置了mysql的方言;
// Configuration cfg = new Configuration().configure();//对于configure()方法,我们可以引入其源代码进行查看,其会在类路
// //径下自动去加载一个默认的hibernate.cfg.xml文件;如果我们想换其他名字,可以使用其重载方法,具体可以查看其源代码(下载的压缩包中有)
// SessionFactory factory = cfg.buildSessionFactory();
// CityTable city = new CityTable();
// city.setCity("Kobe");
// Session session = null;
// Transaction tx = null;
// try {
// session = factory.openSession();
// tx = session.beginTransaction();//开启事务
// session.save(city);//进行保存
// tx.commit();//提交事务
// } catch (HibernateException e) {
// if(tx!=null){
// tx.rollback();//回滚事务
// }
// throw e;//必须抛出异常
// }finally{
// if(session!=null){
// session.close();//关闭session
// }
// }
//2.
CityTable city = new CityTable();
city.setCity("cyw2");
HibernateUtils.add(city);//添加
// city.setCity("Jams");
// HibernateUtils.update(city);//修改
// HibernateUtils.delete(city);//删除
// CityTable city1 = (CityTable) HibernateUtils.findById(CityTable.class, city.getId());//查找
// if(city1 == null){
// System.out.println("null");
// }
// System.out.println("city1:"+city1.getCity());
}
}
三、 结果
数据库多出了一条记录。
更多,可以参考文章:http://blog.youkuaiyun.com/zs234/article/details/9197671