問(wèn)題描述:在做hibernate和struts2整合的小項(xiàng)目(學(xué)生管理系統(tǒng))中,將學(xué)生對(duì)應(yīng)的緊急聯(lián)系人在頁(yè)面上輸入信息后保存到數(shù)據(jù)庫(kù)中。
contact.jsp頁(yè)面顯示

這里分析的學(xué)生和緊急聯(lián)系人是一對(duì)一的關(guān)系,這兩個(gè)表的主鍵都是id設(shè)置自動(dòng)增長(zhǎng),聯(lián)系人主鍵id作為學(xué)生表的外鍵cid。Student(id,cid,name,sex,phone,grade,photo) 從表Contact(id,name,sex,relation,phone) 主表
兩個(gè)表對(duì)應(yīng)著的javabean對(duì)象類:
可以看到在Javabean中這兩個(gè)類中已經(jīng)注解配置了一對(duì)一關(guān)系,并且在student中加入了cid外鍵字段。
在從表中加入Contact contact屬性,并設(shè)置其setter和getter。在其setter和getter前設(shè)置注解,表示與Contact的一對(duì)一關(guān)系,并加入列cid,設(shè)置為唯一的。
@OneToOne @JoinColumn(unique=true,name="cid")在主表中寫(xiě)Student student屬性,并寫(xiě)其setter和getter。在其setter和getter前添加注解配置,表示與Student表的一對(duì)一關(guān)系。這里不再主表中添加指向Student的外鍵,所以配置@OneToOne時(shí),要添加屬性mappedBy
@OneToOne(mappedBy="contact")Studnet.java
package model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.OneToOne;@Entitypublic class Student { PRivate int id; private String name; private String pwd; private String phone; private String grade; private String photo; private String sex; private Contact contact; @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getGrade() { return grade; } public void setGrade(String grade) { this.grade = grade; } public String getPhoto() { return photo; } public void setPhoto(String photo) { this.photo = photo; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @OneToOne @JoinColumn(unique=true,name="cid") public Contact getContact() { return contact; } public void setContact(Contact contact) { this.contact = contact; }}Contact.javapackage model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.OneToOne;@Entitypublic class Contact { private int id; private String name; private String sex; private String relation; private String phone; private Student student; @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getRelation() { return relation; } public void setRelation(String relation) { this.relation = relation; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } @OneToOne(mappedBy="contact") public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } }在hibernate.cfg.xml文件中配置這兩個(gè)Javabean:
hibernate.cfg.xml:
<?xml version='1.0' encoding='utf-8'?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><hibernate-configuration> <session-factory> <property name="connection.driver_class">com.MySQL.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/curricula</property> <property name="connection.username">jack</property> <property name="connection.passWord">12345678</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">true</property> <property name="hbm2ddl.auto">update</property> <mapping class="model.Student" /> <mapping class="model.Contact" /> </session-factory></hibernate-configuration>寫(xiě)DAO中更新聯(lián)系人表方法和Action中的方法(在struts.xml中采用通配符方式配置,這里不細(xì)說(shuō))ContactDAO:這里用的就是saveOrUpdate方法
package common;import org.hibernate.Session;import org.hibernate.Transaction;import model.Contact;public class ContactDAO { //定義公共變量 Session session; //更新或者保存聯(lián)系人的方法 public void updateContact(Contact contact) { session=HibernateUtil.openSession(); Transaction tx=session.beginTransaction(); session.saveOrUpdate(contact); tx.commit(); session.close(); }}ContactAction.javapackage Action;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionSupport;import common.ContactDAO;import common.StudentDAO;import model.Contact;import model.Student;public class ContactAction extends ActionSupport { /** * */ private static final long serialVersionUID = 1L; private Contact contact; public Contact getContact() { return contact; } public void setContact(Contact contact) { this.contact = contact; } private StudentDAO sdao=new StudentDAO(); private ContactDAO cdao=new ContactDAO(); //保存或者更新聯(lián)系人的方法 public String updatecontact() { //得到request對(duì)象 HttpServletRequest request=ServletActionContext.getRequest(); //得到sess對(duì)象 HttpSession session=request.getSession(); //從session中拿到學(xué)生 Student student= (Student) session.getAttribute("STUDENT"); //保存聯(lián)系人到數(shù)據(jù)庫(kù) cdao.updateContact(contact); //建立Student和Contact的聯(lián)系,誰(shuí)設(shè)置外鍵,用誰(shuí)其中的setter設(shè)置另一個(gè)對(duì)象 student.setContact(contact); //保存更新后的學(xué)生信息到數(shù)據(jù)庫(kù)中 sdao.updateStudent(student); session.setAttribute("STUDENT",student); return "main"; }}發(fā)現(xiàn)的問(wèn)題:當(dāng)在contact.jsp頁(yè)面上修改聯(lián)系人信息的時(shí)候,再點(diǎn)擊進(jìn)入contact.jsp時(shí),信息確實(shí)是在頁(yè)面上顯示更新了。但是 點(diǎn)擊提交去看數(shù)據(jù)庫(kù)中時(shí),發(fā)現(xiàn)student表中的cid字段(外鍵)發(fā)生變化,同時(shí)contact表中是多了一條更新信息之后的記錄(不是在第一次設(shè)置緊急聯(lián)系人的時(shí)候的那條記錄上進(jìn)行更新)。再看控制臺(tái)執(zhí)行的也是 對(duì)contact表 進(jìn)行 insert語(yǔ)句。
問(wèn)題原因:這里調(diào)用的是saveOrUpdate方法,就要了解這個(gè)方法。
saveorupdate():如果傳入的對(duì)象在數(shù)據(jù)庫(kù)中有就做update操作,如果沒(méi)有就做save操作。返回值是voidsave():在數(shù)據(jù)庫(kù)中生成一條記錄,如果數(shù)據(jù)庫(kù)中有,會(huì)報(bào)錯(cuò)說(shuō)有重復(fù)的記錄。save方法返回的是插入數(shù)據(jù)的主鍵update():就是更新數(shù)據(jù)庫(kù)中的記錄
主鍵在saveorupdate()方法中是起著關(guān)鍵作用的,當(dāng)主鍵為空時(shí)進(jìn)行insert,當(dāng)主鍵不為空時(shí)進(jìn)行update。
而做的contact.jsp頁(yè)面上沒(méi)有傳入后臺(tái)Action id值,所以當(dāng)調(diào)用saveOrUpdate方法時(shí),拿不到id值,一直執(zhí)行save方法。也就出現(xiàn)剛才的結(jié)果
解決辦法:應(yīng)該在contact.jsp頁(yè)面上加一個(gè)隱藏變量<input type="hidden" name="contact.id" value="${sessionScope.STUDENT.contact.id}"/> 傳入后臺(tái)Action中,這樣每次保存或更新contact時(shí),就可以根據(jù)id值做出save還是update的選擇,解決這個(gè)記錄冗余的問(wèn)題。
最后修改后的contact.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>緊急聯(lián)系人頁(yè)面</title><link rel="stylesheet" type="text/CSS" href="${pageContext.request.contextPath}/css/TableStyle.css"><script type="text/Javascript" src="${pageContext.request.contextPath}/jslib/jquery-3.1.1.js"></script><script type="text/javascript">$(function(){ if($("[name='contact.sex']:checked").length==0){ $("[name='contact.sex']").eq(0).attr("checked",true); }})</script></head><body><h3>緊急聯(lián)系人頁(yè)面</h3><br><br><s:if test="#session.STUDENT==null"> <jsp:forward page="login.jsp"></jsp:forward></s:if><s:else><form action="${pageContext.request.contextPath}/contact/updatecontact" method="post"><table class="bordered"><tr><td>姓名:</td><td><input type="hidden" name="contact.id" value="${sessionScope.STUDENT.contact.id}"/><input type="text" name="contact.name" value="${sessionScope.STUDENT.contact.name}"></td></tr><tr><td>關(guān)系:</td><td><input type="text" name="contact.relation"value="${sessionScope.STUDENT.contact.relation}"></td></tr><tr><td>性別:</td><td><s:radio list="#{'男':'男','女':'女'}" theme="simple" name="contact.sex" value="#session.STUDENT.contact.sex"/></td></tr><tr><td>電話:</td><td><input type="text" name="contact.phone" value="${sessionScope.STUDENT.contact.phone}"></td></tr><tr><td colspan="2"><input type="submit" value="提交"></td></tr></table></form></s:else><br><br><a href="${pageContext.request.contextPath}/main.jsp">返回主頁(yè)面</a></body></html>初學(xué)者入門(mén),如有不合適的地方還請(qǐng)指出,共同進(jìn)步
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注