双向one-to-many
package com;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
import com.yourcompany.hib.HibernateSessionFactory;
import com.yourcompany.struts.AppConPath;
public class ClassListTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext context = new FileSystemXmlApplicationContext(AppConPath.getPath());
try{
/**************在主表操作**************************/
//创建Student对象
/**
Student st1 = new Student();
st1.setStudentName("st1");
Student st2 = new Student();
st2.setStudentName("st2");
Student st3 = new Student();
st3.setStudentName("st3");
Student stu = new Student();
stu.setStudentName("stu");
//创建Teacher对象
Set<Student> hs = new HashSet<Student>();
Teacher t = new Teacher();
t.setTeacherName("afuer");
hs.add(st1);
hs.add(st2);
hs.add(st3);
hs.add(stu);
t.setStudents(hs);
*/
TeacherDAO s =(TeacherDAO) context.getBean("TeacherDAO");
/**********保存方法***********/
/**
* 如果配置文件中 inverse="true"
&nbs
欢迎光临学网,收藏本篇文章 [1] [2] [3]
$False$
p; * 则在student表中teacher_id为NULL。
*
*/
//s.save(t);
/**********更新方法**********/
/**
t.setId(1);
st1.setId(1);
stu.setId(2);
st2.setId(3);
st3.setId(4);
//s.findById(t.getId());//假如用这个则TeacherDAO类中的update()不用getHibernateTemplate().load方法
t.setTeacherName("kk");
s.update(t);
*/
/**********删除方法**********/
/**
t.setId(1);
s.delete(t);
*/
/**********查找方法**********/
/**
* 如果 配置文件中lazy="true"
* 则会报错:
*
* 第1个老师信息 :
* 老师id:1 老师姓名:kk
* org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.Teacher.students - no session or session was closed
* at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:191)
* at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:183)
* at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:48)
* at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:134)
* at com.ClassListTest.main(ClassListTest.java:93)
*/
List list = s.findAll();
Iterator it = list.iterator();
for(int i=1;it.hasNext();i++){
Teacher teacher =(Teacher) it.next();
System.out.println("第"+i+"个老师信息 :");
System.out.println("老师id:"+teacher.getId()+欢迎光临学网,点击这里查看更多文章教程 [1] [2] [3]
" 老师姓名:"+teacher.getTeacherName());
Set<Student> hs = teacher.getStudents();
Iterator hsIt = hs.iterator();
for(int j=1;hsIt.hasNext();j++){
Student student = (Student) hsIt.next();
System.out.println("第"+j+"个学生信息 :");
System.out.println("学生id:"+student.getId()+"学生姓名:"+student.getStudentName());
}
}
/**************在从表操作**************************/
/**
StudentDAO s1= (StudentDAO) context.getBean("StudentDAO");
Student st4 = new Student();
st4.setStudentName("st4");
st4.setTeacher(t);
s1.save(st4);
*/
}cat
ch(Exception e){
e.printStackTrace();
}finally{
System.out.println("success");//看什么时候执行完
}
}
}
/**********************************************************************/
配置文件中的inverse属性是用来优化更新速度, 如果="true",表示在执行主表的时候不更新从表的值
如果去掉或者把它="false"则会更新。
lazy,如果="true"在查询主表的时候不会去查找从表,如果去掉或者="false"则会去查询,这样会增大
查询数据的数量,同时还增大内存。如果从表数据太多,在查询的时候将会耗费大量的内存。所以程序员开发
的时候设置为"true"
/**********************************************************************/
()
this.getHibernateTemplate().delete(persistentInstance);
本来这句没错,但是只要加了
<set name="dessertOrders" lazy="false" inverse="true" cascade="all-delete-orphan">
<key>
<column name="customer_id" not-null="true" />
</key>
<one-to-many class="com.hibernate.DessertOrder" />
</set>
在xml里面就立即报错,没什么特别的提示信息,为什么
问题补充:exception
javax.servlet.ServletException: com.exception.ActionException: 删除产品出现异常,请重试!
()
hibernate级联的3个属性
cascade(级联)
级联在编程中经常接触,写过触发器来修改或删除关联表相记录的一定会知道,触发器的作用是当 主控表信息改变时,用来保证其关联表中数据同步更新。比如一个employee存放职员信息,一个 timecard存放职员的考勤信息,当从职员表中删除一个职员时,timecard表中对应的考勤信息 已经没有意义,因为其所属的职员已不存在,如果继续留在timecard表中就成了没用的也称脏数据。 理想的做法是在删除职员信息的同时将该职员信息对应的考勤信息也删除。在hibernate中如果要达到这个 效果只需要设置cascade属性值即可。当然是否进行级联关系要根据实际情况慎重考虑。
inverse(反转)
表与表之间的关联,我们通常将主动发起关联请求的表称为主动表,被关联的表成为被动表,hibernate中 将此概念冠以在表所对应的对象上,因此将主动发起关联请求的对象称为主动对象或主控对象,被关联的对象 称为被动对象或被控对象。hibernate由主动对象维护关联关系,在实际中经常碰到一个对象的关联角色并不 那么明确,如双向关联,这时inverse值用来标明由谁来维护关联关系。设为true时反转控制角色,即由该 属性关联的对象维护关联关系。
Lazy Loading(延时装载)
延时装载主要是从性能方面的考虑,对于 “select coulmn1 from table”和“select * from table”语句 的性能比较,相信大家不会有异议,第一条的执行性能要高于第二条,当然这个表中字段存储的信息应该能充分 体现出优越性为前提,比如说一个employee表中存放有,职员姓名、年龄、照片等,如果只需要查看姓名和年龄, 那么照片信息就不应该附带出来。表与表之间的关联也应如此,如果不需要用到关联表中的数据就不应该去进行关 联操作,或在需要的时候才启动关联操作。让数据在最恰当的时候才出现,这就是延时装载。
(()
你好,能帮我解决上述问题吗?十分感谢。。。
以下是我的代码
表结构:
create table book (--图书基本信息表
bookId number primary key, --图书编号
bookName varchar2(50) not null , --图书名
bookType varchar2(50) not null , --图书类别
publish varchar2(50), --出版社
author varchar2(50), --作者
price varchar2(50), --定价
bookTotal number,--在库数量
bookContent varchar2(200)--图书介绍
);
create table userInfo (--用户信息表
userId number primary key, --用户id号
userPs varchar2(50) not null,--用户密码
userName varchar2(50) not null, --用户名
sex varchar2(10) not null --性别
);
create table booklendinfo(--图书借阅信息表
id number primary key,--主键标记
bookId number not null, --书号
userId number not null , --用户号
lendDate date not null , --借书时间
returnDate date , --还书时间
foreign key(bookId) references book(bookId) on delete cascade ,
foreign key(userId) references userInfo(userId) on delete cascade
);
public Book searchBookByInfo(BookLendInfo info){
System.out.println("info:"+info);
Book book=info.getBook();
book.getAuthor();
System.out.println("book:"+book);
return book;
}
上面是UserDaoImpl里面的方法,返回booklendinfo中的book对象,其中UserDaoImpl实现了UserDao接口,然后我在jsp中调用,请接着看下面的代码
if(request.getAttribute("list")!=null){
List list=(List)request.getAttribute("list");//获取借书列表
WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServletContext());
UserDao userDao=(UserDao)ctx.getBean("userDaoProxy");//获取代理dao
Iterator it=list.iterator();
while(it.hasNext())
{
BookLendInfo info=(BookLendInfo)it.next();
Book book=userDao.searchBookByInfo(info);
System.out.println("book"+book);
我用了spring事务了,还是不行啊
<bean id="userDaoProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" >
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="target">
<ref local="userDao" />
</property>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly </prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly </prop>
<prop key="save*">PROPAGATION_REQUIRED </prop>
<prop key="insert*">PROPAGATION_REQUIRED </prop>
<prop key="update*">PROPAGATION_REQUIRED </prop>
<prop key="return*">PROPAGATION_REQUIRED </prop>
<prop key="search*">PROPAGATION_REQUIRED </prop> //这就是上面方法的事务配置,UserDaoImpl中的searhBookByInfo方法
<prop key="*">PROPAGATION_REQUIRED,readOnly </prop>
</props>
</property>
</bean>
<hibernate-mapping>
<class name="com.beans.BookLendInfo" table="BOOKLENDINFO" schema="SCOTT">
<id name="id" type="java.lang.Long">
<column name="ID" precision="22" scale="0" />
<generator class="increment" />
</id>
<many-to-one name="book" class="com.beans.Book" fetch="select">
<column name="BOOKID" precision="22" scale="0" not-null="true" />
</many-to-one>
<many-to-one name="userinfo" class="com.beans.UserInfo" fetch="select">
<column name="USERID" precision="22" scale="0" not-null="true" />
</many-to-one>
<property name="lenddate" type="java.util.Date">
<column name="LENDDATE" length="7" not-null="true" />
</property>
<property name="returndate" type="java.util.Date">
<column name="RETURNDATE" length="7" />
</property>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="com.beans.Book" table="BOOK" schema="SCOTT">
<id name="bookid" type="java.lang.Long">
<column name="BOOKID" precision="22" scale="0" />
<generator class="increment" >
</generator>
</id>
<property name="bookname" type="java.lang.String">
<column name="BOOKNAME" length="50" not-null="true" />
</property>
<property name="booktype" type="java.lang.String">
<column name="BOOKTYPE" length="50" not-null="true" />
</property>
<property name="publish" type="java.lang.String">
<column name="PUBLISH" length="50" />
</property>
<property name="author" type="java.lang.String">
<column name="AUTHOR" length="50" />
</property>
<property name="price" type="java.lang.String">
<column name="PRICE" length="50" />
</property>
<property name="booktotal" type="java.lang.Long">
<column name="BOOKTOTAL" precision="22" scale="0" />
</property>
<property name="bookcontent" type="java.lang.String">
<column name="BOOKCONTENT" length="200" />
</property>
<set name="booklendinfos" inverse="true" cascade="save-update" lazy="false">
<key>
<column name="BOOKID" precision="22" scale="0" not-null="true" />
</key>
<one-to-many class="com.beans.BookLendInfo" />
</set>
</class>
</hibernate-mapping>
()
SSH加了级联删除总是出错
this.getHibernateTemplate().delete(persistentInstance);
本来这句没错,但是只要加了
<set name="dessertOrders" lazy="false" inverse="true" cascade="all-delete-orphan">
<key>
<column name="customer_id" not-null="true" />
</key>
<one-to-many class="com.hibernate.DessertOrder" />
</set>
在xml里面就立即报错,没什么特别的提示信息,为什么
本贴来自ZDNetChina中文社区 http://bbs.zdnet.com.cn ,本贴地址:http://bbs.zdnet.com.cn/viewthread.php?tid=850768
)()
HIbernate级联删除(hibernate 双向一对多中 主表设置cascade="all-delete-orphan",在save时出现2008-10-30 11:57数据库为:Oracle 9i
主表为: 用户表(member)
create table member (
member_id number(10,0) not null,
name varchar2(10 char),
sex varchar2(1 char),
primary key (member_id)
)
从表为: 订单表(orders)
create table orders (
Order_id number(10,0) not null,
total_price float,
member_id number(10,0),
primary key (Order_id)
)
alter table orders
add constraint FKC3DF62E5CDAA53AA
foreign key (member_id)
references member
双向关联映射细分:
在主表member的关系映射文件中:
1)一端(member)中对多端(order)采取了延迟加载策略:lazy="true"默认
2)将多端(order)的传播持久性(级联)设置为最全面的全部级联(包括孤儿模式):cascade="all-delete-orphan"
3)将维护关系的控制权交给多端(order):inverse="true"
在从表orders的关系映射文件中:
1)多端(order)对一端(member)采取了预先抓取策略:fetch="join"(并且要把一端‘member’映射文件的class标签的lazy属性设置为false)
2)将一端(member)的传播持久性(级联)设置为存储、更新:cascade="save-update"
用户表member(主表):
<hibernate-mapping>
<class name="hbp.ch04.ex03.model.Member" table="member" lazy="false">
<id name="memberId" column="member_id" type="java.lang.Integer">
<generator class="native"> </generator>
</id>
<property name="name" column="name" type="java.lang.String" length="10"> </property>
<property name="sex" column="sex" type="java.lang.String" length="1"> </property>
<set name="orders" order-by="order_id" inverse="true" lazy="true" cascade="all-delete-orphan">
<key column="member_id"> </key>
<one-to-many class="hbp.ch04.ex03.model.Order"/>
</set>
</class>
</hibernate-mapping>
订单表orders(从表)
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
<class name="hbp.ch04.ex03.model.Order" table="orders">
<id name="orderId" column="Order_id" type="java.lang.Integer">
<generator class="native"> </generator>
</id>
<property name="totalPrice" column="total_price" type="java.lang.Float"> </property>
<many-to-one name="member" column="member_id" class="hbp.ch04.ex03.model.Member" cascade="save-update" fetch="join"> </many-to-one>
</class>
</hibernate-mapping>
pojo类:
Member------------------------
import java.util.HashSet;
import java.util.Set;
public class Member {
// Fields
private Integer memberId;
private String name;
private String sex;
private Set orders;
// Constructors
/** default constructor */
public Member() {
// TODO Auto-generated constructor stub
}
// Property accessors
/**
* @return the orders
*/
public Set getOrders() {
if (orders == null) {
orders = new HashSet();
}
return orders;
}
// 其他 get/set访问方法省略。。。。。
}
Order-----------------
public class Order {
// Fields
}
Member的DAO类(DAO实现的接口省略。。。)
import org.hibernate.*;
import util.HibernateSessionFactory;
import hbp.dao.MemberDAO;
import hbp.model.Member;
import hbp.model.Order;
public class HibernateMemberDAO implements MemberDAO {
public void deleteMember(Integer memberId) {
// TODO Auto-generated method stub
Session session = HibernateSessionFactory.getSession();
session.beginTransaction();
Member member = (Member)session.get(Member.class, memberId);
session.delete(member);
session.getTransaction().commit();
session.close();
}
public Member getMemberById(Integer memberId) {
// TODO Auto-generated method stub
Session session = HibernateSessionFactory.getSession();
session.beginTransaction();
Member member = (Member)session.get(Member.class, memberId);
//Hibernate.initialize(member.getOrders());
session.getTransaction().commit();
return member;
}
public Order getOrderById(Integer orderId) {
// TODO Auto-generated method stub
Session session = HibernateSessionFactory.getSession();
session.beginTransaction();
Order order=(Order)session.get(Order.class, orderId);
//Hibernate.initialize(order.getMember());
session.getTransaction().commit();
return order;
}
public void saveMember(Member member) {
// TODO Auto-generated method stub
Session session = HibernateSessionFactory.getSession();
session.beginTransaction();
session.save(member);
session.getTransaction().commit();
}
public void saveOrder(Integer memberId, Order order) {
// TODO Auto-generated method stub
Session session = HibernateSessionFactory.getSession();
session.beginTransaction();
Member member = (Member)session.get(Member.class, memberId);
order.setMember(member);
member.getOrders().add(order);
session.save(member);
session.getTransaction().commit();
}
public void delete_orphan(Member member,Order order) {
Session session = HibernateSessionFactory.getSession();
session.beginTransaction();
member.getOrders().remove(order);
session.save(member);
session.getTransaction().commit();
}
}
测试方法:
import java.util.HashSet;
import hbp.dao.hibernate.HibernateMemberDAO;
import hbp.model.Member;
import hbp.model.Order;
import junit.framework.TestCase;
public class HibernateMemberDAO03Test extends TestCase {
public void testSaveMember(){
HibernateMemberDAO memberDAO = new HibernateMemberDAO();
Member member, member2, member3;
member = new Member();
member.setName("李四");
member.setSex("f");
member.setOrders(new HashSet());
memberDAO.saveMember(member);
member2 = new Member();
member2.setName("王五");
member2.setSex("m");
member2.setOrders(new HashSet());
memberDAO.saveMember(member2);
member3 = new Member();
member3.setName("张三");
member3.setSex("m");
member3.setOrders(new HashSet());
memberDAO.saveMember(member3);
}
public void testSaveOrder() {
HibernateMemberDAO memberDAO = new HibernateMemberDAO();
Order order = new Order();
order.setTotalPrice(new Float(12.34));
memberDAO.saveOrder(new Integer(3), order);
}
public void testGetMemberById() {
HibernateMemberDAO memberDAO = new HibernateMemberDAO();
Member member = memberDAO.getMemberById(new Integer(3));
System.out.println("会员姓名:" + member.getName());
System.out.println("订单数量:" + member.getOrders().size());
}
public void testGetOrderById() {
HibernateMemberDAO memberDAO = new HibernateMemberDAO();
Order order = memberDAO.getOrderById(new Integer(4));
System.out.println("会员姓名:" + order.getMember().getName());
System.out.println("订单价格:" + order.getTotalPrice());
}
public void testDeleteMember() {
/*
HibernateMemberDAO memberDAO = new HibernateMemberDAO();
memberDAO.deleteMember(new Integer(2));
memberDAO.deleteMember(new Integer(3));
*/
HibernateMemberDAO memberDAO = new HibernateMemberDAO();
Member member = memberDAO.getMemberById(new Integer(3));
Order order = memberDAO.getOrderById(new Integer(4));
memberDAO.delete_orphan(member, order);
}
}
()
ajax和struts实现级联
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<script type="text/javascript">
var xmlhttp;
function createXMLHttp(){
if(window.ActiveXObject){
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}else if(window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest();
}
}
function getLevel2(){
createXMLHttp();
url="info.do?id="+document.forms.form1.select1.value;
alert(url);
xmlhttp.open("get",url,true);
xmlhttp.onreadystatechange=function callback(){
if(xmlhttp.readyState==4)
{
if(xmlhttp.status==200)
{
addOption();
}
}
};
xmlhttp.send(null);
}
function clearlist(){
var models=document.getElementById("select2");
while(models.childNodes.length>0){
models.removeChild(models.childNodes[0]);
}
}
function addOption(){
clearlist();
createXMLHttp();
var xmlDoc=xmlhttp.responseXML;
alert(xmlDoc);
var results=xmlDoc.getElementsByTagName("option");
for(var i=0;i<results.length;i++){
var xValue=results[i].childNodes[0].firstChild.nodeValue;
var xText=results[i].childNodes[1].firstChild.nodeValue;
var option=new Option(xText,xValue);
models.appendChild(option);
}
}
</script>
</head>
<body>
<form action="#" name="form1">
<select name="select1" οnchange="getLevel2();">
<option value="0">
请选择一级目录
</option>
<%
List<Info> list = InfoDao.getFirst();
for (Info info : list) {
request.setAttribute("info", info);
%>
<option value="${info.id }">
${info.name }
</option>
<%
}
%>
</select>
<select name="select2">
<option value="0">
请选择二级目录
</option>
</select>
</form>
<br>
</body>
</html>
action代码
public class InfoAction extends Action {
/*
* Generated Methods
*/
/**
* Method execute
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
// TODO Auto-generated method stub
String id=request.getParameter("id");
Info info1=InfoDao.getInfo(id);
List<Info> list=(ArrayList<Info>)InfoDao.getNext(info1);
String xml_start="<?xml version=/"1.0/" encoding=/"UTF-8/"?><selects>";
String xml_end="</selects>";
String xml="";
for(Info info : list){
xml+="<option value='"+info.getId()+"'>'"+info.getName()+"'</option>";
}
String last_xml=xml_start+ xml+ xml_end;
try {
response.getWriter().write(last_xml);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(last_xml);
return mapping.findForward("ok");
}
}为什么js中addOption()在callback()中调用不起作用啊?求高手指导
()