前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CRM第二篇

CRM第二篇

作者头像
海仔
发布2019-10-22 16:09:15
1K0
发布2019-10-22 16:09:15
举报
文章被收录于专栏:海仔技术驿站海仔技术驿站

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/zhao1299002788/article/details/101757651

代码语言:javascript
复制
检索策略 : 相当于优化查询,主要是分为立即加载和延迟加载.
	当你查询一个对象的时候,要想立马使用这个对象,或者说是立即查询出来,就使用立即加载.
	当你查询这个对象时候不想立马查询出来,而是在使用这个对象的时候再查询出来它,那就用延迟加载.
	
	1.1 字典表和客户表的关系映射:
		当在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_address` varchar(128) DEFAULT NULL COMMENT '客户联系地址',
		  `cust_phone` varchar(64) DEFAULT NULL COMMENT '客户联系电话',
		  PRIMARY KEY (`cust_id`)
		) ENGINE=InnoDB AUTO_INCREMENT=94 DEFAULT CHARSET=utf8;

		/*创建联系人表*/
		CREATE TABLE `cst_linkman` (
		  `lkm_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '联系人编号(主键)',
		  `lkm_name` varchar(16) DEFAULT NULL COMMENT '联系人姓名',
		  `lkm_gender` char(1) DEFAULT NULL COMMENT '联系人性别',
		  `lkm_phone` varchar(16) DEFAULT NULL COMMENT '联系人办公电话',
		  `lkm_mobile` varchar(16) DEFAULT NULL COMMENT '联系人手机',
		  `lkm_email` varchar(64) DEFAULT NULL COMMENT '联系人邮箱',
		  `lkm_position` varchar(16) DEFAULT NULL COMMENT '联系人职位',
		  `lkm_memo` varchar(512) DEFAULT NULL COMMENT '联系人备注',
		  `lkm_cust_id` bigint(32) NOT NULL COMMENT '客户id(外键)',
		  PRIMARY KEY (`lkm_id`),
		  KEY `FK_cst_linkman_lkm_cust_id` (`lkm_cust_id`),
		  CONSTRAINT `FK_cst_linkman_lkm_cust_id` FOREIGN KEY (`lkm_cust_id`) REFERENCES `cst_customer` (`cust_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
		) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;


		/*创建数据字典表*/
		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;

		/*为字典表插入数据:Data for the table `base_dict` */

		LOCK TABLES `base_dict` WRITE;

		insert  into `base_dict`(`dict_id`,`dict_type_code`,`dict_type_name`,`dict_item_name`,`dict_item_code`,`dict_sort`,`dict_enable`,`dict_memo`) 
		values ('1','001','客户行业','教育培训 ',NULL,1,'1',NULL),
		('10','003','公司性质','民企',NULL,3,'1',NULL),
		('12','004','年营业额','1-10万',NULL,1,'1',NULL),
		('13','004','年营业额','10-20万',NULL,2,'1',NULL),
		('14','004','年营业额','20-50万',NULL,3,'1',NULL),
		('15','004','年营业额','50-100万',NULL,4,'1',NULL),
		('16','004','年营业额','100-500万',NULL,5,'1',NULL),
		('17','004','年营业额','500-1000万',NULL,6,'1',NULL),
		('18','005','客户状态','基础客户',NULL,1,'1',NULL),
		('19','005','客户状态','潜在客户',NULL,2,'1',NULL),
		('2','001','客户行业','电子商务',NULL,2,'1',NULL),
		('20','005','客户状态','成功客户',NULL,3,'1',NULL),
		('21','005','客户状态','无效客户',NULL,4,'1',NULL),
		('22','006','客户级别','普通客户',NULL,1,'1',NULL),
		('23','006','客户级别','VIP客户',NULL,2,'1',NULL),
		('24','007','商机状态','意向客户',NULL,1,'1',NULL),
		('25','007','商机状态','初步沟通',NULL,2,'1',NULL),
		('26','007','商机状态','深度沟通',NULL,3,'1',NULL),
		('27','007','商机状态','签订合同',NULL,4,'1',NULL),
		('3','001','客户行业','对外贸易',NULL,3,'1',NULL),
		('30','008','商机类型','新业务',NULL,1,'1',NULL),
		('31','008','商机类型','现有业务',NULL,2,'1',NULL),
		('32','009','商机来源','电话营销',NULL,1,'1',NULL),
		('33','009','商机来源','网络营销',NULL,2,'1',NULL),
		('34','009','商机来源','推广活动',NULL,3,'1',NULL),
		('4','001','客户行业','酒店旅游',NULL,4,'1',NULL),
		('5','001','客户行业','房地产',NULL,5,'1',NULL),
		('6','002','客户信息来源','电话营销',NULL,1,'1',NULL),
		('7','002','客户信息来源','网络营销',NULL,2,'1',NULL),
		('8','003','公司性质','合资',NULL,1,'1',NULL),
		('9','003','公司性质','国企',NULL,2,'1',NULL);
		UNLOCK TABLES;

	
	1.2 字典表和客户表的关系分析:
		通过上图我们可以的知 :
			一个客户只能有一个来源(级别).多个客户可能有同一个来源(级别).
		所以客户表和字典表的之间的关系是多对一.在数据库中都是依靠外键约束来实现的.
	1.3 字典表和客户表的实现类映射配置
		/*
			客户的实体类
			明确使用的注解都是JPA规范的.
			所以导包都要导入javax.persistence包下的.
		/*
		@Entity  //表示当前类是一个实体类
		@Table(name="cst_customer")  //建立当前实体类和表之间的对应关系
		public class Customer implements Serializable {
			@Id //表名当前有属性是主键
			@GeneratedValue(strategy=GenerationType.IDENTITY) //指定主键的生成策略
			@Column(name="cust_id")  //指定和数据库表中的cust_id列对应
			private Long custId;
			@Column(name="cust_name")//指定和数据库表中的cust_name列对应
			private String custName;
			
			@Column(name="cust_industry")//指定和数据库表中的cust_industry列对应
			private String custIndustry;
			
			@Column(name="cust_address")//指定和数据库表中的cust_address列对应
			private String custAddress;
			@Column(name="cust_phone")//指定和数据库表中的cust_phone列对应
			private String custPhone;
				
			@ManyToOne(targetEntity=BaseDict.class)
			@JoinColumn(name="cust_source",referencedColumnName="dict_id")
			private BaseDict custSource;
			
			@ManyToOne(targetEntity=BaseDict.class)
			@JoinColumn(name="cust_level",referencedColumnName="dict_id")
			private BaseDict custLevel;
		
	<!-- Struts2框架提供的下拉选择框的标签,做修改的时候,可以帮你自动选中
				<s:select>
					list 			要遍历集合,编写的OGNL的表达式
					name			提供表单有关,强调.
					headerKey   	请选择选项值
					headerValue 	请选择选项文字, -请选择-
					listKey			生成option下拉选择框的值
					listValue		生成option下拉选择框的文字
				 -->
				<s:select list="#sourceList" name="source.dictId" headerKey="" headerValue="-请选择-" listKey="dictId" listValue="dictItemName"></s:select>	
	
	/**
		 * 字典表的数据模型
		 *
		 */
		@Entity
		@Table(name="base_dict")
		public class BaseDict implements Serializable {
			
			@Id
			@GeneratedValue(strategy=GenerationType.AUTO)
			@Column(name="dict_id")
			private String dictId;
			@Column(name="dict_type_code")
			private String dictTypeCode;
			@Column(name="dict_type_name")
			private String dictTypeName;
			@Column(name="dict_item_name")
			private String dictItemName;
			@Column(name="dict_item_code")
			private String dictItemCode;
			@Column(name="dict_sort")
			private Integer dictSort;
			@Column(name="dict_enable")
			private String dictEnable;
			@Column(name="dict_memo")
			private String dictMemo;
			public String getDictId() {
				return dictId;
			}
			public void setDictId(String dictId) {
				this.dictId = dictId;
			}
			public String getDictTypeCode() {
				return dictTypeCode;
			}
			public void setDictTypeCode(String dictTypeCode) {
				this.dictTypeCode = dictTypeCode;
			}
			public String getDictTypeName() {
				return dictTypeName;
			}
			public void setDictTypeName(String dictTypeName) {
				this.dictTypeName = dictTypeName;
			}
			public String getDictItemName() {
				return dictItemName;
			}
			public void setDictItemName(String dictItemName) {
				this.dictItemName = dictItemName;
			}
			public String getDictItemCode() {
				return dictItemCode;
			}
			public void setDictItemCode(String dictItemCode) {
				this.dictItemCode = dictItemCode;
			}
			public Integer getDictSort() {
				return dictSort;
			}
			public void setDictSort(Integer dictSort) {
				this.dictSort = dictSort;
			}
			public String getDictEnable() {
				return dictEnable;
			}
			public void setDictEnable(String dictEnable) {
				this.dictEnable = dictEnable;
			}
			public String getDictMemo() {
				return dictMemo;
			}
			public void setDictMemo(String dictMemo) {
				this.dictMemo = dictMemo;
			}
			@Override
			public String toString() {
				return "BaseDict [dictId=" + dictId + ", dictTypeCode=" + dictTypeCode + ", dictTypeName=" + dictTypeName
						+ ", dictItemName=" + dictItemName + ", dictItemCode=" + dictItemCode + ", dictSort=" + dictSort
						+ ", dictEnable=" + dictEnable + ", dictMemo=" + dictMemo + "]";
			}
		}

		第2章客户的增删改查操作
		2.1写在最前
		本章节提供的是客户增删改查的代码实现。
		下面出现的Action指的的是:CustomerAction
		出现的Service指的是:ICustomerService和CustomerServiceImpl
		出现的Dao指的是:CustomerDao和CustomerDaoImpl。
		这些类都需要交给spring来管理。
		在没有提供新的类(或接口)时,从2.2章节开始的Action,Service和Dao的代码都是出现在以下的类中。
		Action
		/**
		 * 客户的动作类
		 *
		 *
		 */
		@Controller("customerAction")
		@Scope("prototype")
		@ParentPackage("struts-default")
		@Namespace("/customer")
		public class CustomerAction extends ActionSupport implements ModelDriven<Customer> {
			private Customer customer = new Customer();
			
			@Autowired
			private ICustomerService customerService ;

			@Override
			public Customer getModel() {
				return customer;
			}
		}
		Service
		/**
		 * 客户的业务层接口
		 *
		 */
		public interface ICustomerService {
		}

		/**
		 * 客户的业务层实现类
		 *
		 */
		@Service("customerService")
		@Transactional(propagation=Propagation.SUPPORTS,readOnly=true)
		public class CustomerServiceImpl implements ICustomerService {

			@Autowired
			private ICustomerDao customerDao;
		}

		Dao
		/**
		 * 客户的持久层接口
		 *
		 */
		public interface ICustomerDao {
		}

		/**
		 * 客户的持久层实现类
		 *
		 */
		@Repository("customerDao")
		public class CustomerDaoImpl implements ICustomerDao {
			@Autowired
			private HibernateTemplate hibernateTemplate;
		}

		2.2显示添加客户页面
		2.2.1menu.jsp页面
		<A	href="${pageContext.request.contextPath}/customer/addUICustomer.action"  
			class=style2 target=main>
			- 新增客户
		</A>
		2.2.2Action
		/**
		 * 获取添加客户页面
		 * @return
		 */
		private List<BaseDict> custSources;
		private List<BaseDict> custLevels;

		@Action(value="addUICustomer",results={
			@Result(name="addUICustomer",type="dispatcher",location="/jsp/customer/add.jsp")
		})
		public String addUICustomer(){
			//1.查询所有客户来源
			custSources = customerService.findAllCustomerSource();
			//2.查询所有客户级别
			custLevels = customerService.findAllCustomerLevel();
			return "addUICustomer";
		}

		public List<BaseDict> getCustLevels() {
			return custLevels;
		}
		public void setCustLevels(List<BaseDict> custLevels) {
			this.custLevels = custLevels;
		}
		public List<BaseDict> getCustSources() {
			return custSources;
		}
		public void setCustSources(List<BaseDict> custSources) {
			this.custSources = custSources;
		}
		2.2.3Service
			/**
			 * 查询所有客户来源
			 * @return
			 */
			List<BaseDict> findAllCustomerSource();
			
			/**
			 * 查询所有客户级别
			 * @return
			 */
			List<BaseDict> findAllCustomerLevel();

			@Override
			@Transactional(propagation=Propagation.SUPPORTS,readOnly=true)
			public List<BaseDict> findAllCustomerSource() {
				return baseDictDao.findBaseDictByTypeCode("002");
			}

			@Override
			@Transactional(propagation=Propagation.SUPPORTS,readOnly=true)
			public List<BaseDict> findAllCustomerLevel() {
				return baseDictDao.findBaseDictByTypeCode("006");
			}
		2.2.4Dao
		/**
		 * 数据字典实体的持久层接口
		 *
		 *
		 */
		public interface IBaseDictDao {
			/**
			 * 根据字典类型查询字典表数据
			 * @param typeCode		字典类型编码
			 * @return
			 */
			List<BaseDict> findBaseDictByTypeCode(String typeCode);	
		}

		/**
		 * 数据字典实体的持久层实现类
		 *
		 */
		@Repository("baseDictDao")
		public class BaseDictDaoImpl implements IBaseDictDao {
			
			@Autowired
			private HibernateTemplate hibernateTemplate;

			@Override
			public List<BaseDict> findBaseDictByTypeCode(String typeCode) {
				return (List<BaseDict>) hibernateTemplate.find("from BaseDict where dictTypeCode = ? ", typeCode);
			}
		}


		1.使用了Struts2框架的select标签,默认含有样色的。不想使用样式,在strts.xml配置文件中添加常量
		<constant name="struts.ui.theme" value="simple"/>
		2.3保存客户
		2.3.1add.jsp
		<s:form action="addCustomer" namespace="/customer">
			<TABLE cellSpacing=0 cellPadding=5  border=0>
				<TR>
					<td>客户名称:</td>
					<td>
						<s:textfield name="custName" class="textbox" id="sChannel2" style="WIDTH: 180px" maxLength="50" />
					</td>
					<td>所属行业 :</td>
					<td>
						<s:textfield name="custIndustry" class="textbox" id="sChannel2" style="WIDTH: 180px" maxLength="50" />
					</td>
				</TR>							
				<TR>	
					td>信息来源 :</td>
					<td>
						<s:select list="custSources"  name="custSource.dictId" listKey="dictId" listValue="dictItemName" headerKey="" headerValue="---请选择---" class="textbox" id="sChannel2" style="WIDTH: 180px"></s:select>
					</td>
					<td>客户级别:</td>
					<td>
						<s:select list="custLevels"  name="custLevel.dictId" listKey="dictId" listValue="dictItemName" headerKey="" headerValue="---请选择---" class="textbox" id="sChannel2" style="WIDTH: 180px"></s:select>									</td>
				</TR>
				<TR>
					<td>联系地址 :</td>
					<td>
						<s:textfield name="custAddress" class="textbox" id="sChannel2" style="WIDTH: 180px" maxLength="50" />
					</td>
					<td>联系电话 :</td>
					<td>
						<s:textfield name="custPhone" class="textbox" id="sChannel2" style="WIDTH: 180px" maxLength="50" />								
					</td>
				</TR>
				<tr>
					<td rowspan=2>
						<s:submit value="保存"/>
					</td>
				</tr>
			</TABLE>
		</s:form>
		2.3.2Action
		@Action(value="addCustomer",results={
			@Result(name="addCustomer",type="redirect",location="/jsp/success.jsp")
		})
		public String addCustomer(){
			customerService.saveCustomer(customer);
			return "addCustomer";
		}
			
		2.3.3Service
		/**
		 * 保存客户
		 * @param customer
		 */
		void saveCustomer(Customer customer);


		@Override
		public void saveCustomer(Customer customer) {
			customerDao.save(customer);
		}
		2.3.4Dao
		/**
		 * 保存客户
		 * @param customer
		 */
		void save(Customer customer);


		@Override
		public void save(Customer customer) {
			hibernateTemplate.save(customer);
		}
		2.4客户列表展示
		2.4.1menu.jsp
		<A href="${pageContext.request.contextPath}/customer/findAllCustomer.action" 
			class=style2 target=main>
			- 客户列表
			</A>
		2.4.2Action
		/**
		 * 查询所有客户
		 * @return
		 */
		private List<Customer> customers;
		@Action(value="findAllCustomer",results={
			Result(name="findAllCustomer",location="/jsp/cusotmer/list.jsp")
		})
		public String findAllCustomer(){
			//1.查询所有客户
			customers = customerService.findAllCustomer();
			return "findAllCustomer";
		}

		public List<Customer> getCustomers() {
			return customers;
		}
		public void setCustomers(List<Customer> customers) {
			this.customers = customers;
		}
		2.4.3Service
		/**
		 * 查询所有客户信息
		 * @return
		 */
		List<Customer> findAllCustomer();

		@Override
		@Transactional(propagation=Propagation.SUPPORTS,readOnly=true)
		public List<Customer> findAllCustomer() {
			return customerDao.findAllCustomer();
		}
		2.4.4Dao
		/**
		 *查询所有客户
		 * @return
		 */
		List<Customer> findAllCustomer();

		@Override
		public List<Customer> findAllCustomer() {
			return (List<Customer>) hibernateTemplate.find("from Customer ");
		}
		2.5客户删除
		2.5.1list.jsp
		<s:a href="javascript:delOne('%{custId}')">删除</s:a>
		<SCRIPT language=javascript>
			function delOne(custId){
				var sure = window.confirm("确定删除吗?");
				if(sure){
			window.location.href="${pageContext.request.contextPath}/customer/removeCustomer.action?custId="+custId;
				}
			}
		</SCRIPT>
		2.5.2Action
		/**
		 * 删除客户
		 * @return
		 */
		@Action(value="removeCustomer",results={
			@Result(name="removeCustomer",type="redirect",location="/jsp/success.jsp")
		})
		public String removeCustomer(){
			customerService.removeCustomer(customer);
			return "removeCustomer";
		}
		2.5.3Service
		/**
		 * 删除客户
		 * @param customer
		 */
		void removeCustomer(Customer customer);

		@Override
		public void removeCustomer(Customer customer) {
			customerDao.delete(customer);
		}
		2.5.4Dao
		/**
		 * 删除客户
		 * @param customer
		 */
		void delete(Customer customer);

		@Override
		public void delete(Customer customer) {
			hibernateTemplate.delete(customer);
		}

		2.6显示客户修改页面
		2.6.1list.jsp
		<s:a action="editUICustomer" namespace="/customer">
			<s:param name="custId" value="%{custId}"></s:param>
			修改
		</s:a>
		2.6.2Action
		/**
		 * 获取编辑客户页面
		 * @return
		 */
		@Action(value="editUICustomer",results={
			@Result(name="editUICustomer",type="dispatcher",location="/jsp/customer/edit.jsp")
		})
		public String editUICustomer(){
			//1.根据id查询要编辑的客户对象
			Customer dbCustomer = customerService.findCustomerById(customer.getCustId());
			//2.获取值栈对象
			ValueStack vs = ActionContext.getContext().getValueStack();
			//3.把查询出来的客户对象压入栈顶
			vs.push(dbCustomer);
			//4.查询所有客户来源和客户级别
			custSources = customerService.findAllCustomerSource();
			custLevels = customerService.findAllCustomerLevel();
			return "editUICustomer";
		}
		2.6.3Service
		/**
		 * 根据id查询客户信息
		 * @param custId
		 * @return
		 */
		Customer findCustomerById(Long custId);

		@Override
		@Transactional(propagation=Propagation.SUPPORTS,readOnly=true)
		public Customer findCustomerById(Long custId) {
			return customerDao.findById(custId);
		}
		2.6.4Dao
		/**
		 * 根据id查询客户
		 * @param customer
		 */
		void findById(Long custId);


		@Override
		public void findById (Long custId) {
			hibernateTemplate.get(Customer.class,custId);
		}
		2.7客户修改
		2.7.1edit.jsp
		<s:form action="editCustomer" namespace="/customer">
			<s:hidden name="custId" value="%{custId}"></s:hidden>
			<TABLE cellSpacing=0 cellPadding=5  border=0>
				<TR>
					<td>客户名称:</td>
					<td>
						<s:textfield name="custName" class="textbox" id="sChannel2" style="WIDTH: 180px" maxLength="50" />
					</td>
					<td>所属行业 :</td>
					<td>
						<s:textfield name="custIndustry" class="textbox" id="sChannel2" style="WIDTH: 180px" maxLength="50" />
					</td>
				</TR>							
				<TR>	
					td>信息来源 :</td>
					<td>
						<s:select list="custSources"  name="custSource.dictId" listKey="dictId" listValue="dictItemName" headerKey="" headerValue="---请选择---" class="textbox" id="sChannel2" style="WIDTH: 180px"></s:select>
					</td>
					<td>客户级别:</td>
					<td>
						<s:select list="custLevels"  name="custLevel.dictId" listKey="dictId" listValue="dictItemName" headerKey="" headerValue="---请选择---" class="textbox" id="sChannel2" style="WIDTH: 180px"></s:select>									</td>
				</TR>
				<TR>
					<td>联系地址 :</td>
					<td>
						<s:textfield name="custAddress" class="textbox" id="sChannel2" style="WIDTH: 180px" maxLength="50" />
					</td>
					<td>联系电话 :</td>
					<td>
						<s:textfield name="custPhone" class="textbox" id="sChannel2" style="WIDTH: 180px" maxLength="50" />								
					</td>
				</TR>
				<tr>
					<td rowspan=2>
						<s:submit value="保存"/>
					</td>
				</tr>
			</TABLE>
		</s:form>
		2.7.2Action
		/**
		 * 编辑客户
		 * @return
		 */
		@Action(value="editCustomer",results={
			@Result(name="editCustomer",type="redirect",location="/jsp/success.jsp")
		})
		public String editCustomer(){
			customerService.updateCustomer(customer);
			return "editCustomer";
		}
		2.7.3Service
		/**
		 * 编辑客户
		 * @param customer
		 */
		void updateCustomer(Customer customer);

		@Override
		public void updateCustomer(Customer customer) {
			customerDao.update(customer);
		}
		2.7.4Dao
		/**
		 * 更新客户
		 * @param customer
		 */
		void update(Customer customer);


		@Override
		public void delete(Customer customer) {
			hibernateTemplate.update(customer);
		}

		2.8客户的列表条件查询
		2.8.1list.jsp
		<s:form action="findAllCustomer" namespace="/customer">
			<TR>
				<td>客户名称:</td>
				<td>
					<s:textfield name="custName" class="textbox" id="sChannel2" style="WIDTH: 80px" maxLength="50" />
				</td>
				<td>所属行业 :</td>
				<td>
					<s:textfield name="custIndustry" class="textbox" id="sChannel2" style="WIDTH: 80px" maxLength="50" />
				</td>
				<td>信息来源 :</td>
				<td>
					<s:select list="custSources"  name="custSourceId" listKey="dictId" listValue="dictItemName" headerKey="" headerValue="---请选择---" class="textbox" id="sChannel2" style="WIDTH: 80px"></s:select>
				</td>
				<td>客户级别:</td>
				<td>
					<s:select list="custLevels"  name="custLevelId" listKey="dictId" listValue="dictItemName" headerKey="" headerValue="---请选择---" class="textbox" id="sChannel2" style="WIDTH: 80px"></s:select>								
				</td>
				<TD>
					<s:submit value=" 筛选 "></s:submit>
				</TD>
			</TR>
		</s:form>
		2.8.2Action
		/**
		 * 查询所有客户
		 * @return
		 */

		@Action(value="findAllCustomer",results={
			@Result(name="findAllCustomer",type="dispatcher",location="/jsp/customer/list.jsp")
		})
		public String findAllCustomer(){
			//1.创建离线查询对象
			DetachedCriteria dCriteria = DetachedCriteria.forClass(Customer.class);//就相当于查询所有  from Customer;
			//2.拼装查询条件
			//判断是否提供了客户名称
			if(StringUtils.isNotBlank(customer.getCustName())){
				//添加条件:模糊查询客户名称
			dCriteria.add(Restrictions.like("custName","%"+customer.getCustName()+"%"));
			}
			//判断是否提供了客户行业
			if(StringUtils.isNotBlank(customer.getCustIndustry())){
				//添加条件:模糊查询客户行业
			dCriteria.add(Restrictions.like("custIndustry","%"+customer.getCustIndustry()+"%"));
			}
			//判断是否提供了客户来源
			if(StringUtils.isNotBlank(custSourceId)){
				//添加条件:精确查询客户来源  
			dCriteria.add(Restrictions.eq("custSource.dictId", custSourceId));
			}
			//判断是否提供了客户来源
			if(StringUtils.isNotBlank(custLevelId)){
				//添加条件:精确查询客户来源  
				dCriteria.add(Restrictions.eq("custLevel.dictId", custLevelId));
			}
			//3.查询所有客户
			customers = customerService.findAllCustomer(dCriteria);
			//4.查询所有客户来源和所有客户级别
			custSources = customerService.findAllCustomerSource();
			custLevels = customerService.findAllCustomerLevel();
			return "findAllCustomer";
		}
		2.8.3Service
		/**
		 * 查询所有客户,带条件
		 * @param dCriteria	查询条件
		 * @return
		 */
		List<Customer> findAllCustomer(DetachedCriteria dCriteria);

		@Override
		@Transactional(propagation=Propagation.SUPPORTS,readOnly=true)
		public Page findAllCustomer(DetachedCriteria dCriteria) {
			return customerDao.findAllCustomer(dCriteria);
		}
		2.8.4Dao
		/**
		 * 查询所有客户
		 * @param dCriteria 查询条件
		 * @return
		 */
		List<Customer> findAllCustomer(DetachedCriteria dCriteria);
		
	Jsp页面:
		<%-- 页面自带的
									<select name="custSource" class=textbox id=sChannel2 style="WIDTH: 180px">
										<option value="non">---请选择---</option>
										<option value="6">电话营销</option>
										<option value="7">网络营销</option>
									</select>
									--%>
									
									<%-- 默认选中比较麻烦
									<select name="custSource" class=textbox id=sChannel2 style="WIDTH: 180px">
										<c:forEach var="dict" items="${ sourceList }">
											<option value="${ dict.dictId }">${ dict.dictItemName }</option>
										</c:forEach>
									</select>
									--%>
									
									<%-- Struts2框架提供的下拉选择框的标签,做修改的时候,可以帮你自动选中 
										<s:select>
											list			要遍历集合,编写的OGNL的表达式
											name			提供表单有关,强调。
											headerKey		请选择选项值
											headerValue		请选择选项文字  -请选择-
											listKey			生成option下啦选择框的值
											listValue		生成option下啦选择框的文字
									--%>
									<s:select list="#sourceList" name="source.dictId" headerKey="" headerValue="-请选择-" listKey="dictId" listValue="dictItemName"/>
<%-- 
									<select name="custSource" class=textbox id=sChannel2 style="WIDTH: 180px">
										<c:forEach items="${ sourc3eList }" var="dict">
											<c:choose>
												<c:when test="${ dict.dictId == source.dictId }">
													<option value="${ dict.dictId }" selected>${ dict.dictItemName }</option>
												</c:when>
												<c:otherwise>
													<option value="${ dict.dictId }">${ dict.dictItemName }</option>
												</c:otherwise>
											</c:choose>
										</c:forEach>
									</select>
									--%>
									
									<%-- 
										下拉选择框,Struts2标签可以使用name属性获取值栈中的值。
										name="source.dictId"	获取的model对象的source属性,source对象的dictId属性
										<s:textfield name="custName" />
									--%>
									<s:select list="#sourceList" name="source.dictId" listKey="dictId" listValue="dictItemName"/>

	Action	
		package com.baidu.customer.action;

		import java.util.List;

		import javax.annotation.Resource;

		import org.hibernate.criterion.DetachedCriteria;
		import org.hibernate.criterion.Restrictions;
		import org.springframework.context.annotation.Scope;
		import org.springframework.stereotype.Controller;

		import com.baidu.base.action.BaseAction;
		import com.baidu.customer.domain.Customer;
		import com.baidu.customer.service.CustomerService;
		import com.baidu.dict.domain.Dict;
		import com.baidu.dict.service.DictService;
		import com.opensymphony.xwork2.ModelDriven;

		/**
		 * 客户模块
		 * @author Administrator
		 */
		@Controller("customerAction")
		@Scope("prototype")
		public class CustomerAction extends BaseAction implements ModelDriven<Customer>{

			private static final long serialVersionUID = 4683080283444298532L;
			
			private Customer model = new Customer();
			
			// ${model.custName}		model调用getModel()方法
			public Customer getModel() {
				return model;
			}
			
			@Resource(name="customerService")
			private CustomerService customerService;
			
			@Resource(name="dictService")
			private DictService dictService;
			
			/**
			 * 跳转到新增页面
			 * @return
			 * @throws Exception
			 */
			public String initSave() throws Exception {
				// 查询来源 SELECT * FROM base_dict WHERE dict_type_code = '002'
				List<Dict> sourceList = dictService.findByWhere("002");
				// 查询级别
				List<Dict> levelList = dictService.findByWhere("006");
				// 查询行业
				List<Dict> industryList = dictService.findByWhere("001");
				
				/*
				// 压栈
				ActionContext context = ActionContext.getContext();
				// put方法
				context.put("sourceList", sourceList);
				context.put("levelList", levelList);
				context.put("industryList", industryList);
				*/
				
				// 调用父类的方法
				super.put("sourceList", sourceList);
				super.put("levelList", levelList);
				super.put("industryList", industryList);
				
				// ValueStack vs = context.getValueStack();
				// vs.push(xxx);
				
				return "initSave";
			}
			
			/**
			 * 保存客户
			 * @return
			 * @throws Exception
			 */
			public String save() throws Exception {
				customerService.save(model);
				return SUCCESS;
			}
			
			/**
			 * 查询所有的客户
			 * @return
			 * @throws Exception
			 
			public String list() throws Exception {
				// 使用service查询
				List<Customer> list = customerService.findAll();
				// 压栈
				// ActionContext.getContext().put("list", list);
				super.put("list", list);
				return "list";
			}
			*/
			
			/**
			 * 添加查询条件
			 * @return
			 * @throws Exception
			 */
			public String list() throws Exception {
				/*
				// 使用service查询
				List<Customer> list = customerService.findAll();
				// 压栈
				// ActionContext.getContext().put("list", list);
				super.put("list", list);
				*/
				
				// 推荐,带条件的查询,使用离线查询方式
				// 创建离线条件的对象
				DetachedCriteria criteria = DetachedCriteria.forClass(Customer.class);
				// model已经封装了custName属性
				String custName = model.getCustName();
				// 判断
				if(custName != null && !custName.trim().isEmpty()){
					// 说明,填入了值,拼接查询条件
					criteria.add(Restrictions.like("custName", "%"+custName+"%"));
				}
				// 调用业务层
				List<Customer> list = customerService.findAll(criteria);
				super.put("list", list);
				
				return "list";
			}
			
			/**
			 * 跳转到修改的页面
			 * @return
			 * @throws Exception
			 */
			public String initUpdate() throws Exception {
				// 接收id值 ,model已经封装
				model = customerService.findById(model.getCustId());
				// 压栈
				super.push(model);
				
				// 查询来源 行业 级别
				List<Dict> sourceList = dictService.findByWhere("002");
				// 查询级别
				List<Dict> levelList = dictService.findByWhere("006");
				// 查询行业
				List<Dict> industryList = dictService.findByWhere("001");
				
				// 调用父类的方法
				super.put("sourceList", sourceList);
				super.put("levelList", levelList);
				super.put("industryList", industryList);
				
				return "initUpdate";
			}
			
			/**
			 * 修改客户
			 * @return
			 * @throws Exception
			 */
			public String update() throws Exception {
				// 先通过id查询,从数据库中查询的,数据没有改变的数据
				Customer customer = customerService.findById(model.getCustId());
				// model封装了主键 名称 所有的属性,只会封装7个属性,model封装的是页面提交的数据,修改后的数据
				// 把model的数据设置到customer对象中
				customer.setCustName(model.getCustName());
				customer.setIndustry(model.getIndustry());
				customer.setSource(model.getSource());
				customer.setLevel(model.getLevel());
				customer.setCustAddress(model.getCustAddress());
				customer.setCustPhone(model.getCustPhone());
				// 更新
				customerService.update(customer);
				return SUCCESS;
			}
			
			/**
			 * 删除
			 * @return
			 * @throws Exception
			 */
			public String delete() throws Exception {
				// model封装了dictId属性
				Customer customer = customerService.findById(model.getCustId());
				// 删除功能的时候,为了级联删除做准备工作,先查询,再删除
				customerService.delete(customer);
				return SUCCESS;
			}
			
		}
	持久层 :
		package com.baidu.customer.dao.impl;

		import java.util.List;

		import javax.annotation.Resource;

		import org.hibernate.criterion.DetachedCriteria;
		import org.springframework.orm.hibernate5.HibernateTemplate;
		import org.springframework.stereotype.Repository;

		import com.baidu.customer.dao.CustomerDao;
		import com.baidu.customer.domain.Customer;

		/**
		 * 持久层
		 * @author Administrator
		 */
		@Repository("customerDao")
		public class CustomerDaoImpl implements CustomerDao {
			
			@Resource(name="hibernateTemplate")
			private HibernateTemplate hibernateTemplate;
			
			/**
			 * 保存
			 */
			public void save(Customer customer) {
				hibernateTemplate.save(customer);
			}

			/**
			 * 查询所有
			 */
			public List<Customer> findAll() {
				return (List<Customer>) hibernateTemplate.find("from Customer");
			}

			/**
			 * 通过主键查询一个对象
			 */
			public Customer findById(Long custId) {
				// session.get()
				return hibernateTemplate.get(Customer.class, custId);
			}

			public void update(Customer customer) {
				hibernateTemplate.update(customer);
			}

			public void delete(Customer customer) {
				hibernateTemplate.delete(customer);
			}
			
			/**
			 * 离线条件查询
			 */
			public List<Customer> findAll(DetachedCriteria criteria) {
				return (List<Customer>) hibernateTemplate.findByCriteria(criteria);
			}

		}
	
	离线查询的好处:在任意位置不需要session可以创建对象.
	
	字典表代码 :
		package com.baidu.dict.domain;

		import javax.persistence.Column;
		import javax.persistence.Entity;
		import javax.persistence.GeneratedValue;
		import javax.persistence.Id;
		import javax.persistence.Table;

		import org.hibernate.annotations.GenericGenerator;

		/**
		 * 客户字典表
		 * @author Administrator
		 */
		@Entity
		@Table(name="base_dict")
		public class Dict {
			
			/**
			 * 主键的类型是String,不能使用自动递增。学习过hibernate框架,提供主键生成策略。
			 * 		* native	整形
			 * 		* uuid		字符串
			 * 
			 * 在JPA中使用hibernate框架的策略,uuid的策略
			 * 	@GenericGenerator(name="sysUUID",strategy="uuid")
				@GeneratedValue(generator="sysUUID")			// 引入其他的策略
			 */
			@Id
			// @GeneratedValue(strategy=GenerationType.AUTO)	使用JPA的策略
			// 自定义sysUUID的策略,使用的hibernate框架的uuid策略
			@GenericGenerator(name="sysUUID",strategy="uuid")
			@GeneratedValue(generator="sysUUID")			// 引入其他的策略
			@Column(name="dict_id")
			private String dictId;
			
			@Column(name="dict_type_code")
			private String dictTypeCode;
			
			@Column(name="dict_type_name")
			private String dictTypeName;
			
			@Column(name="dict_item_name")
			private String dictItemName;
			
			@Column(name="dict_item_code")
			private String dictItemCode;
			
			@Column(name="dict_sort")
			private Integer dictSort;
			
			@Column(name="dict_enable")
			private String dictEnable;
			
			@Column(name="dict_memo")
			private String dictMemo;

			public String getDictId() {
				return dictId;
			}

			public void setDictId(String dictId) {
				this.dictId = dictId;
			}

			public String getDictTypeCode() {
				return dictTypeCode;
			}

			public void setDictTypeCode(String dictTypeCode) {
				this.dictTypeCode = dictTypeCode;
			}

			public String getDictTypeName() {
				return dictTypeName;
			}

			public void setDictTypeName(String dictTypeName) {
				this.dictTypeName = dictTypeName;
			}

			public String getDictItemName() {
				return dictItemName;
			}

			public void setDictItemName(String dictItemName) {
				this.dictItemName = dictItemName;
			}

			public String getDictItemCode() {
				return dictItemCode;
			}

			public void setDictItemCode(String dictItemCode) {
				this.dictItemCode = dictItemCode;
			}

			public Integer getDictSort() {
				return dictSort;
			}

			public void setDictSort(Integer dictSort) {
				this.dictSort = dictSort;
			}

			public String getDictEnable() {
				return dictEnable;
			}

			public void setDictEnable(String dictEnable) {
				this.dictEnable = dictEnable;
			}

			public String getDictMemo() {
				return dictMemo;
			}

			public void setDictMemo(String dictMemo) {
				this.dictMemo = dictMemo;
			}
		}
		
		package com.baidu.dict.service.impl;

		import java.util.List;

		import javax.annotation.Resource;

		import org.springframework.stereotype.Service;

		import com.baidu.dict.dao.DictDao;
		import com.baidu.dict.domain.Dict;
		import com.baidu.dict.service.DictService;

		@Service("dictService")
		public class DictServiceImpl implements DictService {

			@Resource(name="dictDao")
			private DictDao dictDao;

			/**
			 * 按条件查询
			 */
			public List<Dict> findByWhere(String string) {
				return dictDao.findByWhere(string);
			}
			
		}

		2package com.baidu.dict.dao.impl;

		import java.util.List;

		import javax.annotation.Resource;

		import org.springframework.orm.hibernate5.HibernateTemplate;
		import org.springframework.stereotype.Repository;

		import com.baidu.dict.dao.DictDao;
		import com.baidu.dict.domain.Dict;

		@Repository("dictDao")
		public class DictDaoImpl implements DictDao {
			
			@Resource(name="hibernateTemplate")
			private HibernateTemplate hibernateTemplate;
			
			/**
			 * 条件查询
			 */
			public List<Dict> findByWhere(String string) {
				// 使用HQL的查询
				return (List<Dict>) hibernateTemplate.find("from Dict where dictTypeCode = ?", string);
			}
			
		}

	配置文件:
		<?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:aop="http://www.springframework.org/schema/aop"
			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/aop
			http://www.springframework.org/schema/aop/spring-aop.xsd
			http://www.springframework.org/schema/tx 
			http://www.springframework.org/schema/tx/spring-tx.xsd">
			
			<!-- 开启注解的扫描 -->
			<context:component-scan base-package="com.baidu"/>
			
			<!-- 配置C3P0的连接池 -->
			<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
				<property name="driverClass" value="com.mysql.jdbc.Driver"/>
				<property name="jdbcUrl" value="jdbc:mysql:///crm"/>
				<property name="user" value="root"/>
				<property name="password" value="root"/>
			</bean>
			
			<!-- Spring整合hibernate框架 -->
			<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
				<!-- 注入连接池 -->
				<property name="dataSource" ref="dataSource"/>
				<!-- 注入属性 -->
				<property name="hibernateProperties">
					<props>
						<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
						<prop key="hibernate.show_sql">true</prop>
						<prop key="hibernate.format_sql">true</prop>
						<prop key="hibernate.hbm2ddl.auto">none</prop>
						<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</prop>
					</props>
				</property>
				<!-- 注入扫描entity注解 -->
				<property name="packagesToScan">
					<array>
						<value>com.baidu.*.domain</value>
					</array>
				</property>
			</bean>
			
			<!-- 先配置模板 -->
			<bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
				<property name="sessionFactory" ref="sessionFactory"/>
			</bean>
			
			<!-- 配置事务 -->
			<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
				<property name="sessionFactory" ref="sessionFactory"/>
			</bean>
			
			<!-- 配置事务通知 -->
			<tx:advice id="myAdvice" transaction-manager="transactionManager">
				<tx:attributes>
					<tx:method name="save*" isolation="DEFAULT" propagation="REQUIRED"/>
					<tx:method name="update*" isolation="DEFAULT" propagation="REQUIRED"/>
					<tx:method name="delete*" isolation="DEFAULT" propagation="REQUIRED"/>
					<tx:method name="find*" read-only="true"/>
					<tx:method name="*" isolation="DEFAULT" propagation="REQUIRED"/>
				</tx:attributes>
			</tx:advice>
			
			<!-- 配置AOP增强 -->
			<aop:config>
				<aop:advisor advice-ref="myAdvice" pointcut="execution(* com.baidu.*.service.impl.*ServiceImpl.*(..))"/>
			</aop:config>
			
		</beans>

		<?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>
			<!-- 使用Struts2框架标签的时候,使用简单的样式 -->
			<constant name="struts.ui.theme" value="simple"/>
			
			<package name="crm" extends="struts-default" namespace="/">
				<!-- 配置客户模块 -->
				<action name="customerAction_*" class="customerAction" method="{1}">
					<result name="initSave">/jsp/customer/add.jsp</result>
					<result name="list">/jsp/customer/list.jsp</result>
					<result name="initUpdate">/jsp/customer/edit.jsp</result>
					<result name="success" type="redirect">customerAction_list</result>
				</action>
			</package>
		</struts>
		离线查询的好处:在任意位置不需要session可以创建对象

	在Struts2框架中,先后在struts.xml中,struts.properties中和web.xml中来修改struts的同一个常量.在web.xml配置文件中的修改会最终生效.web.xml是倒数第二个执行的.
	通过构造函数依赖注入,使用,其中index="1" 表示 : 按照参数的顺序,其中1表示第二个参数.
		有关一级缓存和快照描述 :
			A: 快照区保存了与一级缓存相对应的数据,但是并不是真正的对象.
			B: 刷新一级缓存时,执行SQL语句的判定标准为数据区与快照区的数据是否相同.
			D: 执行查询时,查询数据封装为对象保存在一级缓存区,同时将查询数据快照信息保存到快照区.
		值栈root对象栈数据描述:
			A: valueStack.push(obj)将指定的对象压入到值栈.
			B: 在jsp页面,可以使用defs:property/> 获得栈顶的数据
			D: 在jsp页面,可以使用defs:property value="name"/> 获得对象栈中name属性的值
			
		struts访问servlet的api:
			A: 可以通过ActionContext解耦合的方式,间接的操作servlet的三个作用域.
			B: ServletActionContext提供了访问servlet常用对象的方法.例如 : getServletContext()等.
			C: struts提供若干接口直接给action注入相应的对象.例如 : ServletContextAware可以给当前action注入ServletContext对象.
			D: ServletActionContext.getRequest()可以获得HttpServletRequest对象.
			
		以下描述是正确的:
			A: value属性的值对应值栈中的相关的数据.
			C: 如果使用var属性,在值栈的context中存放一个键值对.
			D: 如果使用status属性,可以获得当前遍历的状态.例如 : 遍历的索引,是否为奇偶等.
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-09-30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档