话不多说,hibernate是一个优秀的ORM开源框架,被许多人采用,当然,入门很简单,但要用的很好,需要经验的积累,开源的好处在于可以定制自己需要东西,这也需要对框架本身有很深入的理解。初学建议使用MyEclispe,因为它集成了几乎所有开源框架,使用很方便。下面开始最简单的hibernate例子。
一创建表:首先,必须有个数据库,这里使用的是ORACLE,其次要考虑ID的自增,oracle里我使用序列,其他有自增属性的则方便一些。一下是我用到的表和序列,因为和ibatis使用的是一个,所以名字有点不妥,如果你要使用,请自己改个。
create table IBATISLEARN ( ID NUMBER primary key, ACCOUNT VARCHAR2(13) not null, PASWD VARCHAR2(16) not null, GENDER VARCHAR2(2), PHONE VARCHAR2(11) ) create sequence IBATIS_ID minvalue 1 maxvalue 99999 start with 1 increment by 1 cache 20;
二创建项目和添加hibernate支持:创建项目不必多说,右键-NEW-Web Project--起个名字--finish就OK了,当然接着将MVC三层模式的包建立起来,我这简单的分,接口设计省略了,共3个包:model,dao,services。在添加hibernate支持之前,先配置数据源:在MyEclipse右上角,有个表格右上角带加号的图标:Open Perspective,点开选择My Eclipse Data Explorer,左边窗口,右键-NEW,选择驱动模板(数据库名称),输入驱动名字,连接字符串,用户密码,点击Add jar 在资源管理器里找到你数据库对应的驱动包,最后测试下连接,成功则进入下一步,不成,到网上搜个带图的教程,我懒得截图了 。接下来添加hibernate支持。点击右上角>>图标,选择MyEclipse Java...这个返回代码编辑界面,在项目上右键,选择MyEclipse--Add Hibernate Capabilities;第一页默认或者将copy library...选上,方便移植。next--next,选择刚刚配置的那个数据源,next,session factory前面勾去掉,然后点击finish。添加完成。
三创建映射和实体:使用自动生成,进入到数据源配置视图进入方法如二所说,找到在二步骤中所创建的数据源,双击,接下来因数据库不同而有所不同,此处以oracle为例,mysql的相对而言比较简单,找到创建数据源时所用的数据库用户帐号名,点开,Table,找到一中的表名,这里是ibatislearn,右键,选择Hibernate Reverse...这个选项,Java src folder点右边按钮选择二创建的项目,Java package选择项目下的model包,下面的选项,第一个保持默认,即打勾,选择第一个;第二个打勾即可,无需选择选项,其他保持默认,点击finish完成。
四修改配置文件和映射文件:自动生成的配置文件和映射文件需要修改,全文修改如下:
映射文件Ibatislearn.hbm.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"> <!-- Mapping file autogenerated by MyEclipse Persistence Tools --> <hibernate-mapping> <class name="com.hiber.yanglong.model.Ibatislearn" table="IBATISLEARN" schema="SCOTT"> <id name="id" type="java.lang.Integer"> <column name="ID" precision="22" scale="0" /> <!-- 使用序列自增主键,此处注意id的type,如果数据库是number或者int那么自动生成的是BigDecimal类型 那么就要改为实际的类型或者将type属性去掉,POJO也是要修改的 --> <!-- 自增的数据库用此<generator class="native" /> --> <generator class="sequence"> <param name="sequence">ibatis_id</param> </generator> </id> <property name="account" type="java.lang.String"> <column name="ACCOUNT" length="13" not-null="true" /> </property> <property name="paswd" type="java.lang.String"> <column name="PASWD" length="16" not-null="true" /> </property> <property name="gender" type="java.lang.String"> <column name="GENDER" length="2" /> </property> <property name="phone" type="java.lang.String"> <column name="PHONE" length="11" /> </property> </class> </hibernate-mapping>
可以看到,自动生成的文件ID的类型和修改后的不一样,所以生成的实体Ibatislearn.java也要修改:
package com.hiber.yanglong.model; /** * Ibatislearn entity. @author MyEclipse Persistence Tools */ public class Ibatislearn implements java.io.Serializable { // Fields private int id; private String account; private String paswd; private String gender; private String phone; // Constructors /** default constructor */ public Ibatislearn() { } /** minimal constructor */ public Ibatislearn(int id, String account, String paswd) { this.id = id; this.account = account; this.paswd = paswd; } /** full constructor */ public Ibatislearn(int id, String account, String paswd, String gender, String phone) { this.id = id; this.account = account; this.paswd = paswd; this.gender = gender; this.phone = phone; } // Property accessors public int getId() { return this.id; } public void setId(int id) { this.id = id; } public String getAccount() { return this.account; } public void setAccount(String account) { this.account = account; } public String getPaswd() { return this.paswd; } public void setPaswd(String paswd) { this.paswd = paswd; } public String getGender() { return this.gender; } public void setGender(String gender) { this.gender = gender; } public String getPhone() { return this.phone; } public void setPhone(String phone) { this.phone = phone; } public String toString(){ return "查询到的对象=="+this.account+":"+this.gender+":"+this.paswd+":"+this.phone; } }
下面是修改后的配置文件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"> <!-- Generated by MyEclipse Hibernate Tools. --> <hibernate-configuration> <session-factory> <!-- 数据库方言 --> <property name="dialect"> org.hibernate.dialect.Oracle10gDialect </property> <!-- 数据库连接地址 --> <property name="connection.url"> jdbc:oracle:thin:@127.0.0.1:1521:orcl </property> <!-- 用户名 --> <property name="connection.username">scott</property> <!-- 密码 --> <property name="connection.password">tiger</property> <!-- 数据库JDBC驱动类名 --> <property name="connection.driver_class"> oracle.jdbc.OracleDriver </property> <!-- 在控制台输出SQL --> <property name="show_sql">true</property> <!-- HQL批量更新或删除时所需查询翻译器属性配置节点 --> <property name="hibernate.query.factory_class"> org.hibernate.hql.ast.ASTQueryTranslatorFactory </property> <!-- 需要c3p0.jar支持 --> <!-- 连接池类名 <property name="hibernate.connection.provider_class"> org.hibernate.connection.C3P0ConnectionProvider </property> --> <!-- 最大连接数 <property name="hibernate.c3p0.max_size">20</property> --> <!-- 最小连接数 <property name="hibernate.c3p0.min_size">5</property> --> <!-- 连接最大空闲时间数,秒 <property name="hibernate.c3p0.timeout">5000</property> --> <!-- 缓存预编译语句最大数 <property name="hibernate.c3p0.max_statements">10</property> --> <!-- 连接自动生效前的空闲时间秒数 <property name="hibernate.c3p0.idle_test_period">300</property> --> <!-- 注册ORM映射文件 --> <mapping resource="com/hiber/yanglong/model/Ibatislearn.hbm.xml" /> </session-factory> </hibernate-configuration>
五创建session帮助类:映射和配置文件弄好后,说明程序可以正确在持久化时能够将对象和数据库中的表相对应,但要操作数据,还需要hibernate封装的工具类的支持,是通过session来完成的,所以我们在操作数据时还需要获取session。session帮助类我将其放在DAO包中,MySessionUtil.java代码:
package com.hiber.yanglong.dao; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; /** * session生成类 * @author Dream.YangLong * */ public class MySessionUtil { private static SessionFactory factory=null; /** * 静态语句块,加载类时即生成sessionfactory */ static{ try { Configuration cfg=new Configuration().configure("/hibernate.cfg.xml"); factory=cfg.buildSessionFactory(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static Session getSession(){ return factory.openSession(); } public static SessionFactory getSessionFactory(){ return factory; } public static void closeConnection(Session session){ if(session!=null)session.close(); } }
六创建DAO:有了session,才能操纵数据,操纵数据是通过事务来完成的,DAO简而言之,就是数据访问对象,里面封装了数据操纵的方法。HiDAO.java代码:
package com.hiber.yanglong.dao; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import com.hiber.yanglong.model.Ibatislearn; /** * DAO * @author Dream.YangLong * */ public class HiDAO { /** * 插入 * @param object 需保存对象(或者可指明对象类型) * @return true or false */ public boolean save(Object object) { boolean flag=true; Session session=MySessionUtil.getSession(); try { //事务开始 session.getTransaction().begin(); //执行事务方法 session.save(object); //提交事务 session.getTransaction().commit(); } catch (HibernateException e) { //出现异常回滚事务 session.getTransaction().rollback(); flag=false; e.printStackTrace(); }finally{ //最后关闭数据库连接 MySessionUtil.closeConnection(session); } return flag; } /** * 更新 * @param object 需更新对象,注意必须带有主键值,批量时建议使用HQL语句或者SQL */ public boolean update(Object object) { boolean flag=true; Session session=MySessionUtil.getSession(); try { session.getTransaction().begin(); session.update(object); session.getTransaction().commit(); } catch (HibernateException e) { flag=false; session.getTransaction().rollback(); e.printStackTrace(); }finally{ MySessionUtil.closeConnection(session); } return flag; } /** * 使用HQL批量更新或删除 * 注意需要在配置文件中设置查询翻译器属性 * @param HQL HQL语句 * @return true or false */ public boolean update(String HQL){ Session session=MySessionUtil.getSession(); try { session.getTransaction().begin(); Query updateHQL=session.createQuery(HQL); updateHQL.executeUpdate(); session.getTransaction().commit(); } catch (HibernateException e) { session.getTransaction().rollback(); System.out.println("更新失败!"); e.printStackTrace(); return false; } finally{ MySessionUtil.closeConnection(session); } return true; } /** * 绕过HIberate,使用SQL语句批量更新或删除 * @param SQL sql语句 * @return true or false */ @SuppressWarnings("deprecation") public boolean updateORdelete(String SQL){ Session session=MySessionUtil.getSession(); try { session.getTransaction().begin(); Connection conn=session.connection(); Statement st=conn.createStatement(); st.executeUpdate(SQL); session.getTransaction().commit(); } catch (HibernateException e) { session.getTransaction().rollback(); System.out.println("执行失败!"); e.printStackTrace(); } catch (SQLException e) { session.getTransaction().rollback(); System.out.println("执行失败!"); e.printStackTrace(); } finally{ MySessionUtil.closeConnection(session); } return true; } /** * 删除 * @param object 需删除对象,注意需要带有主键值,批量时建议使用HQL语句或者SQL */ public boolean delete(Object object) { boolean flag=true; Session session=MySessionUtil.getSession(); try { session.getTransaction().begin(); session.delete(object); session.getTransaction().commit(); } catch (HibernateException e) { flag=false; session.getTransaction().rollback(); e.printStackTrace(); }finally{ MySessionUtil.closeConnection(session); } return flag; } /** * 查询单条数据 * @param HQL HQL语句 * @return 已封装数据对象 */ public Object getObject(String HQL) { Object object=null; Session session=MySessionUtil.getSession(); try { session.getTransaction().begin(); //装载单个对象 object=session.createQuery(HQL).uniqueResult(); session.getTransaction().commit(); } catch (HibernateException e) { session.getTransaction().rollback(); e.printStackTrace(); }finally{ MySessionUtil.closeConnection(session); } return object; } /** * 查询多条数据 * @param HQL HQL语句 * @return 数据对象链表 */ @SuppressWarnings("unchecked") public List<Ibatislearn> findWithPage(String HQL) { List<Ibatislearn> list=new ArrayList<Ibatislearn>(); Session session=MySessionUtil.getSession(); try { session.getTransaction().begin(); //装载查询结果 list=(List<Ibatislearn>)session.createQuery(HQL).list(); session.getTransaction().commit(); } catch (HibernateException e) { session.getTransaction().rollback(); e.printStackTrace(); }finally{ MySessionUtil.closeConnection(session); } return list; } }
七创建services类:services通过调用dao来持久化或反持久化对象并进行数据的逻辑处理(业务逻辑),错误处理和一些日志处理。HiServices.java代码:
package com.hiber.yanglong.services; import java.util.List; import com.hiber.yanglong.dao.HiDAO; import com.hiber.yanglong.model.Ibatislearn; /** * Services类 * * @author Dream.YangLong * */ public class HiServices { private HiDAO hidao = new HiDAO(); /** * 新增数据 * * @param ib * 需新增临时对象 * @return true or false */ public boolean addHi(Ibatislearn ib) { return hidao.save(ib); } /** * 删除持久对象 * * @param ib * 封装有需删除对象特征属性的对象 * @return true or false */ public boolean deleHi(Ibatislearn ib) { return hidao.delete(ib); } /** * 查询单个持久对象 * * @param HQL * 查询语句 * @return Ibatislearn对象 */ public Ibatislearn queryOne(String HQL) { return (Ibatislearn) hidao.getObject(HQL); } /** * 查询多个持久对象 * * @param HQL * 查询语句 * @return 持久对象链表 */ public List<Ibatislearn> queryMore(String HQL) { return hidao.findWithPage(HQL); } /** * 更新持久对象 * * @param ib * 封装有需更新的持久对象的特征码和需更新的属性值的对象 * @return true or false */ public boolean updateHi(Ibatislearn ib) { return hidao.update(ib); } }
八测试类:测试类本该放在专门的测试包中,但为了方面,我直接放在了services包中,其实services类可以不写,可直接测试DAO即可,但为了以后的结构体系完整,所以写了下。TestHi.java代码:
package com.hiber.yanglong.services; import java.util.List; import org.hibernate.Hibernate; import com.hiber.yanglong.dao.HiDAO; import com.hiber.yanglong.model.Ibatislearn; /** * 测试类 * @author Dream.YangLong * */ public class TestHi { private Ibatislearn ib; private HiServices his=new HiServices(); private List<Ibatislearn> ibs; public void insert(){ ib=new Ibatislearn(); ib.setAccount("hibernate4"); ib.setPaswd("hipass4"); ib.setGender("男"); ib.setPhone("1002004"); if(his.addHi(ib)){ System.out.println("新增成功!"); } else{ System.out.println("新增失败!"); } } public void delete(){ ib=new Ibatislearn(); ib.setId(15); ib.setAccount("hibernate1"); ib.setPaswd("hipass1"); if(his.deleHi(ib)){ System.out.println("ID为"+ib.getId()+"的数据已删除!"); }else{ System.out.println("删除失败!"); } } public void selectOne(){ ib=new Ibatislearn(); String HQL="from Ibatislearn ib where ib.account="+"'hibernate5'"; ib=his.queryOne(HQL); if(ib!=null){ System.out.println(ib.toString()); }else{ System.out.println("查询失败!"); } } public void selectMore(){ String HQLALL="from Ibatislearn ib"; String condition="bernate"; String HQLCondition="from Ibatislearn ib where ib.account like '%"+condition+"%'"; ibs=his.queryMore(HQLALL); if(ibs==null){ System.out.println("无数据!"); return; } for (Ibatislearn e : ibs) { System.out.println(e); } } public void update(){ ib=new Ibatislearn(); ib.setId(16); ib.setAccount("hibernate2"); ib.setPaswd("hipassg"); ib.setGender("女"); ib.setPhone("1000009"); if(his.updateHi(ib)){ System.out.println("更新成功!"); } else{ System.out.println("更新失败!"); } } public static void main(String[] args) { //---services测试此处为逐一测试,若想全部一起,请自己修改测试方法,建议使用junit比较方便,用法也简单,可以上网查教程---// // TestHi ti=new TestHi(); // ti.insert(); // ti.delete(); // ti.selectOne(); // ti.selectMore(); // ti.update(); // //---批量测试---// HiDAO hid=new HiDAO(); String upHQL="update Ibatislearn set phone=11111111"; String deHQL="delete Ibatislearn where id>5 "; String upSQL="update ibatislearn set phone=22222222"; String deSQL="delete ibatislearn where id<5"; //hid.update(upHQL); //hid.updateORdelete(upSQL); //hid.update(deHQL); hid.updateORdelete(deSQL); } }
至此最简单的hibernate例子完成。附有源码包,有需要的可以自己下载玩一下。