Hiberante3学习之路第一节 原创
一、Hibernate环境搭建
1、建立一个普通的java项目,首先进行数据库连接,选择myeclipseDatabaseExplorer界面,在空白处右键new新建连接,连接的驱动模型Drivertemplate选择MySQLConnector,加载驱动,下一步选择你要加载的数据库,连接后台成功后回到java界面。
2、安装配置的三项准备工作
1、添加hibernate库
将下载目录/hibernate3.jar和/lib下的hibernate运行时必须的包加入classpath中:antlr.jar, cglib.jar , asm.jar , commons-collections.jar , commons-logging.jar , jta.jar , dom4j.jar 将hibernatejar包文件添加到java项目中
2、添加hibernate配置文件
配置文件hibernate.cfg.xml和hibernate.properties,XML和properties两种,这两个文件的作用一样,提供一个即可,推荐XML格式,下载目录/etc下是示例配置文件。
可以在配置文件指定:数据库的URL、用户名、密码、JDBC驱动类、方言等。
启动时Hibernate会在CLASSPATH里找这个配置文件。
命名的语法格式,名字是固定的并且位于src目录下
hibernate.cfg.xml <hibernate-configuration> <session-factory> <!-- 连接数据库名称 是在myeclipse中设置的 --> <property name="myeclipse.connection.profile">localhost</property> <!-- 数据库连接的URL --> <property name="connection.url"> jdbc:mysql://localhost:3306/houtai </property> <!-- 数据库的用户名和密码 --> <property name="connection.username">root</property> <property name="connection.password">root</property> <!-- 数据库的驱动 --> <property name="connection.driver_class"> com.mysql.jdbc.Driver </property> <!-- 数据库的方言 --> <property name="dialect"> org.hibernate.dialect.MySQLDialect </property> <!-- 显示sql语句的操作 --> <property name="show_sql">true</property> <!-- 创建表 <property name="hibernate.hbm2ddl.auto">create</property> --> <!-- 添加映射文件 --> <mapping resource="edu/hiber/User.hbm.xml" /> </session-factory> </hibernate-configuration>
3、添加对应表的实体类和映射文件
映射文件(hbm.xml,对象模型和关系模型的映射)。在/eg目录下有完整的hibernate示例。
实体类和数据库表是通过hbm.xml配置文件来完成
命名语法格式:
类名.hbm.xml 与实体类在同一个包中 User.hbm.xml <hibernate-mapping package="hiber"> <!—name实体类名,table对应数据库表的表名--> <class name="User" table="user" catalog="hoteldb"> <id name="id"><!—user表中有一个id的属性--> <!—generator 引用 native代表主键自动增长 --> <generator class="native" /> </id> <!—property成员属性--> <property name="name" length="40" /> <property name="pass" /> <property name="birthday" /> </class> </hibernate-mapping>
在这里有一个面试常考的题就是数据库的主键生成策略
数据库的主键:
代理主键:没有业务逻辑含义
自然主键:有业务逻辑含义
主键生成策略:
Hibernate提供的内置标识符生成器OID
increment: 适用于代理主键, 由Hibernate自动以递增的方式生成标识符, 每次递增为1 identity: 适用于代理主键, 由底层数据库生成标识符. 前提是底层数据库支持自动增长字段类型 sequence: 适用于代理主键, Hibernate根据底层数据库的序列生成标识符. 前提是底层数据库支持序列 hilo: 适用于代理主键, Hibernate根据hi/low算法生成标识符. Hibernate把特定的字段作为"high".默认情况下选用hibernate_unique_key表的next_hi字段 native: 适用于代理主键, 根据底层数据库对自动生成标识符的支持能力, 来选择identify, sequence, 或hilo uuid.hex: 适用于代理主键, Hibernate采用128位的UUID(Universal Identification)算法生成标识符. UUID算法能够在网络环境中生成唯一的字符串标识符. 这种标识符生成策略并不流行, 因为字符串类型的主键比整数类型的主键占用更大的数据库空间 assigned: 适用于自然主键, 由Java应用程序生成标识符.为了能让Java应用程序设置OID,不要把方法声明为private类型.
二、创建数据库
1、在hibernate.cfg.xml配置文件中写创建数据库命令
<!—创建表 --> <property name="hibernate.hbm2ddl.auto">create</property> 它有4个属性: create : 会根据你的model类来生成表,但是每次运行都会删除上一次的表,重新生成表,哪怕2次没有任何改变 create-drop : 根据model类生成表,但是sessionFactory一关闭,表就自动删除 update : 最常用的属性,也根据model类生成表,即使表结构改变了,表中的行仍然存在,不会删除以前的行 validate : 只会和数据库中的表进行比较,不会创建新表,但是会插入新值
2、添加实体类和数据库表的映射
<!-- 添加映射文件 --> <mapping resource="edu/hiber/User.hbm.xml" /> 同时添加show_sql属性 <!-- 显示sql语句的操作 --> <property name="show_sql">true</property>
3、创建表
/**解析配置文件configure()默认解析hibernate.cfg.xml文件并返回Configuration的对象*/ Configuration cfg=new Configuration().configure(); /**根据cfg对象创建一个SchemaExport的对象*/ SchemaExport se=new SchemaExport(cfg); /**创建表的操作*/ se.create(true, true);
三、操作数据库
操作表(增删改查)
package hiber; import java.util.Date; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.Session; public class TestHiber { /**插入的方法*/ public boolean insert() { boolean flag = false; /** * 采用Configuration对象configure方法解析hibernate.cfg. * xml文件并返回一个Configuration的对象 */ Configuration cfg = new Configuration().configure(); /** 根据cfg对中的buildSessionFactory()方法来创一个SessionFactory工厂 */ SessionFactory sf = cfg.buildSessionFactory(); /** 采用sf对象中的openSession的方法创建连接并打开操作的session */ Session session = sf.openSession(); /** 定义个事务对象 */ Transaction tx = null; try { // 开始事务 tx = session.beginTransaction(); User entity=new User("sha","123",new Date()); //执行事务 session.save(entity); //提交事务 tx.commit(); flag=true; } catch (Exception e) { //如果出现导常则回滚事务 if(tx!=null){ tx.rollback(); } e.printStackTrace(); }finally{ //不管事务执行成功与否都要关闭session session.close(); } return flag; } /**查询的方法*/ public User findById(int id){ User user = new User(); /** * 采用Configuration * 对象configure方法解析hibernate.cfg.xml文件并返回一个Configuration的对象 */ Configuration cfg = new Configuration().configure(); /** 根据cfg对中的buildSessionFactory()方法来创一个SessionFactory工厂 */ SessionFactory sf = cfg.buildSessionFactory(); /** 采用sf对象中的openSession的方法创建连接并打开操作的session */ Session session = sf.openSession(); try{ user = (User)session.load(User.class, id); }catch(Exception ex){ ex.printStackTrace(); } return user; } /**查询的方法*/ public User findByGId(int id){ User user = new User(); /** * 采用Configuration * 对象configure方法解析hibernate.cfg.xml文件并返回一个Configuration的对象 */ Configuration cfg = new Configuration().configure(); /** 根据cfg对中的buildSessionFactory()方法来创一个SessionFactory工厂 */ SessionFactory sf = cfg.buildSessionFactory(); /** 采用sf对象中的openSession的方法创建连接并打开操作的session */ Session session = sf.openSession(); try{ user = (User)session.get(User.class, id); }catch(Exception ex){ ex.printStackTrace(); }finally{ session.close(); } return user; } /**更新的方法*/ public boolean update(User entity) { boolean flag = false; /** * 采用Configuration * 对象configure方法解析hibernate.cfg.xml文件并返回一个Configuration的对象 */ Configuration cfg = new Configuration().configure(); /** 根据cfg对中的buildSessionFactory()方法来创一个SessionFactory工厂 */ SessionFactory sf = cfg.buildSessionFactory(); /** 采用sf对象中的openSession的方法创建连接并打开操作的session */ Session session = sf.openSession(); /** 定义个事务对象 */ Transaction tx = null; try { // 开始事务 tx = session.beginTransaction(); entity.setName("lihui"); // 执行事务 session.update(entity); // 提交事务 tx.commit(); flag =true; } catch (Exception ex) { /** 如果出现异常则回滚事务 */ if (tx != null) { tx.rollback(); } ex.printStackTrace(); }finally{ /**不管事务执行成功与否都要关闭session*/ session.close(); } return flag; } /**删除操作*/ public boolean delete(User entity) { boolean flag = false; /** * 采用Configuration * 对象configure方法解析hibernate.cfg.xml文件并返回一个Configuration的对象 */ Configuration cfg = new Configuration().configure(); /** 根据cfg对中的buildSessionFactory()方法来创一个SessionFactory工厂 */ SessionFactory sf = cfg.buildSessionFactory(); /** 采用sf对象中的openSession的方法创建连接并打开操作的session */ Session session = sf.openSession(); /** 定义个事务对象 */ Transaction tx = null; try { // 开始事务 tx = session.beginTransaction(); // 执行事务 session.delete(entity); // 提交事务 tx.commit(); flag =true; } catch (Exception ex) { /** 如果出现异常则回滚事务 */ if (tx != null) { tx.rollback(); } ex.printStackTrace(); }finally{ /**不管事务执行成功与否都要关闭session*/ session.close(); } return flag; } public static void main(String[] args) { TestHiber th = new TestHiber(); boolean insert=th.insert(); if(insert){ System.out.println("插入成功"); } User entity = th.findById(1); boolean flag = th.delete(entity); if(flag){ System.out.println("删除成功"); }else{ System.out.println("删除失败"); } } }
三、通过Myeclipse工具自动添加hibernate类库文件,利用Myeclipse工具反向生成配置文件与DomainClass
1、项目右键,添加类库文Myeclipse,选择AddHibernateCapabilites,选择hibernate核心文件,自动在src目录下创建hibernate的默认配置文件,在DBDriver选择自己配置的链接地址,会自动创建一个hibernateSessionFactroy,我们只需添加一个路径(包)完成。就会自动创建一个hibernate.cfg.xml配置文件,里面自动配置好数据库链接的属性,还会自动创建一个hibernateSessionFactroy的类。
2、反向生产DomainClass和User.hbm.xml文件
首先到myeclipseDatabaseExplorer窗口,选择uesr表右键选择hibernateReverseEngineering反向工程,选择反向的项目,选择创建user对应的javabean,下一步选择主键生成策略IdGenerator这里选择native,完成,切换到java窗口。
3、操作表(增删改查)
package hiber.test; import java.sql.Timestamp; import java.util.Date; import org.hibernate.Session; import org.hibernate.Transaction; import hiber.bean.User; import hiber.sf.HibernateSessionFactory; public class TestUser { /**插入方法*/ public void insert() { /** 直接利用HibernateSessionFactory得到session对象 */ Session session = HibernateSessionFactory.getSession(); Transaction tx = null; try { /** 获取当前session的事务 */ tx = session.getTransaction(); /** 开始事务 */ tx.begin(); /** 瞬时状态对象 */ User entity = new User("yq", "123", new Timestamp(System .currentTimeMillis())); /** 执行插入操作 */ session.save(entity); /** 持久状态对象 */ /** 事务提交 */ tx.commit(); } catch (Exception ex) { if (tx != null) tx.rollback();/**事务回滚*/ ex.printStackTrace(); } finally { /**关闭session*/ session.close(); } /** 脱管状态对象..... */ } /**查询的方法*/ public User findByLId(int id){ User entity = new User(); /**获取session对象*/ Session session = HibernateSessionFactory.getSession(); try{ /**执行操作*/ entity = (User)session.load(User.class, id); }catch(Exception ex){ ex.printStackTrace(); }finally{ /**关闭session*/ session.close(); } return entity; } /**查询的方法*/ public User findByGId(int id){ User entity = new User(); /**获取session对象*/ Session session = HibernateSessionFactory.getSession(); try{ /**执行操作*/ entity = (User)session.get(User.class, id); }catch(Exception ex){ ex.printStackTrace(); }finally{ /**关闭session*/ session.close(); } return entity; } /**更新方法*/ public void update(User entity) { /** 直接利用HibernateSessionFactory得到session对象 */ Session session = HibernateSessionFactory.getSession(); Transaction tx = null; try { /** 获取当前session的事务 */ tx = session.getTransaction(); /** 开始事务 */ tx.begin(); /** 执行更新操作 */ session.update(entity); /** 持久状态对象 */ /** 事务提交 */ tx.commit(); } catch (Exception ex) { if (tx != null) tx.rollback();/**事务回滚*/ ex.printStackTrace(); } finally { /**关闭session*/ session.close(); } /** 脱管状态对象..... */ } /**删除的方法*/ public void delete(User entity) { /** 直接利用HibernateSessionFactory得到session对象 */ Session session = HibernateSessionFactory.getSession(); Transaction tx = null; try { /** 获取当前session的事务 */ tx = session.getTransaction(); /** 开始事务 */ tx.begin(); /** 执行更新操作 */ session.delete(entity); /** 持久状态对象 */ /** 事务提交 */ tx.commit(); } catch (Exception ex) { if (tx != null) tx.rollback();/**事务回滚*/ ex.printStackTrace(); } finally { /**关闭session*/ session.close(); } /** 脱管状态对象..... */ } public static void main(String[] args) { TestUser tu = new TestUser(); User entity = tu.findByLId(2); entity.setName("redarmy"); tu.delete(entity); } }*
这里也有一个面试常考的问题就是对象的状态
对象的状态有三种: 1、瞬时(transient):数据库中没有数据与之对应,超过作用域会被JVM垃圾回收器回收,一般是new出来且与session没有关联的对象。 2、持久(persistent):数据库中有数据与之对应,当前与session有关联,并且相关联的session没有关闭,事务没有提交;持久对象状态发生改变,在事务提交时会影响到数据库(hibernate能检测到)。 3、脱管(detached):也称游离,数据库中有数据与之对应,但当前没有session与之关联;脱管对象状态发生改变,hibernate不能检测到。 瞬时对象可以通过sava或savaorupdate方法转换成持久化对象,对象可以通过get,load,find,iterate方法转换成持久化对象。 持久化对象可以通过delete方法转换成瞬时对象,可以通过evict,close,clear方法转换成脱管对象。 脱管对象可以通过savaorupdate,update,lock方法转换成持久化对象。
希望以上内容对学员学习hibernate有所帮助,以上内容属个人上课记录,如要转发请注明出处。愿你有所收获!