天天看點

CRM第二篇

版權聲明:本文為部落客原創文章,遵循 CC 4.0 BY-SA 版權協定,轉載請附上原文出處連結和本聲明。

本文連結:https://blog.csdn.net/zhao1299002788/article/details/101757651

檢索政策 : 相當于優化查詢,主要是分為立即加載和延遲加載.
	當你查詢一個對象的時候,要想立馬使用這個對象,或者說是立即查詢出來,就使用立即加載.
	當你查詢這個對象時候不想立馬查詢出來,而是在使用這個對象的時候再查詢出來它,那就用延遲加載.
	
	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屬性,可以獲得目前周遊的狀态.例如 : 周遊的索引,是否為奇偶等.           

複制