先看我要做成什么效果?有空扫下我们的二维码呗!
一次性保存多条数据(批量保存)比较简单方便的做法就是使用json格式,具体看我的这篇文章,批量保存数据(json版),该篇文章详细的介绍了使用json来做批量保存!有图有代码有步骤!
但是我本篇文章并没有使用json,我本篇文章使用的是字符串拼接的办法,这种办法比较笨,也比较麻烦一些,但是学习还是不要怕麻烦,一开始不要怕麻烦,等知道了解题思路后,我们再用简单实用的新办法取代旧的笨的办法,这样我们才能循序渐进一点一点的进步!
这是fieldTable.jsp页面
上面的图就是我们要做成的样子,点击加号按钮,就在页面上增加一行,然后在行里的文本框中填写数据,点击保存数据到数据库中的按钮,就会把页面上的每一行数据都保存到数据库中的fieldInfo(字段表)表中,也就是批量保存!
看下面的效果图!
这就是我们要开发的批量保存!OK,接下来贴上代码(代码写完后我还没有整理,所以某个函数中的代码比较多,本来按照代码规范来说的话,一个函数中的代码最多不要超过30行,这样也比较容易阅读!所以还请大家大家见谅!说实话,我写这个批量保存,也是一时头脑发热,临时起意,突然就想写一个批量保存的东西!因为有时候我会想,如果我在一个jsp页面中,同时编辑多条记录,编辑好之后,点击提交,把刚才编辑的多条记录一口气的保存到数据库中,我在想,如果同时编辑了50条记录,点击提交保存,一口气保存50条记录到数据库中,效率上会不会不高,本着这样的想法,所以我临时起意写的这个批量保存的功能!或者这么说把,将来我要是在某些jsp页面上有table表格,表格中有多行记录,我点击保存,要把表格中的每一行的每个单元格的数据都保存到数据库中,这时候我写的这个批量保存就可以派上用场了,到时候我把我现在写的批量保存的代码拿出来改造一下,做成一个通用的批量保存的函数,供其他页面或者其他地方调用,那不是很好嘛?)
好了好了,废话不多说了,还是上代码吧!刚才就是要上代码的,结果我又啰嗦了一大堆!
这是fieldTable.jsp页面的代码!
<strong><%@page import="com.jiongmeng.entity.GoodsType"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!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>
<link rel="stylesheet" type="text/css" href="background/css/body.css"
media="all">
<link rel="stylesheet" type="text/css" href="background/css/mark.css">
<script type="text/javascript" src="background/js/ToolTip.js"></script>
<style type="text/css">
input {
width: 300px;
height: 30px;
border: 2px solid #8E388E;
border-radius: 4px; /*设置边框的4个直角变成圆角有弧度*/
font-weight: bold; /*文本框中的文本字体加粗*/
color: black;
background-color: #F2F2F2;
}
input[type=button], input[type=submit]{
width: auto;
color: white;
background-color: #8E388E;
}
</style>
<script type="text/javascript">
//追加一行
function addRow(){
var tableNode = document.getElementById("fieldTable");
var trNodeList = tableNode.getElementsByTagName("tr");
// for (var index = 0; index < trNodeList.length; index++) {
// var tdNodeList = trNodeList[index].getElementsByTagName("td");
// for (var i = 0; i < tdNodeList.length; i++) {
// alert(tdNodeList[i].id);
// }
// }
//得到最后一行(tr)的所有td
var tdNodeList = trNodeList[trNodeList.length - 1].getElementsByTagName("td");
var td_input_name = tdNodeList[0].getElementsByTagName("input")[0].name;
var strIndex = td_input_name.indexOf("_");
var number = td_input_name.substring(strIndex + 1)
var trNode = document.createElement("tr");
number++;
var tdText = '';
var td1_input_fieldName = '<td><input type="text" name="fieldName_' + number + '" value=""></td>';
var td2_input_fieldType = '<td><input type="text" name="fieldType_' + number + '" value=""></td>';
var td3_input_fieldLength = '<td><input type="text" name="fieldLength_' + number + '" value=""></td>';
tdText = td1_input_fieldName + td2_input_fieldType + td3_input_fieldLength;
trNode.innerHTML = tdText;
tableNode.appendChild(trNode);
//alert("追加一行");
}
</script>
</head>
<body>
<%
/**
jsp中有内置对象,平时我们java中使用对象需要1.先声明2创建,而内置对象不需要声明也不需要创建,可以直接拿来使用,jsp内
置对象也叫隐藏对象或隐含对象或隐式对象
*/
//测试代码
GoodsType goodsType = null;
request.setAttribute("goodsType", goodsType);
String hometown = "江西省赣州市于都县";
session.setAttribute("hometown", hometown);
System.out.println("我是test.jsp页面!");
%>
测试空实体对象.属性是否会报空指针异常=${requestScope.goodsType.goodsTypeId }
<br> 家乡 = ${sessionScope.hometown}
<%
request.setAttribute("test", "jack");
request.setAttribute("test", "jerry");
out.print(request.getAttribute("test") + "<br>");
pageContext.setAttribute("myHome", "江西省赣州市于都县");
request.setAttribute("myHome", "于都县");
out.println("myHome = " + pageContext.getAttribute("myHome"));
%>
<br> hometown:${requestScope.hometown }
<form action="fieldTableServlet" method="post">
<input type="submit" value="保存数据到数据库中">
<input type="button" value="+(增加一行)" onclick="addRow()">
<table id="fieldTable">
<tr id="tr1">
<th>字段名</th>
<th>字段类型</th>
<th>字段长度</th>
</tr>
<tr id="tr2">
<td id="td1"><input type="text" name="fieldName_1" value="姓名"></td>
<td id="td2"><input type="text" name="fieldType_1" value="字符串"></td>
<td id="td3"><input type="text" name="fieldLength_1" value="40"></td>
</tr>
<tr id="tr3">
<td id="td1"><input type="text" name="fieldName_2" value="籍贯"></td>
<td id="td2"><input type="text" name="fieldType_2" value="字符串"></td>
<td id="td3"><input type="text" name="fieldLength_2" value="120"></td>
</tr>
</table>
</form>
<c:if test="${!(empty requestScope.message)}">
<script type="text/javascript">
showWindow("温馨提示", "${requestScope.message}", 500, 120, true);
</script>
</c:if>
</body>
</html></strong>
jsp页面上的form表单提交到一个servlet中,然后在servlet中去处理!我就在servlet中拼接的sql语句,然后在servlet中调用dao,规范的做法肯定不是这样做的,sql语句要写在dao层,我这里是为了省事图方便,所以才在servlet中写sql语句。
接下来看servlet中的代码,servlet的类名叫FieldTableServlet,FieldTableServlet类的url访问路径是fieldTableServlet,也就是我们fieldTable.jsp页面中的form表单的action要填写的地址,即action="fieldTableServlet"(注意:FieldTableServlet类中的saveFieldTable()函数中的代码我还没整理,小伙伴们凑合着看,你们自己去整理也可以哈,当然,你们也可以有不同的写法,思路对了就行!)
<strong>package com.jiongmeng.test;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.jiongmeng.db.JdbcTemplate;
@WebServlet("/fieldTableServlet")
public class FieldTableServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
JdbcTemplate jdbcTemplate = new JdbcTemplate();
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
int row = saveFieldTable(request, response);
request.setAttribute("message", row > 0 ? "成功保存" + row + "条记录!" : "保存失败!");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
request.getRequestDispatcher("fieldTable.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 处理中文乱码,可以使用过滤器
request.setCharacterEncoding("utf-8");
doGet(request, response);
}
protected int saveFieldTable(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException, ClassNotFoundException, SQLException {
// 得到所有的请求参数名称
Enumeration<String> parameterNames = request.getParameterNames();
// 用来装所有的参数名称的后缀(即下划线后面的)
List<String> parameterNamesSuffix = new ArrayList<String>();
List<String> newParameterNamesSuffix = new ArrayList<String>();
// 用来装所有的参数名称和参数值
Map<String, String> parameterNamesAndValues = new HashMap<String, String>();
List<String> parameterNameList = new ArrayList<String>();
while (parameterNames.hasMoreElements()) {
// 得到请求参数的名称
String parameterName = parameterNames.nextElement();
// 根据下划线拆分
String[] myParameterName = parameterName.split("_");
// 得到下划线后面的部分
parameterNamesSuffix.add(myParameterName[myParameterName.length - 1]);
// 保存参数名称和参数值
parameterNamesAndValues.put(parameterName, request.getParameter(parameterName));
parameterNameList.add(parameterName);
String parameterValue = request.getParameter(parameterName);
System.out.println(parameterName + " = " + parameterValue);
}
// 去重
Set<String> set = new HashSet<String>();
for (String parameterNameSuffix : parameterNamesSuffix) {
if (set.add(parameterNameSuffix)) {
newParameterNamesSuffix.add(parameterNameSuffix);
}
}
System.out.println("--------请求参数的名称和参数值-------------------------");
Set<Entry<String, String>> entrySetParameterNamesAndValues = parameterNamesAndValues.entrySet();
Iterator<Entry<String, String>> it = entrySetParameterNamesAndValues.iterator();
System.out.println("-------------请求参数的后缀--------------------");
String[] fieldNames = new String[parameterNamesAndValues.size()];
String[] fieldValues = new String[parameterNamesAndValues.size()];
int elementIndex = 0;
while (it.hasNext()) {
Entry<String, String> entry = it.next();
fieldNames[elementIndex] = entry.getKey();
fieldValues[elementIndex] = entry.getValue();
elementIndex++;
}
for (int i = 0; i < fieldNames.length; i++) {
System.out.println(fieldNames[i] + " - " + fieldValues[i]);
}
System.out.println("------------------------------------");
int successCount = 0;
for (int i = 0; i < newParameterNamesSuffix.size(); i++) {
FieldTable fieldTable = new FieldTable();
StringBuffer sql = new StringBuffer(
"INSERT INTO fieldInfo ( fieldName , fieldType , fieldLength ) VALUES (");
System.out.println(newParameterNamesSuffix.get(i));
for (int index = 0; index < fieldNames.length; index++) {
String[] field = fieldNames[index].split("_");
if (newParameterNamesSuffix.get(i).equals(field[field.length - 1])) {
System.out.println(
newParameterNamesSuffix.get(i) + " " + fieldNames[index] + " " + fieldValues[index]);
if ("fieldName".equals(field[0])) {
fieldTable.setFieldName(fieldValues[index]);
} else if ("fieldType".equals(field[0])) {
fieldTable.setFieldType(fieldValues[index]);
} else if ("fieldLength".equals(field[0])) {
fieldTable.setFieldLength(fieldValues[index]);
}
}
}
sql.append(" '" + fieldTable.getFieldName() + "', ");
sql.append(" '" + fieldTable.getFieldType() + "', ");
sql.append(" '" + fieldTable.getFieldLength() + "' )");
int row = jdbcTemplate.update(sql.toString());
successCount += row;
System.out.println(sql.toString());
}
System.out.println("共保存了" + successCount + "条数据!");
return successCount;
}
}
</strong>
fieldTable.jsp页面中有几行记录,就会生成几条INSERT插入语句,后台就会调用几次插入数据的函数,如下就是根据fieldTable.jsp页面中的记录行生成的INSERT的sql语句。
INSERT INTO fieldInfo ( fieldName , fieldType , fieldLength ) VALUES ( '姓名', '字符串', '40' )
INSERT INTO fieldInfo ( fieldName , fieldType , fieldLength ) VALUES ( '籍贯', '字符串', '120' )
INSERT INTO fieldInfo ( fieldName , fieldType , fieldLength ) VALUES ( '年龄', '整型', '3' )
INSERT INTO fieldInfo ( fieldName , fieldType , fieldLength ) VALUES ( '家庭地址', '字符串', '90' )
INSERT INTO fieldInfo ( fieldName , fieldType , fieldLength ) VALUES ( '电话号码', '字符串', '11' )
等等等.......后面的sql语句我就不全部列举出来了!大家知道意思就行哈!
最后一个类就是实体类了,实体类的类名叫FieldTable,该类中就是一些属性,其实就是和数据库中fieldInfo表中的字段相互对应(属性包括fieldId,fieldName,fieldType,fieldLength)和set,get方法和构造方法!代码如下:
<strong>/**
* <p>Application Name: jmBookShop</p>
* <p>Application Description: 医疗管理系统产品</p>
* <p>Copyright: Copyright (c) 2017 版权归囧萌软件科技公司所有</p>
* <p>Time: 2017年11月23日下午11:29:25</p>
* <p>Company: 囧萌软件科技公司</p>
* @author 囧囧 E-mail:666888999@qq.com
* @author <a href="666888999@qq.com">囧囧</a>
* @version 1.0
*/
package com.jiongmeng.test;
/**
* @Description: (这里用一句话描述这个类的作用)
* @author 囧囧 E-mail:666888999@qq.com jerry
* @date: 2017年11月23日 下午11:29:25
* <p>
* Copyright: Copyright (c) 2005-2017版权归囧萌软件科技公司所有
* </p>
* @version 创建时间:2017年11月23日 下午11:29:25
*/
public class FieldTable {
private int fieldId;
private String fieldName;
private String fieldType;
private String fieldLength;
/**
* <p>Title: </p>
* <p>Description: </p>
*/
public FieldTable() {
super();
}
/**
* <p>Title: </p>
* <p>Description: </p>
* @param fieldName
* @param fieldType
* @param fieldLength
*/
public FieldTable(String fieldName, String fieldType, String fieldLength) {
super();
this.fieldName = fieldName;
this.fieldType = fieldType;
this.fieldLength = fieldLength;
}
/**
* <p>Title: </p>
* <p>Description: </p>
* @param fieldId
* @param fieldName
* @param fieldType
* @param fieldLength
*/
public FieldTable(int fieldId, String fieldName, String fieldType, String fieldLength) {
super();
this.fieldId = fieldId;
this.fieldName = fieldName;
this.fieldType = fieldType;
this.fieldLength = fieldLength;
}
/**
* @return the fieldId
*/
public int getFieldId() {
return fieldId;
}
/**
* @param fieldId the fieldId to set
*/
public void setFieldId(int fieldId) {
this.fieldId = fieldId;
}
/**
* @return the fieldName
*/
public String getFieldName() {
return fieldName;
}
/**
* @param fieldName the fieldName to set
*/
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
/**
* @return the fieldType
*/
public String getFieldType() {
return fieldType;
}
/**
* @param fieldType the fieldType to set
*/
public void setFieldType(String fieldType) {
this.fieldType = fieldType;
}
/**
* @return the fieldLength
*/
public String getFieldLength() {
return fieldLength;
}
/**
* @param fieldLength the fieldLength to set
*/
public void setFieldLength(String fieldLength) {
this.fieldLength = fieldLength;
}
}
</strong>
批量保存的功能就介绍到这里了,其实我们只要保持对软件功能的好奇,我们就会在看到别人的软件的时候去思考,咦,这功能是怎么做出来的,咦,如果让我来做这个功能,我会怎么做,我会怎么写这个功能呢?咦,我这样写有没有比别人的写法执行效率更高,性能更好呢?咦,我写的代码有没有像写诗一样行云流水,阅读起来简单明了的感觉呢?如果还没有像写诗一样行云流水的感觉,就说明我们写的代码还不够好,不够精辟,不够清晰明了,不够通俗易懂,不够流畅,所以还有提高的空间,还有优化的空间,还有重构的空间,所以对程序保持好奇,这样我们才能不断的进步和提高自身的能力!
有空扫下我们的二维码呗!