我写的这个项目是SSH框架整合刚开始写,所以内容不多,不会占用各位大神太多时间
MySQL数据库有两张表,Baoxiaodan(报销单)表和Baoxiaomingxi(报销明细表),一张报销单有多条报销明细(一 报销单 对 多 报销明细),下面分别这两张表的数据库手写生成代码,Hibernate实体类和Hibernate映射文件
数据库手写生成代码
报销单
CREATE TABLE Biaoxiaodan
(
Id INT PRIMARY KEY AUTO_INCREMENT,
YuangongId INT REFERENCES Yuangong(Id),
YuangongId2 INT REFERENCES Yuangong(Id),
CreateTime DATETIME,
ModifyTime DATETIME,
`Event` NVARCHAR(255),
TotalMoney FLOAT,
StateId INT REFERENCES State(Id)
);
报销明细
CREATE TABLE Biaoxiaomingxi
(
Id INT PRIMARY KEY AUTO_INCREMENT,
`Name` NVARCHAR(20),
BiaoxiaoId INT REFERENCES Biaoxiaodan(Id),
Money FLOAT,
`Event` NVARCHAR(155)
);
Hibernate实体类
报销单
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class Baoxiaodan implements Serializable {
private int id;
private Yuangong yuangong;
private Yuangong yuangong2;
private Date createTime;
private Date modifyTime;
private String event;
private double totalMoney;
private State state;
private List<Baoxiaomingxi> mingxis=new ArrayList<Baoxiaomingxi>();
省略set/get方法
}
报销明细
import java.io.Serializable;
public class Baoxiaomingxi implements Serializable {
private int id;
private Baoxiaodan baoxiaodan;
private BaoxiaoType baoxiaoType;
private double money;
private String event;
//省略set/set方法
}
Hibernate映射文件
报销单
<?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>
<class name="entity.Baoxiaodan" table="Baoxiaodan">
<id name="id" type="java.lang.Integer" column="Id">
<generator class="identity"></generator>
</id>
<property name="event" type="java.lang.String" column="Event"></property>
<property name="createTime" type="java.util.Date" column="CreateTime"></property>
<property name="modifyTime" type="java.util.Date" column="ModifyTime"></property>
<property name="totalMoney" type="java.lang.Double" column="TotalMoney"></property>
<many-to-one name="state" class="entity.State" column="StateId"></many-to-one>
<many-to-one name="yuangong" class="entity.Yuangong" column="YuangongId"></many-to-one>
<many-to-one name="yuangong2" class="entity.Yuangong" column="YuangongId2"></many-to-one>
<list name ="mingxis" cascade="all">
<key column="BaoxiaoId"></key>
<index column="Id"></index>
<one-to-many class ="entity.Baoxiaomingxi"></one-to-many>
</list>
</class>
</hibernate-mapping>
报销明细
<?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>
<class name="entity.Baoxiaomingxi" table="Baoxiaomingxi">
<id name="id" type="java.lang.Integer" column="Id">
<generator class="identity"></generator>
</id>
<property name="money" type="java.lang.Double" column="Money"></property>
<property name="event" type="java.lang.String" column="Event"></property>
<many-to-one name="baoxiaodan" class="entity.Baoxiaodan" column="BaoxiaoId"></many-to-one>
<many-to-one name="baoxiaoType" class="entity.BaoxiaoType" column="TypeId"></many-to-one>
</class>
</hibernate-mapping>
接下来是 JSP文件(添加报销单)和Struts2 Action类,dao及service就一行代码,dao有spring整合的hibernate保存报销单对象(里面包含报销明细集合属性),service调用dao的方法,就不展示了
JSP
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*,java.text.*" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!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>添加报销单</title>
<script type="text/javascript" src="JS/jquery-1.8.3.js"></script>
<script type="text/javascript">
var i=1;
$(function(){
loadTypes(null);
$("form").submit(function(){
var totalMoney=0;
$("[name*='.money']").each(function(){
totalMoney+=parseFloat($(this).val());
});
$("[name='baoxiaodan.totalMoney']").val(totalMoney);
if(confirm("报销总金额为"+$("[name='baoxiaodan.totalMoney']").val()+"元,确认提交?")){
return true;
}else{
return false;
}
});
});
function loadTypes(item){
if(item!=null){
var $select=$(item).parents("tr").next().find("select");
$.ajax({
url:'biaoxiaoTypeList.action',
success:function(result){
$select.append("<option value='0'>请选择</option>");
$.each(result,function(i,value){
$select.append("<option value='"+value.id+"'>"+value.name+"</option>");
});
},
error:function(result){
alert("error!");
}
});
}else{
$.ajax({
url:'biaoxiaoTypeList.action',
success:function(result){
$("select").empty();
$("select").append("<option value='0'>请选择</option>");
$.each(result,function(i,value){
$("select").append("<option value='"+value.id+"'>"+value.name+"</option>");
});
},
error:function(result){
alert("error!");
}
});
}
}
function addItem(item){
var tr=
'<tr class="mingxis">'+
'<td><select name="baoxiaodan.mingxis['+i+'].baoxiaoType.id"></select></td>'+
'<td><input type="text" name="baoxiaodan.mingxis['+i+'].money" /></td>'+
'<td><input type="text" name="baoxiaodan.mingxis['+i+'].event" /></td>'+
'<td>'+
'<a href="javascript:void(0)" onclick="addItem(this)">添加</a> '+
'<a href="javascript:void(0)" onclick="delItem(this)">删除</a>'+
'</td>'+
'</tr>';
$(item).parents("tr").after(tr);
loadTypes(item);
i++;
}
function delItem(item){
$(item).parents("tr").remove();
i=0;
$(".mingxis").each(function(){
i++;
});
}
</script>
</head>
<body><form action="baoxiaodanAdd.action" method="post">
<%Date createTime=new Date(); %>
<s:fielderror></s:fielderror>
<table align="center" width="100%">
<tr><td colspan="2"><h3 style="display: inline;">添加报销单</h3></td></tr>
<tr>
<td>*填报人:${user.name}</td>
<td>*填报时间:<%=new SimpleDateFormat("yyyy年MM月日 hh:mm:ss").format(createTime)%></td>
</tr>
<input type="hidden" name="baoxiaodan.createTime" value='<%=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(createTime)%>'/>
<input type="hidden" name="baoxiaodan.yuangong.id" value="${user.id}"/>
<input type="hidden" name="baoxiaodan.yuangong2.id" value="${user.id}"/>
<input type="hidden" name="baoxiaodan.state.id" value="1"/>
<tr>
<td>*总金额:¥<input type="text" name="baoxiaodan.totalMoney" value="系统根据输入自动生成" readonly="readonly"/></td>
<td>*状态:新创建</td>
</tr>
</table>
<table align="center" width="100%">
<tr>
<td>项目类别</td>
<td>项目金额</td>
<td>费用说明</td>
<td>操作</td>
</tr>
<tr class="mingxis">
<td><select name="baoxiaodan.mingxis[0].baoxiaoType.id"></select></td>
<td><input type="text" name="baoxiaodan.mingxis[0].money" /></td>
<td><input type="text" name="baoxiaodan.mingxis[0].event" /></td>
<td>
<a href="javascript:void(0)" onclick="addItem(this)">添加</a>
<a href="javascript:void(0)" onclick="delItem(this)">删除</a>
</td>
</tr>
<tr><td colspan="4">*是由:<textarea style="width:900px;" rows="8" name="baoxiaodan.event"></textarea></td></tr>
<tr><td colspan="4" align="center">
<input type="submit" value="保存" />
<input type="submit" value="提交" />
</td></tr>
</table>
</form></body>
</html>
Struts2 Action类
package action;
import java.util.List;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import entity.BaoxiaoType;
import entity.Baoxiaodan;
import entity.Baoxiaomingxi;
import entity.Zhiwu;
import service.BaoxiaoService;
public class BaoxiaoAction extends ActionSupport {
private BaoxiaoService baoxiaoService;
private Baoxiaodan baoxiaodan;
private List<BaoxiaoType> baoxiaoTypeList;
private List<Zhiwu> zhiwuList;
Map session=ActionContext.getContext().getSession();
public String baoxiaodanList(){
session.put("baoxiaodanList",baoxiaoService.baoxiaodanList());
return SUCCESS;
}
public String baoxiaodanAdd(){
baoxiaoService.baoxiaodanAdd(baoxiaodan);
return SUCCESS;
}
public String baoxiaoTypeList(){
baoxiaoTypeList=baoxiaoService.baoxiaoTypeList();
return SUCCESS;
}
public String zhiwuList(){
zhiwuList=baoxiaoService.zhiwuList();
return SUCCESS;
}
public void setBaoxiaoService(BaoxiaoService baoxiaoService) {
this.baoxiaoService = baoxiaoService;
}
public List<Zhiwu> getZhiwuList() {
return zhiwuList;
}
public void setZhiwuList(List<Zhiwu> zhiwuList) {
this.zhiwuList = zhiwuList;
}
public List<BaoxiaoType> getBaoxiaoTypeList() {
return baoxiaoTypeList;
}
public void setBaoxiaoTypeList(List<BaoxiaoType> baoxiaoTypeList) {
this.baoxiaoTypeList = baoxiaoTypeList;
}
public Baoxiaodan getBaoxiaodan() {
return baoxiaodan;
}
public void setBaoxiaodan(Baoxiaodan baoxiaodan) {
this.baoxiaodan = baoxiaodan;
}
}
结果在JSP文件一点提交,显示成功保存,再看数据库,发现报销单数据Id正确自增,而属于它的明细则是从0开始自增,然后再次保存报销单就报错了,从报错信息里发现是明细编号重复,从0开始自增
你用navicat看看数据库中的表的主键是否为自增的。
经过一番痛苦的尝试,问题算是解决了,在“Baoxiaodan“表映射文件中把对"Baoxiaomingxi"表的一对多关系设置在“list”中,无论怎么弄,最终报销单保存连带所属报销明细保存的时候,报销明细的编号始终是从0开始,而改为“set”之后就正常了,我觉得这是hibernate的一个bug,如果大家有不同意见,欢迎来指正,谢谢!