精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-05-15
很早就接触过Hibernate,可由于项目组中一直没有对Hibernate调优特别精通的牛人,所以后来做的系统大多因为是遗留系统,最终还是放弃了Hibernate,转而采用JDBC+连接池+Apache dbUtil等灵活的方法,自己控制连接池连接的关闭,使用dbUtil实现批量操作,效率也还是凑合的。今年换了一家公司,做产品,其中大量用到了Hibernate,我也早认为有必要好好学习一下Hibernate,于是把学习的心得帖出来,希望和想学Hibernate的朋友们一起进步,共同成长。老鸟看见我们有什么错误,欢迎斧正,不吝赐教,可千万别笑话我们呵呵。 好了言归正传,我的第一个HibernateDemo: 1)新建数据库Table CREATE TABLE `user` ( `id` int(11) NOT NULL auto_increment, `name` varchar(100) NOT NULL default '', `age` int(11) default NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
http://blog.csdn.net/hzsasheng/archive/2007/08/04/1725700.aspx 写道
MyISAM:
这个是Mysql表的默认类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法.与其他存储引擎比较,MyISAM具有检查和修复表格的大多数工具. MyISAM表格可以被压缩,而且它们支持全文搜索.它们不是事务安全的,而且也不支持外键。如果事物回滚将造成不完全回滚,不具有原子性。如果执行大量的SELECT,MyISAM是更好的选择。 InnoDB: 这种类型是事务安全的.它与BDB类型具有相同的特性,它们还支持外键.InnoDB表格速度很快.具有比BDB还丰富的特性,因此如果需要一个事务安全的存储引擎,建议使用它.如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。对于支持事物的InnoDB类型的标,影响速度的主要原因是AUTOCOMMIT默认设置是打开的,而且程序没有显式调用BEGIN 开始事务,导致每插入一条都自动Commit,严重影响了速度。可以在执行sql前调用begin,多条sql形成一个事物(即使autocommit打开也可以),将大大提高性能。 2)新建JavaBean,不要忘记要有一个无参数的默认构造函数。 package com.seeyon.bean; /** * User实体类 * * @author Kuang.Hs * @version <b>V1.0</b> 2008-4-28 下午06:12:13 */ public class User { private Integer id;// 编号 private String name;// 姓名 private Integer age;// 年龄 public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public User() { } } 3)新建Hibernate 实体类映射文件,注意主键的生成方式。 <?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> <class name="com.seeyon.bean.User" table="user"> <id name="id" column="id" type="java.lang.Integer" unsaved-value="null"> <generator class="native" /> </id> <property name="name" column="name" type="java.lang.String" /> <property name="age" column="age" type="java.lang.Integer" /> </class> </hibernate-mapping> 4)新建Hibernate 的配置文件。 <?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> <!-- DB参数 --> <property name="connection.username">root</property> <property name="connection.url">jdbc:mysql://127.0.0.1/hbnt?useUnicode=true&characterEncoding=utf8</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="myeclipse.connection.profile">hbnt_mysql</property> <property name="connection.password">123456</property> <property name="connection.driver_class"> com.mysql.jdbc.Driver </property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql ">true</property> <!-- 连接池参数设置 指定使用C3P0,Hibernate默认的连接池有Bug--> <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> <!-- 连接池详细参数 <property name="c3p0.min_size">6</property> <property name="c3p0.max_size">60</property> <property name="c3p0.timeout">1800</property> <property name="c3p0.max_statements">80</property> --> <!-- 实体类mapping映射 --> <mapping resource="com/seeyon/bean/User.hbm.xml" /> </session-factory> </hibernate-configuration> 注: useUnicode=true&characterEncoding=utf8 是为了强制连接Mysql时使用UTF-8. 4)MyEclipse默认生成的HibernateSessionFactory 也帖一下吧,熟悉的就不用看了,帖出来主要是为了防止没有此文件给大家产生疑惑。 package com.seeyon.hibernate; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.cfg.Configuration; /** * Configures and provides access to Hibernate sessions, tied to the * current thread of execution. Follows the Thread Local Session * pattern, see {@link http://hibernate.org/42.html }. */ public class HibernateSessionFactory { /** * Location of hibernate.cfg.xml file. * Location should be on the classpath as Hibernate uses * #resourceAsStream style lookup for its configuration file. * The default classpath location of the hibernate config file is * in the default package. Use #setConfigFile() to update * the location of the configuration file for the current session. */ private static String CONFIG_FILE_LOCATION = "/com/seeyon/hibernate/hibernate.cfg.xml"; private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); private static Configuration configuration = new Configuration(); private static org.hibernate.SessionFactory sessionFactory; private static String configFile = CONFIG_FILE_LOCATION; static { try { configuration.configure(configFile); sessionFactory = configuration.buildSessionFactory(); } catch (Exception e) { System.err.println("%%%% Error Creating SessionFactory %%%%"); e.printStackTrace(); } } private HibernateSessionFactory() { } /** * Returns the ThreadLocal Session instance. Lazy initialize * the <code>SessionFactory</code> if needed. * * @return Session * @throws HibernateException */ public static Session getSession() throws HibernateException { Session session = (Session) threadLocal.get(); if (session == null || !session.isOpen()) { if (sessionFactory == null) { rebuildSessionFactory(); } session = (sessionFactory != null) ? sessionFactory.openSession() : null; threadLocal.set(session); } return session; } /** * Rebuild hibernate session factory * */ public static void rebuildSessionFactory() { try { configuration.configure(configFile); sessionFactory = configuration.buildSessionFactory(); } catch (Exception e) { System.err.println("%%%% Error Creating SessionFactory %%%%"); e.printStackTrace(); } } /** * Close the single hibernate session instance. * * @throws HibernateException */ public static void closeSession() throws HibernateException { Session session = (Session) threadLocal.get(); threadLocal.set(null); if (session != null) { session.close(); } } /** * return session factory * */ public static org.hibernate.SessionFactory getSessionFactory() { return sessionFactory; } /** * return session factory * * session factory will be rebuilded in the next call */ public static void setConfigFile(String configFile) { HibernateSessionFactory.configFile = configFile; sessionFactory = null; } /** * return hibernate configuration * */ public static Configuration getConfiguration() { return configuration; } } 5)简单准备了一个生成随机用户对象的类,供后面调用。这个大家可以随意实现。 package com.seeyon.common; import java.util.ArrayList; import java.util.Random; import com.seeyon.bean.User; /** * 生成常用名字 * * @author Kuang.Hs * @version <b>V1.0</b> 2008-5-12 下午02:30:28 */ public class UserFactory { private static Random random = new Random(); private static ArrayList<String> surnameCache = new ArrayList<String>();// 姓缓存 private static int surnameCacheSize = 0; // surnameCache 长度缓存一下 private static ArrayList<String> secondNameCache = new ArrayList<String>();// 名缓存 private static int secondNameCacheSize = 0; // secondNameCache 长度缓存一下 private static String[] commonNamesTop50 = { "张伟", "王伟", "王芳", "李伟", "王秀英", "李秀英", "李娜", "张秀莲", "刘伟", "张敏", "张丽", "王静", "王丽", "李强", "张静", "李敏", "王敏", "王磊", "李军", "刘洋", "李静", "王勇", "张勇", "王艳", "李杰", "张磊", "王强", "王军", "张杰", "李娟", "张艳", "张涛", "王涛", "李明", "李艳", "王超", "李勇", "王娟", "刘杰", "王秀兰", "李霞", "刘敏", "张军", "李丽", "张强", "王平", "王刚", "王杰", "李桂英", "刘芳" };// 公安部统计全国常见姓名前50名 private static int MIN_USER_AGE = 20; // 员工最小年龄 private static int MAX_USER_AGE = 35; // 员工最大年龄 /** * 随机返回公安部统计全国常见姓名前50的姓名之1 * * @return 全国常见姓名前50之1(随机) */ public static String getCommonNameInTop50ByRandom() { return commonNamesTop50[random.nextInt(commonNamesTop50.length)]; } /** * 根据全国常见前50姓名生成常见的姓名 * * @return */ public static String getRandomCommonName() { if (surnameCache.size() == 0 || secondNameCache.size() == 0) { for (int i = 0; i < commonNamesTop50.length; i++) { String name = commonNamesTop50[i]; surnameCache.add(name.substring(0, 1)); secondNameCache.add(name.substring(1, name.length())); Logger.debug(name + "\t" + surnameCache.get(i) + "\t" + secondNameCache.get(i)); } surnameCacheSize = surnameCache.size(); secondNameCacheSize = secondNameCache.size(); } return surnameCache.get(random.nextInt(surnameCacheSize)) + secondNameCache.get(random.nextInt(secondNameCacheSize)); } /** * 根据全国常见前50姓名生成常见的用户 * * @return */ public static User getRandomCommonNameUser() { User user = new User(); user.setName(getRandomCommonName()); if (MIN_USER_AGE > MAX_USER_AGE) { int temp = MIN_USER_AGE; MIN_USER_AGE = MAX_USER_AGE; MAX_USER_AGE = temp; Logger.error("参数 MIN_USER_AGE 的值不能比 MAX_USER_AGE 大,已纠正。"); } user.setAge(MIN_USER_AGE + random.nextInt(MAX_USER_AGE - MIN_USER_AGE)); return user; } } 6)开始吧,写我了一个Hibernate调用类。 package com.seeyon.part11; import java.util.Date; import java.util.Scanner; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import com.seeyon.bean.User; import com.seeyon.common.Log4jInit; import com.seeyon.common.Logger; import com.seeyon.common.UserFactory; /** * 主线:Hibernate简单插入数据。 * <p> * 扩展:简单插入size条数据,了解Hibernate性能。 * * @author Kuang.Hs * @version <b>V1.2</b> 2008-4-28 下午06:10:26 */ public class HibernateDemo1 { public static int getInputValue() { Scanner sc = new Scanner(System.in); int value = 0; try { value = sc.nextInt(); } catch (RuntimeException e) { Logger.error(e); System.out.println("輸入有誤,請重新輸入:"); return getInputValue(); } return value; } public static void main(String[] args) { new Log4jInit().init(); System.out.println("請輸入要插入數據的條數:"); int size = getInputValue(); Date date_start = new Date(); Logger.info("插入" + size + "条数据的起始时间:" + date_start); // Configuration 负责管理 Hibernate配置信息 Configuration config = new Configuration() .configure("/com/seeyon/hibernate/hibernate.cfg.xml"); // config 建立 SessionFactory // SessionFactory 將用於建立 Session SessionFactory sessionFactory = config.buildSessionFactory(); // 开Session,相当于JDBC的Connection Session session = sessionFactory.openSession(); // 打开事务 Transaction tx = session.beginTransaction(); // 將对象映射至数据库表格中保存 for (int i = 0; i < size; i++) { // 將持久化的物件 User user = UserFactory.getRandomCommonNameUser(); session.save(user); if (i % 100 == 0) { session.flush(); session.clear(); } } tx.commit(); session.close(); sessionFactory.close(); Date date_end = new Date(); Logger.info("插入" + size + "条数据的结束时间:" + date_end); Logger.info("插入" + size + "条数据,共耗时:" + (date_end.getTime() - date_start.getTime()) + "ms"); } } 好啦,到此就全部结束啦,运行一下HibernateDemo1 就有结果啦。还是很简单的吧。Hibernate的难,不是难在Api的学习,而是对ORM思想的理解,和性能的调优配置。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-05-18
觉得比较基础,期待LZ的高级应用和调优的文章
|
|
返回顶楼 | |
发表时间:2008-05-18
小况终于搞 HIBERNATE 了。^_^ 坚持下去。
|
|
返回顶楼 | |
浏览 2661 次