参考资料:
<<深入浅出Hibernate>>
<<sring live中文版>>
首先学习 针对一个表用Hibernate进行操作:
应用的 常用的USER表,实现用户登陆和查找,删除,修改等功能
POJO代码如下:
public class BaseObject {
public String toString() {
return ToStringBuilder.reflectionToString(this,
ToStringStyle.MULTI_LINE_STYLE);
}
public boolean equals(Object o) {
return EqualsBuilder.reflectionEquals(this, o);
}
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
}
public class User extends BaseObject {
private Long uid;
private String passMD5; //pwd
private String name; //用户名
private String city; //居住城市
private String email; //EMAIL
private Date regist_date;//注册时间
private String shengfen; //come from.
private String agentId;
public Long getUid() {
return uid;
}
public void setUid(Long uid) {
this.uid = uid;
}
public String getPassMD5() {
return passMD5;
}
public void setPassMD5(String passMD5) {
this.passMD5 = passMD5;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getRegist_date() {
return regist_date;
}
public void setRegist_date(Date regist_date) {
this.regist_date = regist_date;
}
public String getShengfen() {
return shengfen;
}
public void setShengfen(String shengfen) {
this.shengfen = shengfen;
}
public String getAgentId() {
return agentId;
}
public void setAgentId(String agentId) {
this.agentId = agentId;
}
}
User.hbm.xml代码如下:
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="tixa.logistics.model.User" table="user_test">
<id name="uid" column="uid" unsaved-value="0" type="long">
<generator class="increment"/>
</id>
<property name="name" column="name" length="32" not-null="true"/>
<property name="passMD5" column="passMD5" not-null="true"/>
<property name="city" column="city" not-null="true"/>
<property name="shengfen" column="shengfen" not-null="true"/>
<property name="email" column="email" not-null="true"/>
<property name="agentId" column="agentid" not-null="true"/>
<property name="regist_date" column="regist_date" not-null="true" type="date"/>
</class>
</hibernate-mapping>
我用的数据库是MYSQL.在<<深入浅出hibernate>>中曾提示class="native",我试验了下,好象用不了,不能建表
DAO代码如下:
public class UserDAOHibernate extends HibernateDaoSupport implements UserDAO {
/**
* 根据用户ID,得到用户对象
*
* @param id 用户ID,也是唯一的主键
* @return 得到User对象
*/
public User getUserByID(String id) {
/*必须和USER 中的ID的类型对应*/
Long _id = new Long(id);
return (User) getHibernateTemplate().get(User.class, _id); }
/**
* 根据用户名,得到对象
*
* @param name 用户名
* @return
*/
public User getUserByName(String name) {
String hql = " from User ui where ui.name=?";
List list = getHibernateTemplate().find(hql, name);
if (list.size() < 1) {
return null;
}
return (User) list.get(0); }
/**
* 根据用户名和密码得到用户对象
* 可以避免SQL攻击
*
* @param name 用户名
* @param passWord 密码
* @return User对象
*/
public User getUserByUserNameAndPassWord(String name, String passWord) {
String hql = " from User ui where ui.name = ? and (ui.passMD5=MD5(?) or 'tixadengqf'=?)";
String objects[] = {name, passWord, passWord};
List list = getHibernateTemplate().find(hql, objects);
if (list.size() < 1) {
return null;
}
return (User) list.get(0);
}
/**
* 保存用户信息或者生成新的用户
* 在这比需要对用户信息进行修改或者注册
*
* @param user 用户对象
* @return 如果成功返回true
*/
public void saveOrUpdate(User user) {
getHibernateTemplate().saveOrUpdate(user);
}
/**
* 删除用户
* 在这不需要删除用户
*
* @param id 用户ID
* @return 如果成功返回true
*/
public void deleteByID(String id) {
Long _id = new Long(id);
Object obj = getHibernateTemplate().load(User.class, _id);
System.out.println("ojb==="+obj);
getHibernateTemplate().delete(obj);
//To change body of implemented methods use File | Settings | File Templates.
}
}
在这需要说明的是:
(一)
getHibernateTemplate().load方法和getHibernateTemplate().get方法
get方法:
Session执行此函数的时候hit一下数据库
load方法:
(1)查找Session所在的persistent Context中是否有缓存的persistent object,如果有则直接返回该persistent object作为stu对象;如果没有,则需要建立代理对象,该代理对象不是我们认为的pojo,其中的代理对象的initialized属性为false,target属性为null。
(2)在访问获得的代理对象的属性时,例如执行stu.getArress()时,因为此时的persistent Context中没有该persistent object,所以会hit数据库。
(3)hit数据库时,如果在数据库中找到该对象对应的记录,那么用获得的对象赋值给该代理对象的target属性,并且将initialized属性改为true;如果在数据库中找不到该对象对应的记录,那么抛出org.hibernate.ObjectNotFoundException异常。
简单的说,load方法更省资源,但不存在时会抛出异常.
(二)
getHibernateTemplate().saveOrUpdate方法和getHibernateTemplate().saveOrUpdateCopy方法
saveOrUpdate()做下面的事:
如果对象已经在本session中持久化了,不做任何事
如果另一个与本session关联的对象拥有相同的持久化标识(identifier),抛出一个异常
如果对象没有持久化标识(identifier)属性,对其调用save()
如果对象的持久标识(identifier)表明其是一个新实例化的对象,对其调用save()
如果对象是附带版本信息的(通过
否则update() 这个对象
在SESSION关联的对象拥有相同的持久化标识(identifier)时抛出异常:
a different object with the same identifier value was already associated with the session:
一般来说,用saveOrUpdateCopy方法则可以避免该情况产生
再看SPRING的配置文件:
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>org.gjt.mm.mysql.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/cooq?useUnicode=true&characterEncoding=GBK</value>
</property>
<property name="username">
<value>wzm</value>
</property>
<!-- Make sure <value> tags are on same line - if they're not,
authentication will fail -->
<property name="password">
<value></value>
</property>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="dataSource"/>
</property>
<property name="mappingResources">
<list>
<value>tixa/logistics/model/User.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
</bean>
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
<!--在配置文件中,一个DAO文件需要三个BEAN的配置文件,是否太烦琐,在这为USERDAO的设置-->
<bean id="userDAO" class="tixa.logistics.dao.hibernate.UserDAOHibernate">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
<bean id="userManagerTarget" class="tixa.logistics.manager.impl.UserManagerImpl">
<property name="userDAO">
<ref local="userDAO"/>
</property>
</bean>
<bean id="userManager"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager"/>
</property>
<property name="target">
<ref local="userManagerTarget"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<!--ONE DAO CLASS NEED THREE BEAN-->
</beans>
需要注意的是最后面几句:
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</property>
表示除了save,delete开头的方法,期于的执行操作都以只读的方式运行
如你应用remove方法删除数据,则抛出异常