项目总目录:基于Hadoop的好友推荐系统项目综述
一、数据表的初始化
1、前端展示层
jsp页面
<select id="cc" class="easyui-combobox" name="dept"
style="width:200px;">
<option value="LoginUser">用户登录表</option>
<option value="HConstants">集群配置表</option>
</select>
<a id="initialId" href="#" class="easyui-linkbutton"
data-options="iconCls:'icon-search'">初始化</a> <br>
<br>
<br>
js处理逻辑:
// 绑定button
$('#initialId').bind('click', function(){
var tableName=$('#cc').combobox("getValue");;
console.info(tableName);
// 弹出进度框
var win = $.messager.progress({
title : 'Please waiting',
msg : '初始化表中中...',
interval : '1200' //设置时间间隔较长
});
// ajax 异步提交任务
// console.info('tt');
$.ajax({
url : "dB/dB_initialTable.action",
data: {tableName:tableName},
async:true,
context : document.body,
success : function(data) {
// console.info(data);
$.messager.progress('close');
var retMsg;
if("true"==data){
retMsg='表初始化成功!';
}else{
retMsg='表初始化失败!';
}
$.messager.show({
title : '提示',
msg : retMsg
});
}
});
});
2、action层
action层接受前端页面提交的参数data: {tableName:tableName},通过判断tableName来判断初始化什么数据。
/**
* 初始化表
*/
public void initialTable(){
boolean initRet = false;
if("LoginUser".equals(tableName)){//初始登录表
initRet=dBService.insertLoginUser();
}else if("HConstants".equals(tableName)){//初始化集群配置表
initRet=dBService.insertHConstants();
}else{
initRet = dBService.insertUserData();//初始用户表(未使用)
}
Utils.write2PrintWriter(initRet);
}
3、service层
首先来看初始化登录表的逻辑
/**
* 初始化登录表
*
* @param tableName
* @return
*/
public boolean insertLoginUser() {
try {
baseDao.executeHql("delete LoginUser");
baseDao.save(new LoginUser("admin", "admin"));
baseDao.save(new LoginUser("test", "test"));
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
这里通过调用baseDao的save方法保存了两个初始数据(admin,admin)和(test,test)。
再来看初始化集群配置表的逻辑
/**
* 初始化HConstants
*
* @return
*/
public boolean insertHConstants() {// 初始化hadoop集群表(需要将其初始化为自己的hadoop配置信息)
try {
baseDao.executeHql("delete HConstants");
baseDao.save(new HConstants("mapreduce.app-submission.cross-platform", "true", "是否跨平台提交任务"));
baseDao.save(new HConstants("fs.defaultFS", "hdfs://sparkproject1:9000", "namenode主机及端口"));
baseDao.save(new HConstants("mapreduce.framework.name", "yarn", "mapreduce 使用配置"));
baseDao.save(new HConstants("yarn.resourcemanager.address", "sparkproject1:8032", "ResourceManager主机及端口"));
baseDao.save(
new HConstants("yarn.resourcemanager.scheduler.address", "sparkproject1:8030", "Scheduler主机及端口"));
baseDao.save(new HConstants("mapreduce.jobhistory.address", "sparkproject1:10020", "JobHistory主机及端口"));
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
这里初始化了集群配置的各项数据,具体描述在上面也有,只需要根据实际情况进行修改即可。
二、数据表的增删改查
1、用户登录表前端显示
这里的数据显示使用了Easyui的datagrid功能
jsp页面:
<table id="loginuserid" class ="easyui-datagrid" >
</table>
js逻辑如下:
var editFlag = undefined;
$(function() {
// loginuserid
$('#loginuserid').datagrid(
{
border : false,
fitColumns : false,
singleSelect : true,
width : 600,
height : 450,
nowrap : false,
fit : true,
pagination : true,// 分页控件
pageSize : 4, // 每页记录数,需要和pageList保持倍数关系
pageList : [ 4, 8, 12 ],
rownumbers : true,// 行号
pagePosition : 'top',
url : 'dB/dB_getTableData.action',
queryParams: {
tableName: 'LoginUser' //,
// subject: 'datagrid'
},
idField:'id',
columns : [[
// {
// field : 'id',
// title : 'ID',
// width : '40'
// },
{
field : 'username',
title : '用户名',
width : '120',
editor: {//设置其为可编辑
type: 'validatebox',//设置编辑样式 自带样式有:text,textarea,checkbox,numberbox,validatebox,datebox,combobox,combotree 可自行扩展
options: {
required: true//设置编辑规则属性
}
}
},
{
field : 'password',
title : '用户密码',
width : '150',
editor: {//设置其为可编辑
type: 'validatebox',//设置编辑格式
options: {
required: true//设置编辑规则属性
}
}
},
{
field : 'description',
title : '备注',
width : '200',
editor: {//设置其为可编辑
type: 'validatebox',//设置编辑格式
options: {
}
}
}
] ],
toolbar: [{//在dategrid表单的头部添加按钮
text: "添加",
iconCls: "icon-add",
handler: function () {
if (editFlag != undefined) {
$("#loginuserid").datagrid('endEdit', editFlag);//结束编辑,传入之前编辑的行
}
if (editFlag == undefined) {//防止同时打开过多添加行
$("#loginuserid").datagrid('insertRow', {//在指定行添加数据,appendRow是在最后一行添加数据
index: 0, // 行数从0开始计算
row: {
username: '请输入用户名',
password: '请输入密码',
description: '用户描述'
}
});
$("#loginuserid").datagrid('beginEdit', 0);//开启编辑并传入要编辑的行
editFlag = 0;
}
}
}, '-', {//'-'就是在两个按钮的中间加一个竖线分割,看着舒服
text: "删除",
iconCls: "icon-remove",
handler: function () {
//选中要删除的行
var row = $("#loginuserid").datagrid('getSelected');
var rowIndex = $('#loginuserid').datagrid('getRowIndex', row);
console.info(row+","+rowIndex);
if (row.id) {//选中几行的话触发事件
deleteRow(row.id,rowIndex);
// $.messager.confirm("提示", "您确定要删除数据吗?", function (res) {//提示是否删除
// if (res) {
// deleteRow(row.id);
// }
// });
}
}
}, '-', {
text: "修改",
iconCls: "icon-edit",
handler: function () {
//选中一行进行编辑
var rows = $("#loginuserid").datagrid('getSelections');
if (rows.length == 1) {//选中一行的话触发事件
if (editFlag != undefined) {
$("#loginuserid").datagrid('endEdit', editFlag);//结束编辑,传入之前编辑的行
}
if (editFlag == undefined) {
var index = $("#loginuserid").datagrid('getRowIndex', rows[0]);//获取选定行的索引
$("#loginuserid").datagrid('beginEdit', index);//开启编辑并传入要编辑的行
editFlag = index;
}
}
}
}, '-', {
text: "保存",
iconCls: "icon-save",
handler: function () {
$("#loginuserid").datagrid('endEdit', editFlag);
}
}, '-', {
text: "撤销",
iconCls: "icon-redo",
handler: function () {
editFlag = undefined;
$("#loginuserid").datagrid('rejectChanges');
}
}, '-'],
onAfterEdit: function (rowIndex, rowData, changes) {//在添加完毕endEdit,保存时触发
console.info(rowData);//在火狐浏览器的控制台下可看到传递到后台的数据,这里我们就可以利用这些数据异步到后台添加,添加完成后,刷新datagrid
saveRow(rowIndex,rowData);
editFlag = undefined;//重置
}, onDblClickCell: function (rowIndex, field, value) {//双击该行修改内容
if (editFlag != undefined) {
$("#loginuserid").datagrid('endEdit', editFlag);//结束编辑,传入之前编辑的行
}
if (editFlag == undefined) {
$("#loginuserid").datagrid('beginEdit', rowIndex);//开启编辑并传入要编辑的行
editFlag = rowIndex;
}
}
});
//loginuserid
});
function deleteRow(index,rowIndex){
$.messager.confirm('Confirm','确认删除?',function(r){
if (r){
$.ajax({
url : 'dB/dB_deleteById.action',
data: {id:index,tableName:'LoginUser'},
type : 'GET',
timeout : 60000,
success : function(data, textStatus, jqXHR) {
var msg = '删除';
if(data == 'success') { //
console.info(index);
$.messager.alert('提示', msg + '成功!', 'info', function() {
$("#loginuserid").datagrid('deleteRow', rowIndex);
});
return;
} else {
$.messager.alert('提示', msg + '失败!', 'error', function() {
});
}
}
});
}
});
}
function saveRow(index,node){
// console.info("node.id:"+node.id+",node.username:"+node.username);
var json={id:node.id,username:node.username,password:node.password,description:node.description};
var encodeJson=JSON.stringify(json);
$.ajax({
url : 'dB/dB_updateOrSave.action',
type : 'POST',
data : {json:encodeJson,tableName:"LoginUser"},
timeout : 60000,
success : function(data, textStatus, jqXHR) {
var msg = '';
if (data == "success") {
console.info('保存成功!');
$.messager.alert('提示', '保存成功!', 'info', function() {
$("#loginuserid").datagrid('refreshRow', index);
$("#loginuserid").datagrid('reload');
});
} else{
msg = "保存失败!";
console.info(msg);
$.messager.alert('提示', msg , 'error', function() {
$("#loginuserid").datagrid('beginEdit', index);
});
}
}
});
}
2、后台逻辑
- 查询用户数据
对应的URL是url : ‘dB/dB_getTableData.action’
Action层
/**
* 根据tableName分页获取表数据
*/
public void getTableData(){
Map<String,Object> list = dBService.getTableData(tableName,rows, page);
String json =JSON.toJSONString(list);
log.info(json);
Utils.write2PrintWriter(json);
}
service层
/**
* 分页获取tableName 所有数据
*
* @param tableName:类实体名
* @param rows
* @param page
* @return
*/
public Map<String, Object> getTableData(String tableName, int rows, int page) {
String hql = "from " + tableName;
String hqlCount = "select count(1) from " + tableName;
List<Object> list = baseDao.find(hql, new Object[] {}, page, rows);
Map<String, Object> jsonMap = new HashMap<String, Object>();
jsonMap.put("total", baseDao.count(hqlCount));
jsonMap.put("rows", list);
return jsonMap;
}
- 添加或者修改数据
对应的URL是url : ‘dB/dB_updateOrSave.action
action层
/**
* 更新或者保存数据
*/
public void updateOrSave(){
boolean delSuccess =dBService.updateOrSave(tableName, json);
String msg="fail";
if(delSuccess){
msg="success";
}
log.info("保存表"+tableName+(delSuccess?"成功":"失败"+"!"));
Utils.write2PrintWriter(msg);
}
service层
/**
* 更新或者插入表 不用每个表都建立一个方法,这里根据表名自动装配
*
* @param tableName
* @param json
* @return
*/
public boolean updateOrSave(String tableName, String json) {
try {
// 根据表名获得全类名并创建相应的实体类,并赋值
Object o = Utils.getEntity(Utils.getEntityPackages(tableName), json);
baseDao.saveOrUpdate(o);
log.info("保存表{}!", new Object[] { tableName });
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
Utils中的getEntity和getEntityPackages方法如下:
/**
* 根据类名获得实体类
* @param tableName
* @param json
* @return
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws IOException
* @throws JsonMappingException
* @throws JsonParseException
*/
@SuppressWarnings("unchecked")
public static Object getEntity(String tableName, String json) throws ClassNotFoundException, InstantiationException, IllegalAccessException, JsonParseException, JsonMappingException, IOException {
Class<?> cl = Class.forName(tableName);//根据全类名创建对应的实体类对象
ObjectInterface o = (ObjectInterface)cl.newInstance();//利用了多态
Map<String,Object> map = new HashMap<String,Object>();
ObjectMapper mapper = new ObjectMapper();//转换json时需要的对象
try {
//convert JSON string to Map
map = mapper.readValue(json, Map.class);
return o.setObjectByMap(map);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获得表的实体类的全路径
* @param tableName
* @return
*/
public static String getEntityPackages(String tableName){
return "com.kang.model."+tableName;
}
- 删除数据
对应的URL是url : ‘dB/dB_deleteById.action’
action层
/**
* 按照id删除表中数据
*/
public void deleteById(){
boolean delSuccess =dBService.deleteById(tableName, id);
String msg="fail";
if(delSuccess){
msg="success";
}
log.info("删除表"+tableName+(delSuccess?"成功":"失败"+"!"));
Utils.write2PrintWriter(msg);
}
service层
public boolean deleteById(String tableName, String id) {
String hql = "delete " + tableName + " tb where tb.id='" + id + "'";
try {
Integer ret = baseDao.executeHql(hql);
log.info("删除表{},删除了{}条记录!", new Object[] { tableName, ret });
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
2、集群配置表的操作
集群配置表的相关操作和实现和用户登录表基本一致,这里不再详述。