CRM客户关系管理系统开发第四讲——实现客户管理模块中保存客户的功能

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/yerenyuan_pku/article/details/101704361

准备工作

在正式编写代码实现客户管理模块中保存客户的功能之前,我们得做一些准备工作,因为这个功能实现起来还是比较难的,不能一蹴而就。

创建客户表

在crm数据库下新建一张客户表,其建表的sql语句如下:

CREATE TABLE `cst_customer` (
	`cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
	`cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)',
	`cust_source` varchar(32) DEFAULT NULL COMMENT '客户信息来源',
	`cust_industry` varchar(32) DEFAULT NULL COMMENT '客户所属行业',
	`cust_level` varchar(32) DEFAULT NULL COMMENT '客户级别',
	`cust_phone` varchar(64) DEFAULT NULL COMMENT '固定电话',
	`cust_mobile` varchar(16) DEFAULT NULL COMMENT '移动电话',
	PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

创建Customer实体类及其对应的映射配置文件

在com.meimeixia.crm.domain包下创建一个Customer实体类及其相对应的映射配置文件。

  • Customer实体类

    package com.meimeixia.crm.domain;
    
    public class Customer {
    	
    	private Long cust_id;
    	private String cust_name;
    	private String cust_source;
    	private String cust_industry;
    	private String cust_level;
    	private String cust_phone;
    	private String cust_mobile;
    	
    	public Long getCust_id() {
    		return cust_id;
    	}
    	public void setCust_id(Long cust_id) {
    		this.cust_id = cust_id;
    	}
    	public String getCust_name() {
    		return cust_name;
    	}
    	public void setCust_name(String cust_name) {
    		this.cust_name = cust_name;
    	}
    	public String getCust_source() {
    		return cust_source;
    	}
    	public void setCust_source(String cust_source) {
    		this.cust_source = cust_source;
    	}
    	public String getCust_industry() {
    		return cust_industry;
    	}
    	public void setCust_industry(String cust_industry) {
    		this.cust_industry = cust_industry;
    	}
    	public String getCust_level() {
    		return cust_level;
    	}
    	public void setCust_level(String cust_level) {
    		this.cust_level = cust_level;
    	}
    	public String getCust_phone() {
    		return cust_phone;
    	}
    	public void setCust_phone(String cust_phone) {
    		this.cust_phone = cust_phone;
    	}
    	public String getCust_mobile() {
    		return cust_mobile;
    	}
    	public void setCust_mobile(String cust_mobile) {
    		this.cust_mobile = cust_mobile;
    	}
    	
    }
    
  • Customer.hbm.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
        
    <hibernate-mapping>
    	<!-- 建立类与表的映射 -->
    	<class name="com.meimeixia.crm.domain.Customer" table="cst_customer">
    		<!-- 建立类中的属性与表中的主键相对应 -->
    		<id name="cust_id" column="cust_id">
    			<!-- 主键的生成策略,现在使用的是本地生成策略 -->
    			<generator class="native" />
    		</id>
    		
    		<!-- 建立类中的普通属性和表中的字段相对应 -->
    		<property name="cust_name" column="cust_name" />
    		<property name="cust_source" column="cust_source" />
    		<property name="cust_industry" column="cust_industry" />
    		<property name="cust_level" column="cust_level" />
    		<property name="cust_phone" column="cust_phone" />
    		<property name="cust_mobile" column="cust_mobile" />
    		
    	</class>
    </hibernate-mapping>
    

创建相关的类(接口)

首先创建web层相关的类,即在com.meimeixia.crm.web.action包下创建一个CustomerAction类,但仅在其中注入service。

package com.meimeixia.crm.web.action;

import com.meimeixia.crm.domain.Customer;
import com.meimeixia.crm.service.CustomerService;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

/**
 * 客户管理的Action类
 * @author liayun
 *
 */
public class CustomerAction extends ActionSupport implements ModelDriven<Customer> {

	//模型驱动使用的对象
	private Customer customer = new Customer();
	
	@Override
	public Customer getModel() {
		return customer;
	}
	
	//注入service
	private CustomerService customerService;

	public void setCustomerService(CustomerService customerService) {
		this.customerService = customerService;
	}	

}

然后,创建service层相关的类。

  • 先在com.meimeixia.crm.service包下创建一个UserService接口,一开始该接口中并没有声明任何方法,如下:

    package com.meimeixia.crm.service;
    
    /**
     * 客户管理类的业务层的接口
     * @author liayun
     *
     */
    public interface CustomerService {
    
    }
    
  • 再在com.meimeixia.crm.service.impl包下编写以上接口的一个实现类——CustomerSeviceImpl.java,但仅在其中注入dao。

    package com.meimeixia.crm.service.impl;
    
    import com.meimeixia.crm.dao.CustomerDao;
    import com.meimeixia.crm.service.CustomerService;
    
    /**
     * 客户管理的业务层的实现类
     * @author liayun
     *
     */
    public class CustomerServiceImpl implements CustomerService {
    	
    	//注入客户的dao
    	private CustomerDao customerDao;
    
    	public void setCustomerDao(CustomerDao customerDao) {
    		this.customerDao = customerDao;
    	}
    	
    }
    

接着,创建dao层相关的类。

  • 先在com.meimeixia.crm.dao包下创建一个UserDao接口,一开始该接口中并没有声明任何方法,如下:

    package com.meimeixia.crm.dao;
    
    /**
     * 客户管理的dao的接口
     * @author liayun
     *
     */
    public interface CustomerDao {
    
    }
    
  • 再在com.meimeixia.crm.dao.impl包下编写以上接口的一个实现类——UserDaoImpl.java。

    package com.meimeixia.crm.dao.impl;
    
    import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
    
    import com.meimeixia.crm.dao.CustomerDao;
    
    /**
     * 客户管理的dao的实现类
     * @author liayun
     *
     */
    public class CustomerDaoImpl extends HibernateDaoSupport implements CustomerDao {
    
    }
    

最后,我们不要忘了在Spring配置文件中对以上类进行配置,即将这些相关的类交给Spring来管理。
在这里插入图片描述

跳转到客户添加页面

以上准备工作做好之后,发布我们的项目到Tomcat服务器并启动,然后访问该项目的首页,点击新增客户超链接之后要能跳转到客户添加页面。
在这里插入图片描述
如何才能点击新增客户超链接之后跳转到我们想要的客户添加页面呢?

在左侧的菜单页面(menu.jsp)中修改提交路径

在这里插入图片描述

编写CustomerAction中的saveUI方法

在CustomerAction类中编写一个如下的saveUI方法。

package com.meimeixia.crm.web.action;

import com.meimeixia.crm.domain.Customer;
import com.meimeixia.crm.service.CustomerService;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

/**
 * 客户管理的Action类
 * @author liayun
 *
 */
public class CustomerAction extends ActionSupport implements ModelDriven<Customer> {

	//模型驱动使用的对象
	private Customer customer = new Customer();
	
	@Override
	public Customer getModel() {
		return customer;
	}
	
	//注入service
	private CustomerService customerService;

	public void setCustomerService(CustomerService customerService) {
		this.customerService = customerService;
	}
	
	/*
	 * 客户管理模块当中的跳转到添加页面的saveUI方法
	 */
	public String saveUI() {
		return "saveUI";
	}
	
}

配置页面跳转

我们还得在Struts2配置文件中(即struts.xml)对CustomerAction进行如下的配置,即配置页面的跳转。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
	<!-- 配置Strust2的一些常量 -->
	<constant name="struts.action.extension" value="action" />
	
	<package name="crm" extends="struts-default" namespace="/">
		<action name="user_*" class="userAction" method="{1}">
			<result name="login">/login.jsp</result>
			<result name="success" type="redirect">/index.jsp</result>
		</action>
		
		<!-- 配置客户管理的Action -->
		<action name="customer_*" class="customerAction" method="{1}">
			<result name="saveUI">/jsp/customer/add.jsp</result>
		</action>
	</package>
	
</struts>

此时,发布我们的项目到Tomcat服务器并启动,然后访问该项目的首页,点击新增客户超链接之后就能跳转到客户添加页面了。
在这里插入图片描述

引入数据字典

跳转到客户添加页面之后,我们就要在其中添加客户相关的信息了,像客户信息来源、客户所属行业以及客户级别等肯定是不能随便填写的,要不然这成何体统啊!思来想去,它们应该是会提供一个下拉列表,让我们在其中进行选择,这就规范很多了,不是吗?在实际的开发中像这种数据的内容都是从某几个固定的值中获取的,那么可以将这类的数据统一存入到数据字典表中,每次获取的时候都从数据字典表中进行获取即可。这就引出了数据字典表了。

什么是数据字典表?

数据字典表就是用来规范我们某些地方的一些具体的值和数据的,也就是说数据字典表主要用于规范某些数据的来源。

创建数据字典表

在crm数据库下新建一张数据字典表,其建表的sql语句如下:

CREATE TABLE `base_dict` (
	`dict_id` varchar(32) NOT NULL COMMENT '数据字典id(主键)',
	`dict_type_code` varchar(10) NOT NULL COMMENT '数据字典类别代码',
	`dict_type_name` varchar(64) NOT NULL COMMENT '数据字典类别名称',
	`dict_item_name` varchar(64) NOT NULL COMMENT '数据字典项目名称',
	`dict_item_code` varchar(10) DEFAULT NULL COMMENT '数据字典项目编号(可为空)',
	`dict_sort` int(10) DEFAULT NULL COMMENT '排序字段',
	`dict_enable` char(1) NOT NULL COMMENT '1:使用 0:停用',
	`dict_memo` varchar(64) DEFAULT NULL COMMENT '备注',
	PRIMARY KEY (`dict_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

我们可以在数据字典表插入一些假数据,以便用于测试。这些假数据可以在《CRM客户关系管理系统开发第一讲——搭建开发环境》这一讲中我提供的百度网盘资料中找到。

分析客户表和数据字典表它俩之间的关系

客户表和数据字典表它俩之间到底是什么关系呢?相信大家初次猛然看到这个问题,还真有点丈二的和尚摸不着头脑,包括我本人也是。为了分析清楚它俩之间的关系,我画了下面一个图。
在这里插入图片描述
从上图中我们可以知道,数据字典表和客户表它俩之间的关系是一对多的关系,而且数据字典表是代表一的一方,客户表是代表多的一方。
在这里插入图片描述
正是由于数据字典表和客户表它俩之间是一对多的关系,所以应该在客户表这一端创建外键,而且还要创建三个外键,因为数据字典表和客户表它俩之间需要创建三个一对多的关系,对应所谓的客户信息来源、客户级别以及客户所属行业。
在这里插入图片描述

在客户添加页面上异步加载数据字典表中的数据

跳转到客户添加页面之后,我们就要在其中添加客户相关的信息了,但像客户信息来源、客户所属行业以及客户级别等下拉列表中的数据从何而来呢?传统的方式是在CustomerAction类中的saveUI方法里面编写代码,从数据字典表中查询到那些需要的数据,然后在客户添加页面上用下拉列表给展示出来,注意这时同步查询。
在这里插入图片描述
除了这种办法之外,还有没有其他办法呢?其实还有一种办法,我们可以异步去查询数据字典表中的数据,就是在客户添加页面跳转过来以后(即现在需要加载add.jsp这个页面),在加载这个页面时,就异步去查询数据字典表中的数据,然后给它加载到客户信息来源、客户所属行业以及客户级别等下拉列表上。但在这里,我们采用异步查询这种方式,前一种方式后面我也会讲到。

创建数据字典实体类及其对应的映射配置文件

在com.meimeixia.crm.domain包下创建一个数据字典实体类及其相对应的映射配置文件。

  • 数据字典实体类

    package com.meimeixia.crm.domain;
    
    /**
     * 数据字典的实体
     * @author liayun
     *
     */
    public class BaseDict {
    	
    	private String dict_id;
    	private String dict_type_code;	//数据字典类别代码
    	private String dict_type_name;	//数据字典类别名称
    	private String dict_item_name;	//数据字典项目名称
    	private String dict_item_code;  //数据字典项目代码
    	private Integer dict_sort;
    	private String dict_enable;
    	private String dict_memo;
    	
    	public String getDict_id() {
    		return dict_id;
    	}
    	public void setDict_id(String dict_id) {
    		this.dict_id = dict_id;
    	}
    	public String getDict_type_code() {
    		return dict_type_code;
    	}
    	public void setDict_type_code(String dict_type_code) {
    		this.dict_type_code = dict_type_code;
    	}
    	public String getDict_type_name() {
    		return dict_type_name;
    	}
    	public void setDict_type_name(String dict_type_name) {
    		this.dict_type_name = dict_type_name;
    	}
    	public String getDict_item_name() {
    		return dict_item_name;
    	}
    	public void setDict_item_name(String dict_item_name) {
    		this.dict_item_name = dict_item_name;
    	}
    	public String getDict_item_code() {
    		return dict_item_code;
    	}
    	public void setDict_item_code(String dict_item_code) {
    		this.dict_item_code = dict_item_code;
    	}
    	public Integer getDict_sort() {
    		return dict_sort;
    	}
    	public void setDict_sort(Integer dict_sort) {
    		this.dict_sort = dict_sort;
    	}
    	public String getDict_enable() {
    		return dict_enable;
    	}
    	public void setDict_enable(String dict_enable) {
    		this.dict_enable = dict_enable;
    	}
    	public String getDict_memo() {
    		return dict_memo;
    	}
    	public void setDict_memo(String dict_memo) {
    		this.dict_memo = dict_memo;
    	}
    	
    }
    

    前面我讲过数据字典表和客户表它俩之间的关系是一对多的关系,那么在创建数据字典实体类时,要不要在这一端写上多的一方的集合呢?不需要,因为我们在查询数据字典表中的数据时,并不需要去查询客户表中的数据。

  • 与数据字典实体类相对应的映射配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
        
    <hibernate-mapping>
    	<!-- 建立类与表的映射 -->
    	<class name="com.meimeixia.crm.domain.BaseDict" table="base_dict">
    		<!-- 建立类中的属性与表中的主键相对应 -->
    		<id name="dict_id" column="dict_id">
    			<!-- 主键的生成策略 -->
    			<generator class="uuid" />
    		</id>
    		
    		<!-- 建立类中的普通属性和表中的字段相对应 -->
    		<property name="dict_type_code" column="dict_type_code" />
    		<property name="dict_type_name" column="dict_type_name" />
    		<property name="dict_item_name" column="dict_item_name" />
    		<property name="dict_item_code" column="dict_item_code" />
    		<property name="dict_sort" column="dict_sort" />
    		<property name="dict_enable" column="dict_enable" />
    		<property name="dict_memo" column="dict_memo" />
    		
    	</class>
    </hibernate-mapping>
    

    因为我们在查询数据字典表中的数据时,并不需要去查询客户表中的数据。所以,我们在创建数据字典实体类相对应的映射配置文件时,可以不用配置与客户相关的内容。

修改数据字典和客户之间的关系映射

创建完数据字典实体类及其对应的映射配置文件之后,我们就要配置数据字典和客户之间的关系映射了。首先,修改了客户实体类,因为客户表和数据字典表它俩之间是属于多对一的关系,所以我们需要在多的一方放置一的一方的对象。

package com.meimeixia.crm.domain;

public class Customer {
	
	private Long cust_id;
	private String cust_name;
	/*private String cust_source;
	private String cust_industry;
	private String cust_level;*/
	private String cust_phone;
	private String cust_mobile;
	/*
	 * 因为我们的客户表和数据字典表是属于多对一的关系,所以需要在多的一方放置一的一方的对象
	 */
	private BaseDict baseDictSource;
	private BaseDict baseDictIndustry;
	private BaseDict baseDictLevel;
	public Long getCust_id() {
		return cust_id;
	}
	public void setCust_id(Long cust_id) {
		this.cust_id = cust_id;
	}
	public String getCust_name() {
		return cust_name;
	}
	public void setCust_name(String cust_name) {
		this.cust_name = cust_name;
	}
	public String getCust_phone() {
		return cust_phone;
	}
	public void setCust_phone(String cust_phone) {
		this.cust_phone = cust_phone;
	}
	public String getCust_mobile() {
		return cust_mobile;
	}
	public void setCust_mobile(String cust_mobile) {
		this.cust_mobile = cust_mobile;
	}
	public BaseDict getBaseDictSource() {
		return baseDictSource;
	}
	public void setBaseDictSource(BaseDict baseDictSource) {
		this.baseDictSource = baseDictSource;
	}
	public BaseDict getBaseDictIndustry() {
		return baseDictIndustry;
	}
	public void setBaseDictIndustry(BaseDict baseDictIndustry) {
		this.baseDictIndustry = baseDictIndustry;
	}
	public BaseDict getBaseDictLevel() {
		return baseDictLevel;
	}
	public void setBaseDictLevel(BaseDict baseDictLevel) {
		this.baseDictLevel = baseDictLevel;
	}
	
}

然后,修改与客户实体类相对应的映射配置文件。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping>
	<!-- 建立类与表的映射 -->
	<class name="com.meimeixia.crm.domain.Customer" table="cst_customer">
		<!-- 建立类中的属性与表中的主键相对应 -->
		<id name="cust_id" column="cust_id">
			<!-- 主键的生成策略,现在使用的是本地生成策略 -->
			<generator class="native" />
		</id>
		
		<!-- 建立类中的普通属性和表中的字段相对应 -->
		<property name="cust_name" column="cust_name" />
		<!-- <property name="cust_source" column="cust_source" />
		<property name="cust_industry" column="cust_industry" />
		<property name="cust_level" column="cust_level" /> -->
		<property name="cust_phone" column="cust_phone" />
		<property name="cust_mobile" column="cust_mobile" />
		
		<!-- 配置客户与数据字典它哥俩之间的多对一的关系映射 -->
		<many-to-one name="baseDictSource" class="com.meimeixia.crm.domain.BaseDict" column="cust_source"></many-to-one>
		<many-to-one name="baseDictIndustry" class="com.meimeixia.crm.domain.BaseDict" column="cust_industry"></many-to-one>
		<many-to-one name="baseDictLevel" class="com.meimeixia.crm.domain.BaseDict" column="cust_level"></many-to-one>
		
	</class>
</hibernate-mapping>

最后,千万记得要把客户实体类和数据字典实体类它俩相对应的映射配置文件都交给Spring来管理哟!
在这里插入图片描述

在客户添加页面上编写异步加载的方法(以异步加载客户信息来源为例)

首先,在客户添加页面中的客户信息来源那一项上添加一个下拉列表。
在这里插入图片描述
然后,在客户添加页面上引入jQuery的JS库文件。
在这里插入图片描述
接着,在客户添加页面上编写异步加载客户信息来源数据的方法。
在这里插入图片描述

编写dao层

首先,在com.meimeixia.crm.dao包下创建一个BaseDictDao接口,并在该接口中添加一个根据数据字典类别代码(dict_type_code)去查询数据字典表的方法声明,如下:

package com.meimeixia.crm.dao;

import java.util.List;

import com.meimeixia.crm.domain.BaseDict;

/**
 * 数据字典dao的接口
 * @author liayun
 *
 */
public interface BaseDictDao {

	List<BaseDict> fingByTypeCode(String dict_type_code);

}

然后,在com.meimeixia.crm.dao.impl包下编写以上接口的一个实现类(BaseDictDaoImpl.java)。

package com.meimeixia.crm.dao.impl;

import java.util.List;

import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import com.meimeixia.crm.dao.BaseDictDao;
import com.meimeixia.crm.domain.BaseDict;

/**
 * 数据字典dao的实现类
 * @author liayun
 *
 */
public class BaseDictDaoImpl extends HibernateDaoSupport implements BaseDictDao {

	//根据类型编码去查询字典数据
	@Override
	public List<BaseDict> fingByTypeCode(String dict_type_code) {
		return (List<BaseDict>) this.getHibernateTemplate().find("from BaseDict where dict_type_code = ?", dict_type_code);
	}

}

最后,不要忘了将以上BaseDictDaoImpl实现类交给Spring来管理。
在这里插入图片描述

编写service层

首先,在com.meimeixia.crm.service包下创建一个BaseDictService接口,在该接口中添加一个根据数据字典类别代码(dict_type_code)去查询数据字典表的方法声明,如下:

package com.meimeixia.crm.service;

import java.util.List;

import com.meimeixia.crm.domain.BaseDict;

/**
 * 数据字典的业务层的接口
 * @author liayun
 *
 */
public interface BaseDictService {

	List<BaseDict> fingByTypeCode(String dict_type_code);

}

然后,在com.meimeixia.crm.service.impl包下编写以上接口的一个实现类——BaseDictServiceImpl.java。

package com.meimeixia.crm.service.impl;

import java.util.List;

import com.meimeixia.crm.dao.BaseDictDao;
import com.meimeixia.crm.domain.BaseDict;
import com.meimeixia.crm.service.BaseDictService;

/**
 * 数据字典的业务层的实现类
 * @author liayun
 *
 */
public class BaseDictServiceImpl implements BaseDictService {
	
	//注入dao
	private BaseDictDao baseDictDao;

	public void setBaseDictDao(BaseDictDao baseDictDao) {
		this.baseDictDao = baseDictDao;
	}

	@Override
	public List<BaseDict> fingByTypeCode(String dict_type_code) {
		return baseDictDao.fingByTypeCode(dict_type_code);
	}
	
}

最后,不要忘了将以上BaseDictServiceImpl实现类交给Spring来管理。
在这里插入图片描述

编写web层

首先,在com.meimeixia.crm.web.action包下创建一个BaseDictAction类,并在里面编写一个根据数据字典类别代码(dict_type_code)去查询数据字典表的findByTypeCode方法。基础不好的同学在编写该方法的过程中会遇到一些问题,其中最主要的问题就是在该方法中查询出来的东东是一个List集合,而要返回给前台的是一个JSON格式的数据,那么怎么把一个List集合转换成一个JSON格式的数据呢?我们要在项目中导入JSON依赖的必要jar包(咱们现在使用的是json-lib,它有一个不好的地方,就是导包导的比较多),如下:
在这里插入图片描述
json-lib中有三个常用的类,它们分别是:

  • JSONArray:该类能将一个数组或者List集合转成一个JSON数组。
    如果我们将BaseDictAction类中的findByTypeCode方法写成下面这个样子,
    /*
     * 根据数据字典类别代码(dict_type_code)来查询数据字典表的findByTypeCode方法
     */
    public String findByTypeCode() throws IOException {
    	System.out.println("BaseDictAction中的findByTypeCode方法执行了......");
    	//调用业务层去查询
    	List<BaseDict> list = baseDictService.fingByTypeCode(baseDict.getDict_type_code());
    	JSONArray jsonArray = JSONArray.fromObject(list);
    	System.out.println(jsonArray.toString());
    	return NONE;//此时页面不用跳转
    }
    
    那么,发布我们的项目到Tomcat服务器并启动,然后访问该项目的首页,点击新增客户超链接之后就能在Eclipse控制台中看到打印的JSON数组了。
    在这里插入图片描述
  • JsonConfig:该类是转成JSON格式的数据时的一个配置对象。
    格式化以上打印出的JSON数组后,变成下面这个样子。
    [{
    	"dict_enable": "1",
    	"dict_id": "6",
    	"dict_item_code": "",
    	"dict_item_name": "电话营销",
    	"dict_memo": "",
    	"dict_sort": 1,
    	"dict_type_code": "002",
    	"dict_type_name": "客户信息来源"
    }, {
    	"dict_enable": "1",
    	"dict_id": "7",
    	"dict_item_code": "",
    	"dict_item_name": "网络营销",
    	"dict_memo": "",
    	"dict_sort": 2,
    	"dict_type_code": "002",
    	"dict_type_name": "客户信息来源"
    }]
    
    可以发现在List集合转JSON数组时,BaseDict实体类中的dict_sort、dict_enable、dict_memo这三个无关痛痒的属性也给转了,但我们是不需要的啊!这可怎么办呢?JsonConfig类就派上用场了,这时可以将findByTypeCode方法写成下面这个样子。
    /*
     * 根据数据字典类别代码(dict_type_code)来查询数据字典表的findByTypeCode方法
     */
    public String findByTypeCode() throws IOException {
    	System.out.println("BaseDictAction中的findByTypeCode方法执行了......");
    	//调用业务层去查询
    	List<BaseDict> list = baseDictService.fingByTypeCode(baseDict.getDict_type_code());
    	JsonConfig jsonConfig = new JsonConfig();
    	jsonConfig.setExcludes(new String[]{"dict_sort", "dict_enable", "dict_memo"});//不想要谁,就把谁往里面一写就行
    	JSONArray jsonArray = JSONArray.fromObject(list, jsonConfig);
    	System.out.println(jsonArray.toString());
    	return NONE;//此时页面不用跳转
    }
    
    再次发布我们的项目到Tomcat服务器并启动,然后访问该项目的首页,点击新增客户超链接之后就可以在Eclipse控制台中看到打印的JSON数组了。
    在这里插入图片描述
  • JSONObject:该类能将一个对象或者Map集合转成一个简单的JSON对象。

了解完上面的知识点之后,我们就知道BaseDictAction类中的findByTypeCode方法该怎样编写了。

package com.meimeixia.crm.web.action;

import java.io.IOException;
import java.util.List;

import org.apache.struts2.ServletActionContext;

import com.meimeixia.crm.domain.BaseDict;
import com.meimeixia.crm.service.BaseDictService;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

import net.sf.json.JSONArray;
import net.sf.json.JsonConfig;

/**
 * 字典的Action类
 * @author liayun
 *
 */
public class BaseDictAction extends ActionSupport implements ModelDriven<BaseDict> {

	//模型驱动使用的对象
	private BaseDict baseDict = new BaseDict();
	
	@Override
	public BaseDict getModel() {
		return baseDict;
	}
	
	//注入service
	private BaseDictService baseDictService;

	public void setBaseDictService(BaseDictService baseDictService) {
		this.baseDictService = baseDictService;
	}
	
	/*
	 * 根据数据字典类别代码(dict_type_code)来查询数据字典表的findByTypeCode方法
	 */
	public String findByTypeCode() throws IOException {
		//System.out.println("BaseDictAction中的findByTypeCode方法执行了......");
		//调用业务层去查询
		List<BaseDict> list = baseDictService.fingByTypeCode(baseDict.getDict_type_code());
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setExcludes(new String[]{"dict_sort", "dict_enable", "dict_memo"});//不想要谁,就把谁往里面一写就行
		JSONArray jsonArray = JSONArray.fromObject(list, jsonConfig);//转JSON的时候,就会把"dict_sort", "dict_enable", "dict_memo"这三属性都去掉。
		System.out.println(jsonArray.toString());
		//要将JSON打印到页面上
		ServletActionContext.getResponse().setContentType("text/html;charset=UTF-8");
		ServletActionContext.getResponse().getWriter().println(jsonArray.toString());
		return NONE;//此时页面不用跳转
	}
	
}

然后,不要忘了将以上BaseDictAction交给Spring来管理。
在这里插入图片描述
接着,我们还要记得在Struts2配置文件中(即struts.xml)对以上BaseDictAction进行配置,就像下面这样:
在这里插入图片描述

异步加载其他字典项数据

客户信息来源那一项的下拉列表中的所需数据加载完了之后,我们还要加载客户级别和客户所属行业这两项的下拉列表中的所需数据。
首先,在客户添加页面中的客户级别那一项上添加一个下拉列表。
在这里插入图片描述
接着,也在客户添加页面中的客户所属行业那一项上添加一个下拉列表。
在这里插入图片描述
最后,在客户添加页面上编写异步加载客户级别和客户所属行业数据的方法。
在这里插入图片描述
此时,发布我们的项目到Tomcat服务器并启动,然后访问该项目的首页,点击新增客户超链接之后就能看到如下动图所示的效果了。
在这里插入图片描述

保存客户数据到数据库中

现在终于要写代码实现保存客户的功能了,真是不容易啊!

修改客户添加页面

在这里插入图片描述

编写dao层

首先,在CustomerDao接口中添加一个保存客户的方法声明,如下:

package com.meimeixia.crm.dao;

import com.meimeixia.crm.domain.Customer;

/**
 * 客户管理的dao的接口
 * @author liayun
 *
 */
public interface CustomerDao {

	void save(Customer customer);

}

然后,在以上接口的一个实现类(CustomerDaoImpl.java)中去实现保存客户的方法。

package com.meimeixia.crm.dao.impl;

import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import com.meimeixia.crm.dao.CustomerDao;
import com.meimeixia.crm.domain.Customer;

/**
 * 客户管理的dao的实现类
 * @author liayun
 *
 */
public class CustomerDaoImpl extends HibernateDaoSupport implements CustomerDao {

	//dao中保存客户的方法
	@Override
	public void save(Customer customer) {
		this.getHibernateTemplate().save(customer);
	}

}

编写service层

首先,在CustomerService接口中添加一个保存客户的方法声明,如下:

package com.meimeixia.crm.service;

import com.meimeixia.crm.domain.Customer;

/**
 * 客户管理类的业务层的接口
 * @author liayun
 *
 */
public interface CustomerService {

	void save(Customer customer)

}

然后,在以上接口的一个实现类(CustomerServiceImpl.java)中去实现保存客户的方法。

package com.meimeixia.crm.service.impl;

import com.meimeixia.crm.dao.CustomerDao;
import com.meimeixia.crm.domain.Customer;
import com.meimeixia.crm.service.CustomerService;

/**
 * 客户管理的业务层的实现类
 * @author liayun
 *
 */
public class CustomerServiceImpl implements CustomerService {
	
	//注入客户的dao
	private CustomerDao customerDao;

	public void setCustomerDao(CustomerDao customerDao) {
		this.customerDao = customerDao;
	}

	//业务层保存客户的方法
	@Override
	public void save(Customer customer) {
		customerDao.save(customer);
	}
	
}

编写web层

在CustomerAction类中编写如下的一个保存客户的方法(save方法)。
在这里插入图片描述

添加事务

这里一定得记得要在业务层中的实现类(CustomerServiceImpl)上添加@Transactional注解。
在这里插入图片描述
如果要是执行查询操作的话,那么是可以不用添加这个注解的。至此,保存客户的功能,我们就已经实现了,至于测试的话,我就不再这里测试了(偷懒了),反正是好使的!

猜你喜欢

转载自blog.csdn.net/yerenyuan_pku/article/details/101704361