Hibernate简单自述
2006-02-23(初建CSDN blog)。没有什么写作能力,此篇文章也是便于自我查阅,鄙人不才让大家见笑。
经过无聊开场白后,开始进入正题:
Hibernate的原理我不想多说了,想知道清查阅这里,建立环境:Eclipse+struts+hibernate
(1)、新建工程MyHibernate,为工程加上Hibernate capabilites和struts Capabilites。
(2)、新建user表,(CID,Username,Password)
(3)、值得注意的是在配置Hibernate Connection Detail时候,一定要勾选(Copy JDBC Driver and add to Classpath 这是3。0版本,3。1或其以上版本都点击)我数据库是oracle 所以必然用Oracle thin Driver,以上配制成功以后,产生hibernate.cfg.xml文件:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">
<!-- DO NOT EDIT: This is a generated file that is synchronized -->
<!-- by MyEclipse Hibernate tool integration. -->
<hibernate-configuration>
<session-factory>
<!-- properties -->
<property name="hibernateProperty">0</property>
<property name="connection.username">my</property>//db用户名
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:CCTV</property>
<property name="dialect">net.sf.hibernate.dialect.Oracle9Dialect</property>
<property name="connection.password">my</property>
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<!-- mapping files -->
<mapping resource="User.hbm.xml"/>//表映射
<mapping resource="Attachment.hbm.xml"/>//表映射
</session-factory>
</hibernate-configuration>
注意<mapping files>是配置与表映射的xml文件,它要与表中字段一一对应!
User.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>
<class name="com.MyHibernate.struts.action.User" table="USER">
<id name="id" column="CID">//标明表中indexID
<generator class="increment" />//increment 数据库id自动增长字段
</id>
<property name="username" column="USERNAME" />//表种字段。
<property name="password" column="PASSWORD" />
</class>
</hibernate-mapping>
说到以上的内容想起hibernate有四种关系的定义:one-to-one, one-to-many, many-to-one, many-to-many。至于为什么要用这些关系方式,我可以大胆的理解成数据库表之间的一种联合查询方式!Out-join等………………
例:(引用)one-to-one
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > <class name="com.MyHibernate.struts.action.User" table="USER" >
<id name="id" type="CID" unsaved-value="0">
<generator class="identity"/>
</id>
<property name="username" column="USERNAME" type="String" length="50"/>
<property name="password" column="PASSWORD" type="String"/>
//建立与Attachment表的连接!
<one-to-one name="Attachment" class="com.user.struts.util.Attachment" outer-join="true"/>
//----
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<!-- DO NOT EDIT: This is a generated file that is synchronized -->
<!-- by MyEclipse Hibernate tool integration. -->
<!-- Created Mon Feb 20 17:07:59 CST 2006 -->
<hibernate-mapping>
<class name="com.user.struts.util.Attachment" table="ATTACHMENT">
<id name="attachmentid" column="ATTACHMENTID" type="java.lang.Long">
<generator class="increment"/>
</id>
<property name="templatenameen" column="templatenameen" type="java.lang.String" not-null="true" />
<property name="itemlistid" column="itemlistid" type="java.lang.Long" not-null="true" />
<property name="attachmentlength" column="attachmentlength" type="java.lang.Long" not-null="true" />
<property name="attachmenttype" column="attachmenttype" type="java.lang.String" />
<property name="attachmentsavepos" column="attachmentsavepos" type="java.lang.String" not-null="true" />
<property name="attachmentsubmitter" column="attachmentsubmitter" type="java.lang.String" />
<property name="attachmentsubmittime" column="attachmentsubmittime" type="java.util.Date" not-null="true" />
<property name="attachmentmemo" column="attachmentmemo" type="java.lang.String" />
<property name="attachmentsequence" column="attachmentsequence" type="java.lang.Long" />
<property name="iscreated" column="iscreated" type="java.lang.String" />
<property name="cipherstate" column="cipherstate" type="java.lang.String" />
<property name="cipherexception" column="cipherexception" type="java.lang.String" />
</class>
</hibernate-mapping>
以上配置可以通过Eclipse来完成!用MyEclipse Database Explorer,第一次使用database explorer时警告我:无法通过oracle.jdbc.driver.OracleDriver连接到数据库!原来需要配置“窗口---首选项”MyEclipse 中Database explorer的Oracle thin Driver想必有人也碰到如此情况把,点击edit通过编辑添加外部jar包(oracle -----Classes12.jar)后终于连接成功!
可以选择左侧的table树,选中新建的user表(要在你所连接的数据库用户下),右键可生成hibernate xml也就是对应在hibernate.cfg.xml的User.hbm.xml文件。
需要注意的是user.hbm.xml中字段名要与接下来要创建的标准java bean getter、setter方法中变量名对应!
要不会抛异常:PropertyNotFoundException: Could not find a setter for property name in class <你的java_bean>
(4)、新建javabean主要是由getter、setter等方法形成的:
public class User{
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public String getPassword() {
return password;
}
public String getUsername() {
return username;
}
public void setId(int id) {
this.id = id;
}
public void setPassword(String password) {
this.password = password;
}
public void setUsername(String username) {
this.username = username;
}
}
(5)、用eclipse 开发hibernate 便会建立一个sessionFactory,这个类封装了一个CurrentSession() return-----net.sf.hibernate.Session方法,其中实现了
public static Session currentSession() throws HibernateException {
Session session = (Session) threadLocal.get();//利用线程控制
if (session == null) {
if (sessionFactory == null) {
try {
cfg.configure("/hibernate.cfg.xml");
sessionFactory = cfg.buildSessionFactory();
}
catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
session = sessionFactory.openSession();
threadLocal.set(session);
}
return session;
}
再struts action中可以直接调用了:
Session session = SessionFactory.CurrentSession();
但还需要有事务的:Transaction tran = session.beginTransaction();
User customer = new User(); //得到一个User_Bean对象
customer.setUsername("customer" + i);
customer.setPassword("password");
session.save(customer);//把User对象保存在session中以便事务的提交!
最后:tran.commit();事务才被提交!
session.flush();
session.close();//别忘关掉!
几种查询方法:Query、find、iterater:
//Query方法查询数据
/*
User user = null;
Query q = session.createQuery("from USER user");
//Query q = session.createQuery("from USER where name=?");//这里的?跟JDBC的PreparedStatement方法一样。
q.setString(0,"my_name");
q.setFirstResult(0);//这句话的意思是说查询结果从第几行开始列出数据
List l=q.list();//返回一个List接口,用来遍历结果集
for(int i=0;i<l.size();i++){
user = (User) l.get(i);//从List中取得一个user对象
System.out.println(user.getUsername());//调用user对象的getUsername方法取得数据库username字段的值
}
*/
//find方法查询数据
/*
User user = null;
List q = session.find("from User");
session.flush();
session.close();
for(int i=0;i<q.size();i++)
{
user= (user) q.get(i);
System.out.println(user.getUsername());
}
*/
//iterate方法查询数据
/*
User user = null;
Iterator q = session.iterate("from User");
while(q.hasNext())
{
user = (User) q.next();
System.out.println(user.getUsername());
}
*/
删除、修改!
//修改数据
/*
Query qq=session.createQuery("from USER user");
User user =(User)session.load(User.class,new Integer(23));
//这里的new Integer(23)意思是修改表中indexID为23的那一行数据,如果使用int的话会出错。
user.setUsername("wang");//把id为23的那一行数据的name字段值改为"wang"
session.flush();
session.close();
有人提出在 Hibernate update持久对象的时候,产生的sql语句是把所有的属性统统set一遍,这样会造成update操作效率很低。Hibernate默认情况下总是在初始化的时候静态生成sql语句,因此不能动态update。但是Hibernate也可以配置为动态产生update和insert语句。
<class name="ClassName" table="tableName" dynamic-update="true|false" dynamic-insert="true|false" />
当设为true的时候,Hibernate在运行期动态产生sql语句,对于insert来说,只插入那些不是null的属性,这样就可以支持数据库字段的default属性;对于update来说,只更新那些修改过的属性。
*/
//删除数据
/*
int abc = session.delete("from USER user where user.id=1");//如果没有找到id为1的数据那么返回0,如果找到返回1。
System.out.println(abc);
session.flush();
session.close();
*/
学习Hibernate主要不是在学习Hibernat怎么配置,用工具怎么生成hbm文件,如果你把重点放在这里,基本上等于白学了Hibernate。Hibernate的精华在于无与伦比的灵巧的对象持久层设计,这些持久层设计经验不会因为你不用Hibernate而丧失掉,我自己学习Hibernate,已经明显感觉到对持久层设计能力已经长了很多经验值了,这些经验甚至不光可以用在Java上,用在.net上也是一样。