/** by metaphy 2005-12-26 v0.01*/
昨天面试,被打击的不轻,9道基础题目,错了4道,其中一个就是关于hibernate的;这种接触过就会,没接触过就不会的题目,我看不出能考察出什么东西;但公司就是如此的不讲道理,会就是水平高,反之就低,仔细想想,真是行业的悲哀。
一、开发环境OS:WindowsXPJDK:1.4.2Database:SqlServer2000 (sp3)JDBC驱动:MicrosoftHibernate:2.1(hibernate2.jar,889k)Eclipse:3.0(需要有数据库的知识和Eclipse的知识)
装好DB后,顺手建立一个表,安装JDBC的jar包,将其加入工程;随后,写了一个测试类:[code]//DbTestimport java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.Statement;
public class DbTest{ public static void main(String args[]){ try{ Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver"); Connection conn =DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433;User=sa;Password=sa;DatabaseName=gtest"); Statement stmt=conn.createStatement(); String sql="select * from department"; ResultSet rs = stmt.executeQuery(sql); while(rs.next()) { System.out.println("records:/t"+rs.getString("department_name")); } rs.close(); stmt.close(); conn.close(); } catch(Exception ex) { System.err.println(ex.getMessage()); } /*写到这,不禁想起网上的那篇“你擦了吗”的帖子,嘿嘿,测试用的例子嘛,先这样写吧*/ }}[/code]编译,运行,一切正常;数据库的记录清楚的打印出来了。
到这里,有必要说一下我在Eclipse下面所建工程的结构及数据库结构:hibapp- |-src (源文件) |-lib (库文件,现在包括3个jdbc驱动,一个hibernate2.jar) |-bin (output directort)
p.s.由于hibernate 内部运行的时候需要许多的关联库(一般是apache的公共包),所以,相关的涉及到的jar包都需要包含进来;我的最终的jar目录(有的没有用到的我也给加进来了):
307,930 cglib-full-2.0.2.jar118,726 commons-beanutils.jar165,119 commons-collections.jar109,096 commons-digester.jar 63,980 commons-lang.jar 31,605 commons-logging.jar 46,865 commons-validator.jar486,522 dom4j.jar 53,232 ehcache-0.9.jar (注:编译的时候,让这个弄的很郁闷,找了半天,才发现需要这个包)935,212 hibernate2.jar604,048 ifxjdbc.jar146,718 jdom.jar104,076 jolt.jar 8,812 jta.jar352,291 log4j-1.2.9.jar286,707 msbase.jar 67,024 mssqlserver.jar 58,903 msutil.jar 13,091 odmg-3.0.jar
数据库gtest--表 departmentCREATE TABLE [dbo].[department] ( [department_id] [int] IDENTITY (1, 1) NOT NULL , [department_name] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL ) ON [PRIMARY]GO
二、Hibernate配置Hibernate的本质是一个“ORM”映射框架;对于上面例子(DbTest)中的数据库链接硬编码,hibernate采用配置文件的办法来管理,在进行config的时候从中读取信息,信息不外乎数据库链接url,用户名/密码,数据库名等,当然还有一些其他的配置信息,如下:[code]//hibernate.cfg.xml<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd"><hibernate-configuration> <!-- SessionFactory 配置 --> <session-factory> <!-- 数据库URL --> <property name="hibernate.connection.url"> jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=gtest </property> <!-- 数据库JDBC驱动 --> <property name="hibernate.connection.driver_class"> com.microsoft.jdbc.sqlserver.SQLServerDriver </property> <!-- 数据库用户名 --> <property name="hibernate.connection.username"> sa </property> <!-- 数据库用户密码 --> <property name="hibernate.connection.password"> sa </property> <!--dialect 每个数据库都有其对应的Dialet以匹配其平台特性 --> <property name="dialect"> net.sf.hibernate.dialect.SQLServerDialect </property> <!-- 是否将运行期生成的SQL输出到日志以供调试 --> <property name="hibernate.show_sql"> True </property> <!-- 是否使用数据库外连接 --> <property name="hibernate.use_outer_join"> True </property> <!-- 事务管理类型,这里我们使用JDBC Transaction --> <property name="hibernate.transaction.factory_class"> net.sf.hibernate.transaction.JDBCTransactionFactory </property> <!--映射文件配置,注意配置文件名必须包含其相对于根的全路径 --> <mapping resource="test/hib/tables/Department.hbm.xml"/> </session-factory></hibernate-configuration>[/code]
通用的配置文件配好后,我们需要对类-表的映射配置文件,hibernate提供了一个自动生成工具Middlegen,用起来也很简单(需要ant),当然需要修改一些配置,鉴于个人环境的不同,可能遇到的问题也不一样;偶省略过程以免误导(上过当),只把最后的结果写下:[code]//Department.hbm.xml<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > <hibernate-mapping><!-- Created by the Middlegen Hibernate plugin 2.1
http://boss.bekk.no/boss/middlegen/ http://www.hibernate.org/-->
<class name="test.hib.tables.Department" table="department"> <id name="departmentId" type="int" column="department_id" > <generator class="native" /> </id>
<property name="departmentName" type="java.lang.String" column="department_name" not-null="true" length="50" />
<!-- Associations --></class></hibernate-mapping>
//这个是POJO(plain ordinary java object)//Department.javapackage test.hib.tables;
import java.io.Serializable;
public class Department implements Serializable { private int departmentId ; private String departmentName ; public int getDepartmentId() { return departmentId; } public void setDepartmentId(int departmentId) { this.departmentId = departmentId; } public String getDepartmentName() { return departmentName; } public void setDepartmentName(String departmentName) { this.departmentName = departmentName; }}[/code]
三、Hibernate开发映射与POJO 写好后,就该练习一些基本的增删查改的东西了;下面是个基本的练习:[code]package test.hib.bizlogic;
import java.io.File;import java.util.List;
import net.sf.hibernate.HibernateException;import net.sf.hibernate.Session;import net.sf.hibernate.SessionFactory;import net.sf.hibernate.Transaction;import net.sf.hibernate.cfg.Configuration;import test.hib.tables.Department;
public class BizDepartment { Configuration config ; SessionFactory sessionFactory ; Session session ; public BizDepartment(){ try { File file = new File("D://ecampus//hibapp//src//test//hib//tables//hibernate.cfg.xml"); //这里用硬编码配置config;据说将文件路径加入环境变量Path,可以直接这样写: //config = new Configuration().configure(); 不过我试验了一下,发现不行 config = new Configuration().configure(file); sessionFactory = config.buildSessionFactory(); }catch(Exception e){ e.printStackTrace() ; } } public Department departmentFind(String depName){ Department dep = null ; String hql = " from Department where department_name ='"+ depName +"'" ; try { session = sessionFactory.openSession(); List list = session.find(hql) ; if (list!=null && list.size()>0){ dep = (Department) list.get(0); } session.flush(); session.close(); }catch (HibernateException e){ e.printStackTrace(); } return dep ; } public void departmentAdd(Department dep){ try { session = sessionFactory.openSession(); Transaction tx= session.beginTransaction(); if (dep != null && dep.getDepartmentName()!=null){ session.save(dep); tx.commit(); session.flush() ; } session.close(); } catch (HibernateException e) { e.printStackTrace(); } } public void departmentModify(Department dep){ try { session = sessionFactory.openSession(); Transaction tx= session.beginTransaction(); if (dep != null && dep.getDepartmentName()!=null){ session.update(dep) ; tx.commit(); session.flush() ; } session.close(); } catch (HibernateException e) { e.printStackTrace(); } } public void departmentDelete(Department dep){ try { session = sessionFactory.openSession(); Transaction tx= session.beginTransaction(); if (dep != null ){ session.delete(dep); tx.commit(); session.flush() ; } session.close(); } catch (HibernateException e) { e.printStackTrace(); } } public static void main(String[] args) { BizDepartment bd = new BizDepartment(); String depName = "测试部" ; Department dep = bd.departmentFind(depName) ; if (dep!=null){ System.out.println(depName+ "ID :" + dep.getDepartmentId()) ; dep.setDepartmentName(depName+"_修改"); bd.departmentModify(dep); } //bd.departmentDelete(dep) ; }}[/code]
编译通过,ok!~
p.s.在学习一个新的技术的时候,一定要同时参考几种(3种以上)资料,切忌只看一篇文章并照着它的例子做;因为你要知道的是其后的道理,而不仅仅是怎么做;并且许多例子因为种种原因,并不能一下就能运行成功
