在Hibernate
中,各表的映射文件….hbm.xml
可以通过工具生成,例如在使用MyEclipse
开发时,它提供了自动生成映射文件的工具。本节简单的讲述一下这些配置文件的配置。
配置文件的基本结构如下:
<?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="包名">
<class name="类名" table="表名">
<id name="主键在java类中的字段名" column="对应表中字段" type="类型 ">
<generator class="主键生成策略"/>
</id>
……
</class>
</hibernate-mapping>
1. 主键(id)
Hibernate的主键生成策略有如下几种:
1) assigned
主键由外部程序负责生成,在 save() 之前指定。
2) hilo
通过hi/lo 算法实现的主键生成机制,需要额外的数据库表或字段提供高位值来源。
3) seqhilo
与hilo 类似,通过hi/lo 算法实现的主键生成机制,需要数据库中的 Sequence,适用于支持 Sequence 的数据库,如Oracle。
4) increment
主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。这种方式可能产生的问题是:不能在集群下使用。
5) identity
采用数据库提供的主键生成机制。如DB2、SQL Server、MySQL 中的主键生成机制。
6) sequence
采用数据库提供的 sequence 机制生成主键。如 Oralce 中的Sequence。
7) native
由 Hibernate 根据使用的数据库自行判断采用 identity、hilo、sequence 其中一种作为主键生成方式。
8) uuid.hex
由 Hibernate 基于128 位 UUID 算法 生成16 进制数值(编码后以长度32 的字符串表示)作为主键。
9) uuid.string
与uuid.hex 类似,只是生成的主键未进行编码(长度16),不能应用在 PostgreSQL 数据库中。
10) foreign
使用另外一个相关联的对象的标识符作为主键。
主键配置举例如下:
<id name="id" column="id" type="java.lang.Integer">
<generator class="native"/>
</id>
另外还可以扩展Hibernate的类来做自己的主键生成策略,具体例子见:http://www.javaeye.com/topic/93391。
2. 普通属性(property)
开发人员可以打开网址:http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd
来查看hibernate3.0的dtd信息,可看到property的定义如下:
<!ELEMENT property (meta*,(column|formula)*,type?)>
<!ATTLIST property name CDATA #REQUIRED>
<!ATTLIST property node CDATA #IMPLIED>
<!ATTLIST property access CDATA #IMPLIED>
<!ATTLIST property type CDATA #IMPLIED>
<!ATTLIST property column CDATA #IMPLIED>
<!ATTLIST property length CDATA #IMPLIED>
<!ATTLIST property precision CDATA #IMPLIED>
<!ATTLIST property scale CDATA #IMPLIED>
<!ATTLIST property not-null (true|false) #IMPLIED>
<!ATTLIST property unique (true|false) "false">
<!ATTLIST property unique-key CDATA #IMPLIED>
<!ATTLIST property index CDATA #IMPLIED> <!-- include the columns spanned by this property in an index -->
<!ATTLIST property update (true|false) #IMPLIED>
<!ATTLIST property insert (true|false) #IMPLIED>
<!ATTLIST property optimistic-lock (true|false) "true"> <!-- only supported for properties of a class (not component) -->
<!ATTLIST property formula CDATA #IMPLIED>
<!ATTLIST property lazy (true|false) "false">
<!ATTLIST property generated (never|insert|always) "never">
它的各属性中比较常用的有:name(对应的java类的属性名称)、column(对应的表中的字段)、tyope(属性的类型,eg.java.lang.String)、not-null(设置该属性是否为空,为true时表示非空,默认为false)和length(字段的长度限制)。
Eg1. <property name="accessname" column="accessName" type="java.lang.String" not-null="true" />
Eg2. <property name="state" column="state" type="java.lang.Byte" not-null="true" />
Eg3. <property name="description" column="description" type="java.lang.String" />
3. 一对多关系(<many-to-one…/>和<set…></set>)
一对多关系一般是用在一个表与另一个表存在外键关联的时候,例如用户表的组织id与组织表存在外键关联,则“一”方为组织表,“多”方为用户表,因为一个组织可以包含多个用户,而一个用户只能隶属于一个组织。
对于存在一对多关系和多对一关系的双方,需要在…hbm.xml中进行相应配置,这时在“一”方(例如:组织)需要在映射文件中添加<set…></set>元素,因为它包含多个“多”方的对象,一般的格式如下:
<set name="java映射类中对应的属性" inverse="true" lazy="true">
<key column="表中对应字段"/>
<one-to-many class="多方的类"/>
</set>
Eg.
<set name="userSet" inverse="true" lazy="true">
<key column="orgId"/>
<one-to-many class="User"/>
</set>
“多”方(例如:用户)隶属于一个“一”方对象,一般的格式如下:
<many-to-one name="java映射类中对应的属性" column="表中对应字段" class="类名" not-null="true" />
Eg.
<many-to-one name="org" column="orgId" class="Organization" not-null="true" />
4. 一对一关系(<one-to-one…/>)
一对一关系相对一对多关系来说比较少见,但也在某些情况下要用到,例如有一个用户的基本信息表(USER)和一个用户的密码表(PASSWD)就存在一对一的关系。下面来看一下一对一关系在Hibernate的配置。
其中主表(eg. 用户的基本信息表)的配置如下:
<one-to-one name="主表对象中子表对象的属性名" class="子表对象的类名" cascade="save-update"/>
Eg. <one-to-one name="password" class="com.amigo.dao.pojo.Passwd" cascade="save-update"/>
子表(eg. 用户的密码表)的配置如下:
<one-to-one name="子表对象中主表对象的属性名" class="主表对象的类名" constrained="true" />
Eg. <one-to-one name="user" class="com.amigo.dao.pojo.User " constrained="true" />
5. 多对多关系(<many-to-many…/>)
在数据库设计时,一般将多对多关系转换为两个一对多(或多对一)关系,例如在基于角色的权限系统中,用户和角色存在的关系就是典型的多对多关系,即一个用户可以具有多个角色,而一个角色又可以为多个用户所有,一般在设计时,都会加一个用户与角色的关联表,该表与用户表以及角色表都存在外键关联。
在本小节中讲述的是没有分解的多对多关系在Hibernate中如何配置。设置格式如下:
<set name="java对象的属性名" table="表名" cascade="all" outer-join="false">
<key column="表的对应字段"/>
<many-to-many class="另一个表的对象类" column="另一个表的字段"/>
</set>
Eg. 上述的多对多关系可以表示为:
t_user方:
<set name="roleSet" table="t_user" cascade="all" outer-join="false">
<key column="roleId"/>
<many-to-many class="com.amigo.dao.pojo.Role" column="roleId"/>
</set>
t_role方:
<set name="userSet" table="t_role" cascade="all" outer-join="false">
<key column="roleId"/>
<many-to-many class="com.amigo.dao.pojo.User" column="roleId"/>
</set>
6. 完整实例
在本小节中举一些.hbm.xml映射文件的例子,让开发人员对其有一个感性的认识。接下来讲述一个用户表(tbl_user)、用户与角色关联表(tbl_user_role)、角色表(tbl_role)以及组织表(tbl_organization)的例子。
(1)tbl_user
<?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.amigo.dao.pojo">
<class name="User" table="tbl_user">
<id name="loginname" column="loginName" type="java.lang.String">
<generator class="assigned"/>
</id>
<property name="name" column="name" type="java.lang.String" not-null="true" />
<property name="password" column="password" type="java.lang.String" not-null="true" />
<property name="mobile" column="mobile" type="java.lang.String" />
<property name="telephone" column="telephone" type="java.lang.String" />
<property name="email" column="email" type="java.lang.String" />
<property name="createtime" column="createTime" type="java.util.Date" not-null="true" />
<property name="lastlogintime" column="lastLoginTime" type="java.util.Date" />
<property name="logintimes" column="loginTimes" type="java.lang.Long" not-null="true" />
<property name="state" column="state" type="java.lang.Byte" not-null="true" />
<property name="description" column="description" type="java.lang.String" />
<many-to-one name="organization" column="orgId" class="Organization" not-null="true" />
<set name="userRoleSet" inverse="true" cascade="all-delete-orphan" lazy="true">
<key column="loginName"/>
<one-to-many class="UserRole"/>
</set>
</hibernate-mapping>
(2)tbl_organization
<?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.amigo.dao.pojo">
<class name="Organization" table="tbl_organization">
<id name="orgid" column="orgId" type="java.lang.Long">
<generator class="native"/>
</id>
<property name="parentorgid" column="parentOrgId" type="java.lang.Long" not-null="true" />
<property name="orgname" column="orgName" type="java.lang.String" not-null="true" />
<property name="orgfullname" column="orgFullName" type="java.lang.String" />
<property name="orglevel" column="orgLevel" type="java.lang.Integer" not-null="true" />
<property name="state" column="state" type="java.lang.Byte" not-null="true" />
<property name="description" column="description" type="java.lang.String" />
<property name="creator" column="creator" type="java.lang.String" />
<property name="createtime" column="createTime" type="java.util.Date" />
<set name="userSet" inverse="true" lazy="true">
<key column="orgId"/>
<one-to-many class="User"/>
</set>
</class>
</hibernate-mapping>
(3)tbl_user_role
<?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.cotel.netvote.dao.model">
<class name="UserRole" table="tbl_user_role">
<id name="urid" column="urId" type="java.lang.Integer">
<generator class="native"/>
</id>
<many-to-one name="role" column="roleId" class="Role" not-null="true" />
<many-to-one name="user" column="loginName" class="User" not-null="true" />
</class>
</hibernate-mapping>
(4)tbl_ role
<?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.cotel.netvote.dao.model">
<class name="Role" table="tbl_role">
<id name="roleid" column="roleId" type="java.lang.Integer">
<generator class="native"/>
</id>
<property name="rolename" column="roleName" type="java.lang.String" not-null="true" />
<property name="createdate" column="createDate" type="java.util.Date" not-null="true" />
<property name="description" column="description" type="java.lang.String" />
<set name="userRoleSet" inverse="true" lazy="true" cascade="all">
<key column="roleId"/>
<one-to-many class="UserRole"/>
</set>
</class>
</hibernate-mapping>
http://www.blogjava.net/amigoxie/archive/2007/12/31/171831.html
这几天把hibernate和spring好好看了下,再想想struts的一些东西,决定把3个整合一下一起用,表现层用struts+freemarker,业务层用spring,hibernate处理持久层。在struts中,利用委托,将action的处理委托给spring进行,struts只负责页面逻辑。
前些日子下了Eclipse 3.2+MyEclipse5.0M2,感觉MyEclipse一些东西还是不错的,就用它来做个整合。
首先,建立一个web project:
然后,给新建立的项目附加上struts的一些文件:
完成后项目结构如下:
接着加入hibernate需要的文件:
完成后项目结构为:
再加入spring的文件:
注意下面的选择:
完成后可以看到:
打开那个applicationContext.xml,将
改为:
现在还需要做一些修改,才能在运行的时候不报错,我以前也写过struts+hibernate的时候,会抛一个错,之所以是由于hibernate包含的那个xerces.jar,所以现在直接把它给删掉,没什么问题。
在spring和hibernate那,有2个log4j.jar,老版本不好用,所以删除,换一个新版本。
删除
和
,换上
,然后,在src下加入一个log4j.properties:
内容如下:
这样log4j就配好了。
接下来是加入FreeMarker,jsp比不上,个人感觉。
先下一个freemarker.jar
,加到WEB-INF下的lib目录,然后,打开web.xml,加入如下内容:
下面来点实战演习。
切换到MyEclipse的hibernate视图。
打开数据库连接:
然后,执行
自动生成几个文件:
并且,spring的applicationContext.xml自动加入
然后,建立ftl页面,根据前面web.xml配置的freemarker设置,需要建立如下目录
先把页面逻辑处理下,打开struts-config.xml,然后进行如下操作
继续加
完成后效果如下:
下面是3个页面:
这里注意下前2行,在freemarker中用struts标签。
前面说过action委托给spring做,许要在struts那加入
然后,action类需要修改下
下面的setter是为spring准备的。
struts配置那的action声明需要修改一下,说明用代理:
然后在spring的applicationContext.xml加上:
注意是用name,不是id。
发布,运行,结果抛了个错
还好,问题不大,找到
加到WEB-INF/lib下就可以了。
开始测试
成功的话:
否则:
然后去数据库一看,郁闷,数据没进来,试了N久,最后发现spring里要定义个dataSource。原来sessionFactory的定义变为如下:
ok,一切正常。到这里,就写完了,只是为说明怎样用MyEclipse进行快速开发,毕竟平时做项目要的是进度,还要监管质量,有了MyEclipse,确实方便不少。
http://www.cnblogs.com/zxub/archive/2006/08/03/466682.html
1:下载dwr.jar放在 WebRoot\WEB-INF\lib
2:页面
<%@ page language="java" pageEncoding="UTF-8"%>
<script type='text/javascript' src='../dwr/engine.js'></script>
<script type='text/javascript' src='../dwr/util.js'></script>
<script type='text/javascript' src='../dwr/interface/
checkuser.js'></script>
<script type='text/javascript'>
function check(form)
{
var id=document.getElementById("id").value;
if(id=="new")
{
regUserChked(form);
}
else
{
RegUserChked(form);
}
}
function regUserChked(form){
var username= document.getElementById("username").value;
if(username=="")
{
alert("用户名不能为空!")
return false;
}
checkuser.isExist(username,showData);//showData回调函数
}
function RegUserChked(form){
var id=document.getElementById("id").value;
var username= document.getElementById("username").value;
if(username=="")
{
alert("用户名不能为空!")
return false;
}
checkuser.IsExistUpdate(username,id,ShowData); //showData回调函数
}
function showData(data){
if(data){
alert('该用户已被注册了!');
}else{
alert('该用户未被注册了!');
}
}
function ShowData(data){
if(data){
alert('该用户已被注册了!');
}else{
alert('可以更新!');
}
}
</script>
</head>
<body>
<html:form action="/acctount" onsubmit="javascript:return Juge(this);">
<input type="hidden" name="id" value="<%=id%>">
username : <html:text property="username" value="<%=Username %>" onblur="check(this)" />
<html:errors property="username"/><br/>
password : <html:text property="password" value="<%=password %>"/>
<html:errors property="password"/><br/>
<html:submit/><html:cancel/>
</html:form>
</body>
</html>
3:
dwr.xml配置
<dwr>
<allow>
<!-- 直接取操作类 <create creator="new" javascript="checkuser" scope="application">
<param name="class" value="com.henry.dao.daospring"/>
<include method="isExist"/>
</create>
-->
<!-- 间接取bean -->
<create creator="spring" javascript="
checkuser">
<param name="beanName" value="
accountDAO" />
<include method="isExist"/>
<include method="IsExistUpdate"/>
</create>
</allow>
</dwr>
4:
applicationContext.xml
<bean id="
accountDAO" class="com.henry.dao.AccountDao">
<property name="dataSource">
<ref local="dataSource"/>
</property>
<property name="sqlMapClient">
<ref bean="sqlMapClient"/>
</property>
</bean>
5:
web.xml
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<display-name>DWR Servlet</display-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
6:1)以上dwr通过间接
spring-> applicationContext.xml的bean
<!-- 间接取bean -->
<create creator="spring" javascript="
checkuser">
<param name="beanName" value="
accountDAO" />
<include method="isExist"/>
<include method="IsExistUpdate"/>
</create>
2)如果直接取
spring-> applicationContext.xml的bean
<!-- 直接取操作类 <create creator="new" javascript="checkuser" scope="application">
<param name="class" value="com.henry.dao.daospring"/>
<include method="isExist"/>
</create>
-->
com.henry.dao.daospring:如下
package com.henry.dao;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.henry.dto.accountDto;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class daospring {
ApplicationContext context=new ClassPathXmlApplicationContext("com/henry/dbxml/applicationContext.xml");
AccountDao testDAOImpl=(AccountDao)context.getBean("AccountDAO");
public List getAccountsByName(String username)
{
return testDAOImpl.getListByName(username);
}
/*
* update check
*/
public boolean
IsExistUpdate(String username)
{
accountDto account=new accountDto();
List list=this.getAccountsByName(username);
if(list.size()==0)
{
return false;
}
else
{
//if(account.getId()==Integer.parseInt(id))
//{
// return false;
//}
//else
//{
return true;
//}
}
}
public String getIdByName(String username,String id)
{
accountDto account=new accountDto();
List list=this.getAccountsByName(username);
if(list.size()==0)
{
return null;
}
else
{
return Integer.toString(((accountDto)list.get(0)).getId()) ;
}
}
public boolean
IsExist(String username) {
if(testDAOImpl.isExist(username))
{
return true;
}
else
{
return false;
}
}
//new or add check
public boolean isExist(String username) {
if(testDAOImpl.isExist(username))
{
return true;
}
else
{
return false;
}
}
public accountDto getAccountById(String id)
{
return testDAOImpl.getById(id);
}
}
7:出现问题struts---->action--->findforward跳转页面------该页面dwr取spring-->
applicationContext.xml的bean变成无效