hibernate 简单实例,没有和spring整合单独使用hibernate 来实现增删该查。
一、小demo
1、正题结构图:
当看到这个结构图时发现hibernate 有两个配置文件,一个为hibernate 的主配置文件,其中配置数据源信息、事务以及 O/R 映射关系配置文件路径配置,另一个就是O/R映射关系表,这里的话 cfg.xml 就是hibernate 的主配置文件而Event.hbm.xml 就是映射文件。
2、hibernate 的主配置文件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> <!-- Database connection settings --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/event</property> <property name="connection.username">root</property> <property name="connection.password">admin</property> <!-- JDBC connection pool (use the built-in) --> <property name="connection.pool_size">1</property> <!-- SQL dialect --> <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property> <!-- Enable Hibernate's automatic session context management --> <property name="current_session_context_class">thread</property> <!-- jdbc transaction --> <property name="hibernate.transaction.factory_class"> org.hibernate.transaction.JDBCTransactionFactory </property> <!-- Disable the second-level cache --> <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> <!-- Echo all executed SQL to stdout --> <property name="show_sql">true</property> <!-- Drop and re-create the database schema on startup --> <property name="hbm2ddl.auto">update</property> <!--映射文件路劲--> <mapping resource="com/test/Event.hbm.xml"/> </session-factory> </hibernate-configuration>
3、O/R 映射文件配置文件:
<?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"> <hibernate-mapping package="com.test"> <class name="Event" table="EVENTS"> <id name="id" column="id"/> <property name="name" column="name"/> <property name="age" column="age"/> </class> </hibernate-mapping>
4、Event :
package com.test; import java.util.Date; import javax.persistence.Entity; import javax.persistence.Table; @Entity @Table(name = "events") public class Event { private int id; private String name; private String age; public Event(){} 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 String getAge() { return age; } public void setAge(String age) { this.age = age; } }
package com.test; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try { // Create the SessionFactory from hibernate.cfg.xml return new Configuration().configure().buildSessionFactory(); } catch (Throwable ex) { // Make sure you log the exception, as it might be swallowed System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } }
package com.test; import java.util.Iterator; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.Transaction; import org.springframework.transaction.annotation.Transactional; public class EventManager { public static void main(String[] args) { EventManager mgr = new EventManager(); mgr.createAndStoreEvent(3,"whd3","233" ); HibernateUtil.getSessionFactory().close(); } private void createAndStoreEvent(int id, String name,String age) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); Transaction trans= session.beginTransaction(); Event theEvent = new Event(); theEvent.setId(id); theEvent.setName(name); theEvent.setAge(age); //添加 //session.save(theEvent); //保存或更新,hibernate是按照id走的,如果有则更新如果没有则添加 //session.saveOrUpdate(theEvent); //更新 //session.update(theEvent); //删除 //session.delete(theEvent); //查询 Query query = session.createQuery("from Event "); List<Event> list = query.list(); Iterator<Event> it= list.iterator(); while(it.hasNext()){ Event event= it.next(); System.out.println(event.getId()); } trans.commit(); } }
写这个demo时看到了如下文章,文章写的比较详细,如果初学很方便
二、文章转载:
1、mysql中库表News,字段如下
id | int | auto_increment | primary key title | varchar content | varchar date | varchar
Session session = HibernateSessionFactory.getSession(); News news = new News(); news.setContent("my content"); news.setTitle("my title"); news.setDate("my date"); //news是VO Transaction trans = session.beginTransaction(); session.save(news); //news是PO trans.commit(); //任何有关数据库更新的操作都是commit后进数据库的 HibernateSessionFactory.closeSession();
Session session = HibernateSessionFactory.getSession(); News news = new News(); news.setId(103); //id不可少,Hibernate只通过id来查找数据库 news.setContent("update content"); news.setTitle("update title"); Transaction trans = session.beginTransaction(); session.update(news); trans.commit(); HibernateSessionFactory.closeSession();注意这里我们更新数据不想对date进行更新,所以没写 setDate ,但Hibernate会认为我们是想把date设置为null,所以如果要更新表中一些字段,最好用下面的方法。
Session session = HibernateSessionFactory.getSession(); Transaction trans = session.beginTransaction(); News news = (News)session.get(News.class, 103); //*****(1) news.setDate("update date"); //*****(2) session.save(news); //*****(3) trans.commit(); HibernateSessionFactory.closeSession();这里其实对数据库进行了两次操作,(1)时从数据库中把相应纪录查找出来,这里news是一个PO,(2)对PO进行date的更新,其他数据没变,然后(3)保存,由于(1)查出的数据就有title,content,所以保存时候title和content都不会是null
4、Hibernate的delete操作
Session session = HibernateSessionFactory.getSession(); Transaction trans = session.beginTransaction(); News news = new News(); news.setId(8); //用下面那句效果一样,只是多了句select session.delete(news); trans.commit(); HibernateSessionFactory.closeSession(); 注意,只能通过id来删除数据,不能通过title或content来删除,会报缺少标示符错误。使用hql来删除(可作批量删除)
Session session = HibernateSessionFactory.getSession(); String hql = "delete Billdetail where name>'detailName1'"; Query query = session.createQuery(hql); int ref = query.executeUpdate(); session.beginTransaction().commit(); System.out.println("delete dates=>"+ref); //操作条数 session.close();
Hibernate的select操作非常丰富,这里写常用的
(1)、criteria查询
Session session = HibernateSessionFactory.getSession(); Criteria c = session.createCriteria(News.class);//News是类,所以N大写 c.add(Expression.lt("date", "date5")); c.add(Expression.between("date", "date1", "date8")); c.addOrder(Order.desc("date")); List<News> list = c.list(); for(int i=0;i<list.size();i++) { System.out.println(list.get(i).getId()+":"+list.get(i).getDate()); } HibernateSessionFactory.closeSession();
比较符合面向对象的概念,因为库表和JAVA类已经作了映射关系,注意Hibernate的所有操作都是针对JAVA类的,而不是库表,所以要区分大小写。
上面的查询相当于sql是: select * from news where date < 'date5' and date BETWEEN 'date1' and 'date8' ORDER by date desc;
(2)、HQL查询
Query query = session.createQuery("from News "); List<News> list = query.list(); //遍历同上HQL是Hibernate主推的查询方式,和普通SQL语句也比较接近,但很重要一点不同就是HQL中from后面的是JAVA类名,不是库表名,切忌!!!其它就是如果查询全字段 "select *" 可以省略不写。
当不是查询全字段,或者是从两张表中联合查询数据时,返回的是一个数组:
Session session = HibernateSessionFactory.getSession(); Query query = session.createQuery("select n.id,n.title,u.username from News as n,User u"); List list = query.list();//这里每一行都是一个1维数组 for(int i=0;i<list.size();i++) { Object []o = (Object[])list.get(i); //转型为数组 int id = (Integer)o[0]; //和select中顺序的类型相对应,可以是类 String title = (String)o[1]; String username = (String)o[2]; System.out.println("id:"+id+" , "+"title"+title+" , "+username); } HibernateSessionFactory.closeSession();查询结果集的大小(和Hibernate2中稍微有点不同)
(Integer)session.createQuery("select count(*) from User").iterate().next();
<span style="font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"> List<News> list = session.createSQLQuery("select * from News").addEntity(News.class).list();</span>addEntity 不能忘记,这种查询方式是把查询好的结果放到一个实体中,再遍历操作,不推荐使用。
SQLQuery query = session.createSQLQuery("select id,title from News"); query.addScalar("id", Hibernate.INTEGER); //注册字段类型,同下 query.addScalar("title",new org.hibernate.type.StringType()); List list = query.list(); for(int i=0;i<list.size();i++) { Object[] o = (Object[])list.get(i); int id = (Integer)o[0]; String title = (String)o[1]; System.out.println("id:"+id+" , title:"+title); }javabean的属性可以作为命名的查询参数(HQL)
Session session = HibernateSessionFactory.getSession(); Transaction trans = session.beginTransaction() Query query = session.createQuery("from room in class Room where room.name=:a") query.setParameter("a", "room1"); //和prepareStatement相似 // Room room1 = new Room(); // room1.setName("room1"); // Query query = session.createQuery("from room in class Room where room.name=:name"); //如果用javabean设置参数来查询,=:name的name一定和Room中对应 // query.setProperties(room1); List<Room> list = query.list(); for(int i=0;i<list.size();i++) { System.out.println(list.get(i).getName()+":"+list.get(i).getDescription()); } trans.commit(); HibernateSessionFactory.closeSession()
首先获取session 然后调用session 中的save update 方法进行操作数据库,当操作结束后我们要关闭session。这个过程感觉和mybatis 很像,也许可能是因为数据库操作的整个流程都是这样。
注意: 这里要注意,在使用hibernate 时在开始时我们要获取事务,在执行结束后我们关闭事务。 这时必须要这么做的(使用jdbc 事务)