基于SSM架构的CRM系统(二):项目改进&BaseMapper&BaseService&集成easyui

4 篇文章 0 订阅
4 篇文章 0 订阅

基于SSM架构的CRM系统(一):spring+springmvc+mybatis集成 : https://blog.csdn.net/qq_33526760/article/details/94441168

一.ssm搭建

1.1拷贝原来的ssme项目,改名为crm

并且在tomcat的server.xml里配置项目

    新建数据库crm及数据库表

    修改包名cn.xxx.ssme为cn.xxx.crm       

     jdbc.properties:数据库名     

     applicationContext.xml里扫描的包,配置文件.......

1.2写查询所有部门代码

代码流程: domain-->建数据库表-->*Mapper.java-->*Mapper.xml-->service的接口和实现-->junit测试service-->controller

1.2.1   domain:

User相关的全部删掉

package cn.xxx.crm.domain;

public class Department {
    private Long id;
    private String name;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Department() {}
    public Department(Long id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    @Override
    public String toString() {
        return "Department [id=" + id + ", name=" + name + "]";
    }
    
}
 

 

1.2.2   数据库表:

1.2.3   DepartmentMapper.java:

package cn.xxx.crm.mapper;

import java.util.List;

import cn.xxx.crm.domain.Department;

public interface DepartmentMapper {
    //查询所有部门
    List<Department> loadAll();
}

注意:为什么mapper里的查询方法用load,因为按照语义,load是加载,更倾向于持久层方法,业务层的方法一般用get,query,find,以后方法命名要注意,接口DepartmentMapper不用我们自己实现,所以前面没有加i

1.2.4   DepartmentMapper.xml:

<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.xxx.crm.mapper.DepartmentMapper">
    <select id="loadAll" resultType="cn.xxx.crm.domain.Department">
        select id,name from t_department
    </select>
</mapper>

1.2.5   service的接口和实现:

package cn.xxx.crm.service;

import java.util.List;

import cn.xxx.crm.domain.Department;

public interface IDepartmentService {
    //查询所有部门
    List<Department> getAll();
}

package cn.xxx.crm.service.impl;

import java.util.List;

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

import cn.xxx.crm.domain.Department;
import cn.xxx.crm.mapper.DepartmentMapper;
import cn.xxx.crm.service.IDepartmentService;
@Service
public class DepartmentServiceImpl implements IDepartmentService{
    @Autowired
    private DepartmentMapper departmentMapper;
    @Override
    public List<Department> getAll() {
        List<Department> list = departmentMapper.loadAll();
        return list;
    }

 }

1.2.6   junit测试service:

测试结果:

1.2.7   controller

启动项目,访问:

注意:由于每一个domain都对应一个service,那么,就要写多个测试类来对service进行测试,那么我们可以抽取一个公共的测试类,每个domain测测试类继承它就可以了,主要是抽取@RunWith和@ContextConfiguration:

 

1.3   项目改进

 

要改进成方案2,把他们的启动分开来管理,更加模块化

扫描包

    扫描Conroller

 扫描Mapper

扫描Service

注意:为什么分开启动之后,applicationContext.xml里直接扫描cn.xxx.crm,但是扫描不出controller,而要在applicationContext-mvc.xml里面扫描controller?因为第一种方式是通过dispatcherServlet启动的时候加载applicationContext.xml,所以能扫描controller,而优化成第二种方式之后,dispatcherServlet启动的时候只加载applicationContext-mvc.xml,所以并没有包的扫描,所以要加上

 

启动服务器,访问:

1.4    抽取BaseMapper&BaseService

base抽取架构图:

由于crm系统有很多domain,比如部门,员工,客户......,那么每个domain都要进行CRUD,那么就可以抽一个公共的接口

BaseMapper:

package cn.xxx.crm.mapper;

import java.io.Serializable;
import java.util.List;
/**
 * 基础的Mapper里实现了基本的CRUD,其他Mapper可以通过继承它就拥有crud
 * 为什么 id要用Serializable?因为有的domain的id是Long,有的domain的id又是Integer
 */
public interface BaseMapper<T> {
	//通过id加载一个对象
	T loadById(Serializable id);
	//加载所有对象
	List<T> loadAll();
	//插入一个对象
	void save(T t);
	//根据id删除对象
	void remove(Serializable id);
	//根据id修改对象
	void update(T t);
}

DepartmentMapper.java:

DepartmentMapper.xml:(这里面的id类型就不用Serializeble了)

<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.xxx.crm.mapper.DepartmentMapper">
	<!-- //通过id加载一个对象
	T (Serializable id); -->
	<select id="loadById" parameterType="long" resultType="cn.xxx.crm.domain.Department">
		select id,name from t_department where id=#{id}
	</select>
	<!-- //加载所有对象
	List<T> loadAll(); -->
	<select id="loadAll" resultType="cn.xxx.crm.domain.Department">
		select id,name from t_department
	</select>
	<!-- //插入一个对象
	void save(T t); -->
	<insert id="save" parameterType="cn.xxx.crm.domain.Department">
		insert into t_department(name) values(#{name})
	</insert>
	<!-- //根据id删除对象
	void remove(Serializable id); -->
	<delete id="remove" parameterType="long">
		delete from t_department where id=#{id}
	</delete>
	<!-- //根据id修改对象
	void update(T t); -->
	<update id="update" parameterType="cn.xxx.crm.domain.Department">
		update t_department set name = #{name} where id=#{id}
	</update>

</mapper>

(注意:①为什么mapper里的查询方法用load,因为按照语义,load是加载,更倾向于持久层方法,业务层的方法一般用get,query,find

          ②抽取的接口BaseMapper不用我们自己实现,所以前面没有加i

)

IBaseService:

package cn.xxx.crm.service;

import java.io.Serializable;
import java.util.List;

public interface IBaseService<T> {
	//通过id加载一个对象
	T getById(Serializable id);
	//加载所有对象
	List<T> getAll();
	//插入一个对象
	void add(T t);
	//根据id删除对象
	void delete(Serializable id);
	//根据id修改对象
	void update(T t);
}

 

BaseServiceImpl:

package cn.xxx.crm.service.impl;

import java.io.Serializable;
import java.util.List;

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

import cn.xxx.crm.mapper.BaseMapper;
import cn.xxx.crm.service.IBaseService;
public class BaseServiceImpl<T> implements IBaseService<T> {
	/*虽然注入的是BaseMapper,但是DepartmentServiceImpl继承BaseServiceImpl,IDepartmentService继承IBaseService之后,
	 * 注入的是DepartmentMapper
	 */
	@Autowired
	private BaseMapper<T> baseMapper;
	@Override
	public T getById(Serializable id) {
		T t = baseMapper.loadById(id);
		return t;
	}

	@Override
	public List<T> getAll() {
		List<T> all = baseMapper.loadAll();
		return all;
	}

	@Override
	public void add(T t) {
		baseMapper.save(t);
	}

	@Override
	public void delete(Serializable id) {
		baseMapper.remove(id);
	}

	@Override
	public void update(T t) {
		baseMapper.update(t);
	}

}

 

DepartmentServiceImpl

package cn.xxx.crm.service;

import cn.xxx.crm.domain.Department;

public interface IDepartmentService extends IBaseService<Department>{
	
}

 

DepartmentServiceImpl

package cn.xxx.crm.service.impl;

import org.springframework.stereotype.Service;

import cn.xxx.crm.domain.Department;
import cn.xxx.crm.service.IDepartmentService;
@Service
public class DepartmentServiceImpl extends BaseServiceImpl<Department> implements IDepartmentService{
	

}

 

生成测试类测试(查看前面生成方法):

package cn.xxx.crm.service;

import static org.junit.Assert.*;

import java.util.List;

import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import cn.xxx.crm.domain.Department;

public class IDepartmentServiceTest extends BaseServiceTest{
	@Autowired
	private IDepartmentService departmentService;
	@Test
	public void testGetById() {
		Department department = departmentService.getById(2L);
		System.out.println(department);
	}

	@Test
	public void testGetAll() {
		List<Department> all = departmentService.getAll();
		for (Department department : all) {
			System.out.println(department);
		}
	}

	@Test
	public void testAdd() {
		for (int i = 0; i < 20; i++) {
			departmentService.add(new Department("test"+i));
		}
//		departmentService.add(new Department("test"+100));
	}

	@Test
	public void testDelete() {
		Department department = departmentService.getById(3L);
		System.out.println(department);
		departmentService.delete(3L);
		department = departmentService.getById(3L);
		System.out.println(department);
	}

	@Test
	public void testUpdate() {
		Department department = departmentService.getById(4L);
		System.out.println(department);
		
		
		department.setName(department.getName()+"->你被修改了!");
		departmentService.update(department);
		
		department = departmentService.getById(4L);
		System.out.println(department);
	}

}

1.5    事务处理

Spirng事务处理有两种方式:

          声明式事务(XML)

          注解式事务(注解)

spring的事务管理器是DataSourceTransactionManager

applicationContext.xml写tx标签的时候,alt+/没有提示,那么要配置约束:

配置了之后需要有网络,如果没有网络,那么要手动引入:

选择

Key就是我们复制的内容粘贴进去

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
	     http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
	     http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
	     http://www.springframework.org/schema/mvc
         http://www.springframework.org/schema/mvc/spring-mvc.xsd
	     http://www.springframework.org/schema/tx
         http://www.springframework.org/schema/tx/spring-tx.xsd
        ">
	<!-- 使用注解要进行扫描 -->
	<context:component-scan base-package="cn.xxx.crm" />

	<context:property-placeholder location="classpath:jdbc.properties" />
	<!-- jdbc.properties->dataSource->sqlSessionFactory->mapper(dao)->service->controller(action) -->
	<!-- 数据源dataSource -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<!-- 依赖注入连接池需要的属性 -->
		<!-- property name="是BasicDataSource的set方法,本质属性" -->
		<!-- property value="是jdbc.properties配置文件的key" -->
		<property name="driverClassName" value="${jdbc.driverClassName}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<!--maxActive: 最大连接数量 -->
		<property name="maxActive" value="150" />
		<!--minIdle: 最小空闲连接 -->
		<property name="minIdle" value="5" />
		<!--maxIdle: 最大空闲连接 -->
		<property name="maxIdle" value="20" />
		<!--initialSize: 初始化连接 -->
		<property name="initialSize" value="30" />
		<!-- 连接被泄露时是否打印 -->
		<property name="logAbandoned" value="true" />
		<!--removeAbandoned: 是否自动回收超时连接 -->
		<property name="removeAbandoned" value="true" />
		<!--removeAbandonedTimeout: 超时时间(以秒数为单位) -->
		<property name="removeAbandonedTimeout" value="10" />
		<!--maxWait: 超时等待时间以毫秒为单位 1000等于60秒 -->
		<property name="maxWait" value="1000" />
		<!-- 在空闲连接回收器线程运行期间休眠的时间值,以毫秒为单位. -->
		<property name="timeBetweenEvictionRunsMillis" value="10000" />
		<!-- 在每次空闲连接回收器线程(如果有)运行时检查的连接数量 -->
		<property name="numTestsPerEvictionRun" value="10" />
		<!-- 1000 * 60 * 30 连接在池中保持空闲而不被空闲连接回收器线程 -->
		<property name="minEvictableIdleTimeMillis" value="10000" />
		<property name="validationQuery" value="SELECT NOW() FROM DUAL" />
	</bean>
	<
	<!-- SSJ集成时候需要entityManagerFactory SSM集成时候需要sqlSessionFactory 集成jpa的时候需要一个EntityManagerFactory对象 
		-> 需要一个FactoryBean来完成功能 需要用到SqlSessionFactoryBean -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<!-- 引用datasource -->
		<property name="dataSource" ref="dataSource" />
		<!-- 读取核心配置文件 -->
		<property name="mapperLocations" value="classpath:cn/xxx/crm/mapper/*Mapper.xml" />
		<!-- 配置别名 -->
		<!-- 配置mybatis 类型别名 -->
		<!-- <property name="typeAliasesPackage"> -->
		<!-- <value> -->
		<!-- cn.itsource.ssm.domain -->
		<!-- cn.itsource.ssm.query -->
		<!-- </value> -->
		<!-- </property> -->
	</bean>

	<!-- MapperFactoryBean:对应到我们的Mapper -->
	<!-- 引用sqlSessoinFactory -->
	<!-- 指向对应的接口 -->
	<!-- 一劳永逸(不要有id) -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="cn.xxx.crm.mapper" />
	</bean>
	<!-- 事务处理:
	1.配置一个事务管理器
	2.开启注解事务支持
	3.类里面加注解 -->
	<!-- 1.配置一个事务管理器 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	<!-- 2.开启注解事务支持 -->
	<tx:annotation-driven/>
	
	<!-- 引入 mvc的配置 -->
<!-- 	<import resource="classpath:plugins/applicationContext-mvc.xml" /> -->

</beans> 

事务处理第三步:    类里面加注解

package cn.xxx.crm.service.impl;

import java.io.Serializable;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import cn.xxx.crm.mapper.BaseMapper;
import cn.xxx.crm.service.IBaseService;
//由于查询比较多,所以在类上配置默认的查询事务,对应里面的增删改,单独配置写事务
@Transactional(propagation=Propagation.SUPPORTS,readOnly=true)
public class BaseServiceImpl<T> implements IBaseService<T> {
	/*虽然注入的是BaseMapper,但是DepartmentServiceImpl继承BaseServiceImpl,IDepartmentService继承IBaseService之后,
	 * 注入的是DepartmentMapper
	 */
	@Autowired
	private BaseMapper<T> baseMapper;
	@Override
	public T getById(Serializable id) {
		T t = baseMapper.loadById(id);
		return t;
	}

	@Override
	public List<T> getAll() {
		List<T> all = baseMapper.loadAll();
		return all;
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED,readOnly=false)
	public void add(T t) {
		baseMapper.save(t);
	}

	@Override
	@Transactional//和上面@Transactional(propagation=Propagation.REQUIRED,readOnly=false)是一样,因为propagation=Propagation.REQUIRED,readOnly=false都是默认值
	public void delete(Serializable id) {
		baseMapper.remove(id);
	}

	@Override
	@Transactional
	public void update(T t) {
		baseMapper.update(t);
	}

}

SUPPORTS:有事务就用,没有就算求.   readOnly=true:只读事务,用于查询

REQUIRED:必须要有事务.

@Transactional默认就是@Transactional(propagation=Propagation.REQUIRED,readOnly=false)

@Transactional等价于@Transactional(propagation=Propagation.REQUIRED,readOnly=false)

测试事务:

二. 集成easyui

解压,改名去掉版本号(因为版本以后可能升级)

 

 

2.1目录规划

把easyui放到新建路径webapp/resources/js下面,因为easyui里面包含了jquery.min.js,jquery也是前端框架,为了区分我们把jquery.min.js拖出来放到webapp/resources/js下面

2.2抽取公共的common.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- easyui的主题样式 -->
<!-- <link rel="stylesheet" type="text/css" href="easyui/themes/default/easyui.css">    -->
<!-- 变相对为绝对路径 -->
<!-- <link rel="stylesheet" type="text/css" href="/resources/js/easyui/themes/default/easyui.css">    -->
<!-- 路径应该加上APPPATH -->
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/resources/js/easyui/themes/default/easyui.css">   
<!-- easyui的主题图标 -->
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/resources/js/easyui/themes/icon.css">   
<!-- easyui的主题颜色-->
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/resources/js/easyui/themes/color.css">   
<!-- easyui的依赖的jQuery-->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/jquery.min.js"></script>   
<!-- easyui的所有插件 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/easyui/jquery.easyui.min.js"></script>  
<!-- easyui的国际化 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/easyui/locale/easyui-lang-zh_CN.js"></script>  

Common.jsp里面引入了easyUI,我们的界面直接导入Common.jsp就相当于引入easyUI:

注意,common.jsp里面的路径一定要根据项目写,路径不对会找不到,如下图:

三.CRUD

页面:

直接从easyui的demo里面copy页面代码:

接下来修改页面代码:

步骤:刷新功能-->删除功能-->保存和编辑功能

注意:1.copy的代码,按钮都是a标签,里面用onClick()绑定的事件,太low了,要把事件去掉,在js里面绑定

         2.前端进行表单提交的时候,接口方法打上@Responsebody返回的不是json对象,而是json字符串,要使用json对象要进行转换,ajax请求的时候,才是返回的json对象,直接使用,如下代码中注释有说明  list.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<%@include file="/WEB-INF/views/common.jsp"%>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>部门管理</title>
</head>
<body>
	<!-- 管理表格 -->
	<table id="deptDatagrid" title="部门管理" class="easyui-datagrid"
		style="width: 700px; height: 250px" url="/department/list"
		toolbar="#deptToolbar" pagination="true" rownumbers="true" fit="true"
		fitColumns="true" singleSelect="true">
		<thead>
			<tr>
				<th field="name" width="50">部门名称</th>
			</tr>
		</thead>
	</table>
	<!-- 管理表格toolbar -->
	<div id="deptToolbar">
		<a id='saveDeptBtn' class="easyui-linkbutton c1" iconCls="icon-add"
			plain="true">新增</a> <a id='editDeptBtn' class="easyui-linkbutton c3"
			iconCls="icon-edit" plain="true">编辑</a> <a id='deleteDeptBtn'
			class="easyui-linkbutton c5" iconCls="icon-remove" plain="true">删除</a>
		<a id='reloadDeptBtn' class="easyui-linkbutton c7"
			iconCls="icon-remove" plain="true">刷新</a>
	</div>
	<!-- 添加和修改对话框 -->
	<div id=saveOrUpdateDeptDlg class="easyui-dialog" style="width: 400px"
		data-options="closed:true,modal:true,border:'thin',buttons:'#dlg-buttons'">
		<form id="fm" method="post" novalidate
			style="margin: 0; padding: 20px 50px">
			<div style="margin-bottom: 10px">
				<input name="id" type="hidden" /> <input name="name"
					class="easyui-textbox" required="true" label="部门名称:"
					style="width: 100%" />
			</div>
		</form>
	</div>
	<!-- 添加和修改对话框按钮 -->
	<div id="dlg-buttons">
		<a id="confirmSaveOrUpdateBtn" class="easyui-linkbutton c6"
			iconCls="icon-ok" style="width: 90px">保存</a> <a
			id="cancelSaveOrUpdateBtn" class="easyui-linkbutton c8"
			iconCls="icon-cancel" style="width: 90px">取消</a>
	</div>
	<script type="text/javascript">
		var url;
		$('#saveDeptBtn').click(function(){
			//清空模态框里字段的内容
			$('#fm').form('clear');
			//打开
			$('#saveOrUpdateDeptDlg').dialog('open').dialog('center').dialog('setTitle','新增');
// 			url = 'save_user.php';?
		});
		$('#editDeptBtn').click(function(){
			//清空模态框里字段的内容
			$('#fm').form('clear');
			//对编辑的数据进行回显
			var row = $('#deptDatagrid').datagrid('getSelected');
			if (row){
				$('#saveOrUpdateDeptDlg').dialog('open').dialog('center').dialog('setTitle','编辑');
				$('#fm').form('load',row);
// 				url = 'update_user.php?id='+row.id;
			}else{
				$.messager.alert('提示','请选择一条数据!','info');
			}
		});
		$('#deleteDeptBtn').click(function(){
			var row = $('#deptDatagrid').datagrid('getSelected');
// 			console.log(row);
			if (row){
				$.messager.confirm('Confirm','确定要删除这条记录吗?',function(r){
					if (r){
						$.post('/department/delete',{id:row.id},function(result){
							if (result.success){
								$.messager.alert('提示',result.message,'info');
								$('#deptDatagrid').datagrid('reload');	// reload the user data
							} else {
								$.messager.alert('错误',result.message,'error');
								$('#deptDatagrid').datagrid('reload');
							}
						},'json');
					}
				});
			}else{
				$.messager.alert('提示','请选择一条数据!','info');
			}
		});
		$('#reloadDeptBtn').click(function(){
			$('#deptDatagrid').datagrid('reload');
		});
		$('#confirmSaveOrUpdateBtn').click(function(){
			
			$('#fm').form('submit',{
				url : '/department/save',
				success : function(data){
					//应该返回一个AjaxResult转换的结果
			    	//由于这儿是做表单提交,不是通过JQuery发送的Ajax请求,返回的是Json字符串需要转换为Json对象
			    	// 1 eval 2 $.parseJSON 3....
					data = $.parseJSON(data);
					if(data.success){
						$.messager.alert('提示',data.message,'info');
						$('#deptDatagrid').datagrid('reload');
						
					}else{
						$.messager.alert('错误',data.message,'error');
						$('#deptDatagrid').datagrid('reload');
					}
				}
			});
			$('#saveOrUpdateDeptDlg').dialog('close');
		});
		$('#cancelSaveOrUpdateBtn').click(function(){
			$('#saveOrUpdateDeptDlg').dialog('close');
		});
		
	</script>
</body>
</html>

controller:

package cn.xxx.crm.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.xxx.crm.domain.Department;
import cn.xxx.crm.service.IDepartmentService;
import cn.xxx.crm.util.AjaxResult;

@Controller
@RequestMapping("/department")
public class DepartmentController {
	@Autowired
	private IDepartmentService departmentService;
	@RequestMapping("/index")
	public String index(){
		return "department/list";
	}
	@RequestMapping("/list")
	@ResponseBody
	public List<Department> list(){
		List<Department> list = departmentService.getAll();
		return list;
	}
	@RequestMapping("/delete")
	@ResponseBody
	public AjaxResult delete(Long id){
		try {
			departmentService.delete(id);
//			int i=1/0;事务处理有问题,发生异常没有把删除操作进行回滚
			return new AjaxResult();//成功就直接返回无参构造函数new的对象,不用设置参数,失败就通过有参构造函数构造对象,这种思想很重要
		} catch (Exception e) {
			e.printStackTrace();
			//成功就直接返回无参构造函数new的对象,不用设置参数,失败就通过有参构造函数构造对象,这种思想很重要,并且把异常返回给前端
			return new AjaxResult(false,"删除失败 : "+e.getMessage());
		}
	}
	@RequestMapping("/save")
	@ResponseBody
	public AjaxResult save(Department department){
		try {
			Long id = department.getId();
			if(id == null){
				departmentService.add(department);
			}else{
				departmentService.update(department);
			}
			return new AjaxResult();
		} catch (Exception e) {
			e.printStackTrace();
			return new AjaxResult(false,"保存失败 : "+e.getMessage());
		}
	}
}
package cn.xxx.crm.util;

public class AjaxResult {
	private Boolean success=true;
	private String message="操作成功!";
	public Boolean getSuccess() {
		return success;
	}
	public void setSuccess(Boolean success) {
		this.success = success;
	}
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
	public AjaxResult() {}
	public AjaxResult(Boolean success, String message) {
		super();
		this.success = success;
		this.message = message;
	}
	
}

注意:AjaxResult    成功就直接返回无参构造函数new的对象,不用设置参数,失败就通过有参构造函数构造对象,这种思想很重要!!

额外知识点:
(

返回json:

Struts2方案 response.getWriter().write("{\"success\":false,\"msg\":\""+e.getMessage()+"\"}");

SpringMVC方案 写一个类来描述这个json,导入只需把这个类的一个对象返回回去,加上@ResponseBody,由框架自动转换。

)

代码下载:https://download.csdn.net/download/qq_33526760/11348484

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值