springboot 入門教程(5) 基於ssm框架的crud操做(前端部分-附源碼)

上一篇介紹了spring boot整合mybatis實現了後端的CRUD的查詢部分,本文主要是完善修改、刪除和添加操做的後端,實現前端頁面的調用。javascript

源碼連接(上一篇的源碼有bug建議你們就看最新的)css

一、完善添加、修改、刪除後臺

    接口上篇已經定義號了,mapper也寫完了,接下來就是完善conntroller,並測試。直接上conntroller的代碼吧,裏面註釋進行了說明。html

    這個版本里面加了分頁,service中的方法有的些變化,我也貼出來供你們參考,分頁的類在源碼中有這裏就不貼了。前端

UserController.javajava

package com.pxk.springboot.conntroller;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.pxk.springboot.domain.User;
import com.pxk.springboot.helper.PageInfo;
import com.pxk.springboot.serivce.UserService;

@RestController
@RequestMapping("/user")
public class UserController {
	@Autowired // 依賴注入service
	UserService userService;

	@RequestMapping("/getUser/{name}") // 定義requestMapping rest風格
	protected User getUser(@PathVariable(value = "name") String name) {
		return userService.getUser(name);
	}

	@RequestMapping("/getUserByName/{name}")
	protected String getUserByName(@PathVariable(value = "name") String name, Model model) {
		User user = userService.getUser(name);
		model.addAttribute(user);
		return "user";
	}
	/**================分割線==================*/

	@RequestMapping("/findUserByPage")
	@ResponseBody
	public PageInfo<User> getStudents(PageInfo<User> pageInfo) {
		return userService.findUserByPage(pageInfo);
	}

	@RequestMapping("/getUserById")
	protected User getUserById(int id) {
		return userService.getUserById(id);
	}

	@RequestMapping("/deleteUser")
	protected int deleteUser(int id) {
		User user = new User();
		user.setId(id);
		return userService.deleteUser(user);
	}

	@RequestMapping(value="/addUser", method = RequestMethod.POST)
	protected int addUser(User user) {
		if(user.getId()!=null&&user.getId()!=0){
			return userService.updateUser(user);
		}else{
			user.setRegestDate(new Date());
			return userService.addUser(user);
		}
	}

}

UserServiceImpl.javajquery

package com.pxk.springboot.serivce.imp;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.pxk.springboot.dao.UserMapper;
import com.pxk.springboot.domain.User;
import com.pxk.springboot.helper.Page;
import com.pxk.springboot.helper.PageInfo;
import com.pxk.springboot.serivce.UserService;
@Service//注入成service
public class UserServiceImpl implements UserService {
	@Autowired
	private UserMapper userMapper;
	@Override
	public User getUser(String name) {
		return new User(name);
	}

	//這裏實現了分頁,看着有點複雜,是由於我原來習慣使用分頁插件包(pageHelper),這裏爲了方便理解直接省略了插件包
	//簡化使用了這個包裏面的兩個類Page和PageInfo
	@Override
	public PageInfo<User> findUserByPage(PageInfo<User> pageInfo) {
		long count =userMapper.findCount();
		List<User> list=userMapper.findUserByPage((pageInfo.getPageNum()-1)*pageInfo.getPageSize(), pageInfo.getPageSize());
		Page<User> page=new Page<>(pageInfo.getPageNum(), pageInfo.getPageSize());
		page.setTotal(count);
		PageInfo<User> rpg = new PageInfo<User>(page);
		rpg.setList(list);
		return rpg;
	}

	@Override
	public User getUserById(int id) {
		return userMapper.getUserById(id);
	}

	@Override
	public int updateUser(User user) {
		return userMapper.updateUser(user);
	}

	@Override
	public int deleteUser(User user) {
		return userMapper.deleteUser(user);
	}

	@Override
	public int addUser(User user) {
		return userMapper.addUser(user);
	}
}

二、整合前端Bootstap Table + jquery

    前端其實很簡單,只有一個核心的html頁面和一個js,有不少細節這裏就不作過多介紹,好比表單中包括附件,處理方式確定不一樣了哈。多選刪除我原本已經實現了,可是爲了簡化又刪了。分頁是藉助了BootStrap分頁的參數(這個參數會自動帶到後臺,Bootstap table源碼的參數和後臺我用PageInfo屬性名不一致,我改過Bootstap源碼,目的就是爲了避免改pagehelper那個分頁插件,也就是我選擇改前端來適應後端,就目前這個例子而言改先後都不會有影響。注意:直接在官網下載的BootStrap Table分頁和這個例子的後臺不能兼容web

    直接貼出html和js,懂點前端的朋友都能看懂,BootStrap Table很差理解的地方所有加了註釋,個人前端很爛的,寫得很差還請見諒了。ajax

    userList.htmlspring

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用戶列表</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="../css/userList.css">
<link rel="stylesheet" type="text/css"
	href="../css/bootstrap/css/bootstrap.css">
<link rel="stylesheet" type="text/css"
	href="../css/bootstrap-select.min.css">
<script type="text/javascript" src="../js/jquery-1.12.0.js"></script>
<script type="text/javascript" src="../js/common.js"></script>
<script type="text/javascript" src="../js/bootstrap-table.js"></script>
<script type="text/javascript" src="../js/bootstrap-table-zh-CN.min.js"></script>
<script type="text/javascript" src="../css/bootstrap/js/bootstrap.js"></script>
<script type="text/javascript" src="js/userList.js"></script>
</head>

<body>
	<div class="container">
		<div class="row">
			<form class="form-horizontal" role="form">
				<div class="from-group">

					<div class="col-sm-1">
						<input type="button" class="btn  btn-primary" value="新增"
							onclick="addUser()" />
					</div>
				</div>
			</form>
		</div>

		<div class="">
			<table id="mytab" class="table table-hover"></table>

		</div>
	</div>
	<!-- 編輯用戶信息  模態窗口-->
	<div class="modal fade" id="myModal" tabindex="-1" role="dialog"
		aria-labelledby="myModalLabel" aria-hidden="true">
		<div class="modal-dialog">
			<div class="modal-content">
					<div class="modal-header">
						<button type="button" class="close" data-dismiss="modal"
							aria-hidden="true">×</button>
						<h4 class="modal-title" id="myModalLabel">修改用戶信息</h4>
					</div>
					<div class="modal-body">
						<input type="hidden" id="sid" name="sid" />
						<div class="form-group">
							<label class="control-label">姓名:</label><input name="name"
								id="usernameTextE" type="text" class="form-control" />
						</div>
						<div class="form-group">
							<label class="control-label">性別:</label>&nbsp;&nbsp;&nbsp;&nbsp;<input
								id="gederTextM" value="M" name="gender" type="radio" />&nbsp;&nbsp;&nbsp;&nbsp;男&nbsp;&nbsp;&nbsp;&nbsp;<input
								id="gederTextF" name="gender" value="F" type="radio" />&nbsp;&nbsp;&nbsp;&nbsp;女
						</div>
						<div class="form-group">
							<label class="control-label">年齡:</label><input name="age"
								id="ageTextE" type="text" class="form-control" />
						</div>
					</div>
					<div class="modal-footer">
						<button type="button" class="btn btn-default" data-dismiss="modal">關閉</button>
						<button type="button" class="btn btn-primary" onclick="saveUser()">保存</button>
					</div>
			</div>
			<!-- /.modal-content -->
		</div>
		<!-- /.modal-dialog -->
	</div>
	<!-- /.modal -->
</body>
</html>

userList.js數據庫

var myrow = {};
$(function() {
	$('#mytab').bootstrapTable({
		url : "../user/findUserByPage",// 數據源
		dataField : "list",// 服務端返回數據鍵值 就是說記錄放的鍵值是rows,分頁時使用總記錄數的鍵值爲total
		// search: true,//是否搜索
		totalField : "total",// 接收總頁數的參數
		pagination : true,// 是否分頁
		pageSize : 5,// 單頁記錄數
		pageList : [ 5, 10, 20, 50 ],// 分頁步進值
		sidePagination : "server",// 服務端分頁
		// contentType: "application/x-www-form-urlencoded",//請求數據內容格式 默認是
		// application/json 本身根據格式自行服務端處理
		dataType : "json",// 期待返回數據類型
		method : "get",// 請求方式
		searchAlign : "left",// 查詢框對齊方式
		queryParamsType : "other",// 查詢參數組織方式 爲limit時候傳的參數是 offset和limit,不然爲
		// pageSize和pageNumber
		// 能夠帶查詢參數
		// queryParams : function getParams(params) {
		// params.name = $('#usernameText').val();
		// return params;
		// },
		searchOnEnterKey : false,// 回車搜索
		columns : [
		// {
		// title : "全選",
		// // field : "select",
		// checkbox : true,
		// width : 20,// 寬度
		// align : "center",// 水平
		// valign : "middle"// 垂直
		// },
		{
			title : "用戶名",// 標題
			field : "name"// 鍵名
		// sortable: true,//是否可排序
		// order: "desc"//默認排序方式
		}, {
			field : "gender",
			title : "性別",
			formatter : function(value, row, index) {
				if (value == "F") {
					return "女";
				} else {
					return "男";
				}
			}
		},{
			title : "註冊時間",// 標題
			field : "regestDate"// 鍵名
		}, {
			title : "操做",
			field : "control",
			width : 70,
			align : "center",
			valign : "middle",
			formatter : operateFormatter,
			events : "operateEvents"
		} ],
		locale : "zh-CN", // 中文支持,
		detailView : false
	// 是否顯示詳情摺疊
	});
});
window.operateEvents = {
	'click .remove' : function(e, value, row) {
		deleteSudentsById(row.id);
	},
	'click .edite' : function(e, value, row) {
		$("#myModal").modal('show');
		$("#sid").val(row.id);
		// 爲輸入框賦值
		$("#usernameTextE").val(row.name);
		$("#ageTextE").val(row.age);
		$("#regestDateE").val(row.regestDate);
		row.gender == "F" ? $("#gederTextF").prop("checked", "checked") : $(
				"#gederTextM").prop("checked", "checked");
	}
};
function operateFormatter(value, row, index) {
	return [
			'<div class="pull-center">',
			'<a  class="edite" href="javascript:void(0)" title="編輯" href="#"><span class="glyphicon glyphicon-expand"></span></a>',
			'&nbsp;&nbsp;&nbsp;&nbsp;<a class="remove" href="javascript:void(0)" title="刪除">',
			'<i class="glyphicon glyphicon-remove"></i>', '</a>', '</div>' ]
			.join('');
}
// 新增用戶
function addUser() {
	$("#sid").val("");
	// 狀況信息編輯窗口(編輯和新增公用了一個窗口須要清空)
	$("#usernameTextE").val("");
	$("#gederTextM").attr("checked", "checked");// 性別默認爲男
	$("#dd").html("");// 清空頭像
	// 彈出信息編輯模態窗口
	$("#myModal").modal('show');
}
// 保存用戶信息
function saveUser() {
	// 調用後臺方法進行保存
	$.ajax({
		url : '../user/addUser',
		type : 'POST',
		data : {
			id : $("#sid").val(),
			// 爲輸入框賦值
			name : $("#usernameTextE").val(),
			age : $("#ageTextE").val(),
			gender : $('#gederTextM:checked').val()
		},
		async : false,
		cache : false,
		success : function(returndata) {
			// 關閉模態窗口
			$("#myModal").modal('hide');
			// 刷新列表
			$('#mytab').bootstrapTable('refresh');
		},
		error : function(returndata) {
			alert("添加失敗!");
		},
		dataType : "json"
	});
}
function deleteSudentsById(id) {
	var r = confirm("確認要刪除該數據嗎!");
	if (r == true) {
		$.get("../user/deleteUser", {
			id : id
		}, function(data) {
			alert("刪除成功!");
			// 刷新列表
			$('#mytab').bootstrapTable('refresh');
		}, "json");
	} else {
		alert("刪除失敗!")
	}
}
// 下面用於多圖片上傳預覽功能
function setImagePreviews(avalue) {
	var docObj = document.getElementById("upload-file");
	var dd = document.getElementById("dd");
	dd.innerHTML = "";
	var fileList = docObj.files;
	for (var i = 0; i < fileList.length; i++) {
		dd.innerHTML += "<img id='img" + i + "'  />";
		var imgObjPreview = document.getElementById("img" + i);
		if (docObj.files && docObj.files[i]) {
			// 火狐下,直接設img屬性
			imgObjPreview.style.display = 'block';
			imgObjPreview.style.width = '150px';
			imgObjPreview.style.height = '180px';
			// imgObjPreview.src = docObj.files[0].getAsDataURL();
			// 火狐7以上版本不能用上面的getAsDataURL()方式獲取,須要一下方式
			imgObjPreview.src = window.URL.createObjectURL(docObj.files[i]);
		} else {
			// IE下,使用濾鏡
			docObj.select();
			var imgSrc = document.selection.createRange().text;
			alert(imgSrc)
			var localImagId = document.getElementById("img" + i);
			// 必須設置初始大小
			localImagId.style.width = "150px";
			localImagId.style.height = "180px";
			// 圖片異常的捕捉,防止用戶修改後綴來僞造圖片
			try {
				localImagId.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale)";
				localImagId.filters
						.item("DXImageTransform.Microsoft.AlphaImageLoader").src = imgSrc;
			} catch (e) {
				alert("您上傳的圖片格式不正確,請從新選擇!");
				return false;
			}
			imgObjPreview.style.display = 'none';
			document.selection.empty();
		}
	}
	return true;
}

 總結:

    其實這個demo前端你們可能會陌生一些,若是你們不習慣用BootStrap Table那就隨便換,後臺都實現了並且是rest接口 前端隨便你怎麼換,參數給對了就好了。

    坑:

    一、遇到亂碼問題,若是是數據傳到後臺沒亂碼,那必定就是數據庫的問題,設置下數據庫服務端編碼搞定,若是是前端傳到後端出現亂碼,那springboot 提供了直接在application.properties中設置編碼(參見源碼)

    二、實體屬性和數據庫屬性對應不上的時候要注意了,好比數據庫用的下劃線隔開,實體類中用的駝峯。

    三、日期的格式,spring mvc rest方式接口會自動轉json格式返回,可是若是是日期格式默認直接轉換成毫秒,須要在實體屬性上加上註解@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")。

    四、mybatis語法上的一些細節,這個只能靠多用多練了。

一個完整項目要用到的技術點太多,這只是個demo有不少細節沒有作處理(異常處理、單元測試、返回結果封裝、數據加密、接口權限等等,太多了就不一一列舉了,之後有機會用專題文章來介紹)

相關文章
相關標籤/搜索