SSH enterprise case_ CRM customer management system: customer management module & Dictionary & asynchronous

Posted by rfrid on Thu, 20 Jan 2022 23:22:38 +0100

1. Review of last lesson

 SVN
• SVN: version control tool.
• common version control tools
     SVN
     CVS
     GIT
• install SVN server
• install SVN client
• use of SVN
 check out
 update
 submit commit
 solve SVN conflict
• setting of SVN permissions
 SVN create user
 SVN create group
 SVN setting permission
• Eclipse Plug-in for SVN
 build CRM environment
• CRM: Customer Relationship Management
• CRM preparation:
 CRM user registration function
• complete the function of user registration
 deploy CRM on SVN server

2. CRM comprehensive exercise: user module login function

User module: login function code implementation

Modify the login page: change the path to login_action
Write the login method in Action

Write Service

Write Dao

Configure page Jump

Display data in page
 display user information on the success page
 display error information on the failed page

3. CRM comprehensive exercise: customer management saving customers

Customer management: preparation

Create table

CREATE TABLE `cst_customer` (
  `cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT 'Customer number(Primary key)',
  `cust_name` varchar(32) NOT NULL COMMENT 'Customer name(corporate name)',
  `cust_source` varchar(32) DEFAULT NULL COMMENT 'Customer information source',
  `cust_industry` varchar(32) DEFAULT NULL COMMENT 'Customer industry',
  `cust_level` varchar(32) DEFAULT NULL COMMENT 'Customer level',
  `cust_phone` varchar(64) DEFAULT NULL COMMENT 'fixed telephone',
  `cust_mobile` varchar(16) DEFAULT NULL COMMENT 'Mobile phone',
  PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

Create entities and mappings
 create entity
 create mapping

//entity
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;
//mapping
<hibernate-mapping>
	<!-- Establish the mapping between class and table -->
	<class name="domain.Customer" table="cst_customer">
		<!-- Primary key field -->
		<id name="cust_id" column="cust_id">
			<generator class="native"/>
		</id>
		<!-- Common attribute fields -->
		<property name="cust_name"/>
		<property name="cust_source"/>
		<property name="cust_industry"/>
		<property name="cust_level"/>
		<property name="cust_phone"/>
		<property name="cust_mobile"/>
		<!-- set label: name<->The attribute name of more than one party in this object -->
		<!-- <set name="linkMans" cascade="save-update,delete" batch-size="4" lazy="false">
			key Label: the foreign key name of one party in more than one party
			<key column="lkm_cust_id"></key>
			one-to-maney: Multi party full path
			<one-to-many class="domain.LinkMan"/>
		</set> -->
	</class>
</hibernate-mapping>

Create Action

Create Service and Dao (same as User)
Configure related classes into Spring (the same as User)
 here are similar practices. Refer to Chapter 1

Jump to add page

Modify left menu page
Method of writing saveUI in Action: jump function

Configure Action jump

Test jump

Import data dictionary (* * *)

What is a data dictionary
The data dictionary is used to standardize specific values and data in some places
Create data dictionary table

CREATE TABLE `base_dict` (
  `dict_id` varchar(32) NOT NULL COMMENT 'data dictionary id(Primary key)',
  `dict_type_code` varchar(10) NOT NULL COMMENT 'Data dictionary category code',
  `dict_type_name` varchar(64) NOT NULL COMMENT 'Data dictionary category name',
  `dict_item_name` varchar(64) NOT NULL COMMENT 'Data dictionary item name',
  `dict_item_code` varchar(10) DEFAULT NULL COMMENT 'Data Dictionary Project(Can be empty)',
  `dict_sort` int(10) DEFAULT NULL COMMENT 'sort field',
  `dict_enable` char(1) NOT NULL COMMENT '1:Use 0:Deactivate',
  `dict_memo` varchar(64) DEFAULT NULL COMMENT 'remarks',
  PRIMARY KEY (`dict_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Relationship analysis between customer table and dictionary table

Create dictionary entities and mappings
 create entity
 create mapping

//entity
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;
//mapping
<hibernate-mapping>
	<!-- Establish the mapping between class and table -->
	<class name="domain.BaseDict" table="base_dict">
		<!-- Primary key field -->
		<id name="dict_id" column="dict_id">
			<generator class="uuid"/>
		</id>
		<!-- Common attribute fields -->
		<property name="dict_type_code"/>
		<property name="dict_type_name"/>
		<property name="dict_item_name"/>
		<property name="dict_item_code"/>
		<property name="dict_sort"/>
		<property name="dict_enable"/>
		<property name="dict_memo"/>
		<!-- If the associated object is not used in the query, you do not need to set it -->
	</class>
</hibernate-mapping>

Modify the relationship mapping between dictionary and customer
 modified the customer's entity
 modify customer mapping

//entity
private Long cust_id;
private String cust_name;
private String cust_phone;
private String cust_mobile;
//Although they are the same object, they are treated as different attributes
private BaseDict cust_source;
private BaseDict cust_industry;
private BaseDict cust_level;
//mapping
<hibernate-mapping>
	<!-- Establish the mapping between class and table -->
	<class name="domain.Customer" table="cst_customer">
		<!-- Primary key field -->
		<id name="cust_id" column="cust_id">
			<generator class="native"/>
		</id>
		<!-- Common attribute fields -->
		<property name="cust_name"/>
		<property name="cust_phone"/>
		<property name="cust_mobile"/>
		<!-- Associated object field -->
		<many-to-one name="cust_source" class="domain.BaseDict" column="cust_source"/>
		<many-to-one name="cust_industry" class="domain.BaseDict" column="cust_industry"/>
		<many-to-one name="cust_level" class="domain.BaseDict" column="cust_level"/>
	</class>
</hibernate-mapping>

Give the mapping file to Spring

Load dictionary data asynchronously on the add page

Create Action, Service and Dao of Dictionary (same as User)
 write DAO
 write Service
 write Action
Give the dictionary class to Spring
Introduce js of jquery (on the add page)

Writing methods for asynchronous loading

<script type="text/javascript">
	$(function(){
		/*
		The page load function executes
		Page loading, asynchronous query dictionary data
		Load customer source
		*/
		$.post("${pageContext.request.contextPath }/baseDict_findByTypeCode",{"dict_type_code":"002"},function(data){
			//Traversing json data
			$(data).each(function(i,n){
				$("#cust_source").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>");
			});
		},"json");
	});
</script>

Write Action

Write Service

Write Dao

Load additional dictionary item data

<script type="text/javascript">
	$(function(){
		/*
		The page load function executes
		Page loading, asynchronous query dictionary data
		Load customer source
		*/
		$.post("${pageContext.request.contextPath }/baseDict_findByTypeCode",{"dict_type_code":"002"},function(data){
			//Traversing json data
			$(data).each(function(i,n){
				$("#cust_source").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>");
			});
		},"json");
		$.post("${pageContext.request.contextPath }/baseDict_findByTypeCode",{"dict_type_code":"001"},function(data){
			//Traversing json data
			$(data).each(function(i,n){
				$("#cust_industry").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>");
			});
		},"json");
		$.post("${pageContext.request.contextPath }/baseDict_findByTypeCode",{"dict_type_code":"006"},function(data){
			//Traversing json data
			$(data).each(function(i,n){
				$("#cust_level").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>");
			});
		},"json");
	});
</script>

Summary: no error is reported when writing the code, and the data is not available. It took more than an hour. The reasons are as follows:
1. When using modelDriver to encapsulate data, it must be instantiated manually
2. When using hibernate for query, the name of java object must be followed by from, not the name of database!
3. Blame yourself for not mastering the basic skills well, resulting in mistakes and wasting a lot of time

Save data to database

Modify add page
 modify table submission action - > Customer_ save
 modify form item name:

Write Action, Service and Dao
Add transaction: @ Transactional

4. CRM comprehensive exercise: customer management paging customer query

Query customer (pagination)

Writing pageBean objects

public class PageBean<T> {
	private Integer curPage;	//Current page
	private Integer pageSize;	//Number of records per page
	private Integer pageCount;	//Number of objects per page
	private Integer totalPage;	//PageCount 
	private Integer totalCount;	//Total number
	private List<T> list;	//Encapsulate per page objects
	public void setPageSize(Integer pageSize) {
		if(pageSize == null)this.pageSize=3;
		else this.pageSize = pageSize;
	}
	public void setTotalPage(Integer totalPage) {
		this.totalPage = totalPage;
	}
	public void setTotalCount(Integer totalCount) {
		this.totalCount = totalCount;
		totalPage = (int) Math.ceil(totalCount*1.0/pageSize*1.0);
	}
	public void setList(List<T> list) {
		this.list = list;
	}
	public Integer getPageSize() {
		return pageSize;
	}
	public Integer getTotalPage() {
		return totalPage;
	}
	public Integer getTotalCount() {
		return totalCount;
	}
	public List<T> getList() {
		return list;
	}
	public Integer getPageCount() {
		return pageCount;
	}
	public void setPageCount(Integer pageCount) {
		this.pageCount = pageCount;
	}
	public Integer getCurPage() {
		return curPage;
	}
	public void setCurPage(Integer curPage) {
		this.curPage = curPage;
	}
}

Modify menu jsp
 modify table submission action - > Customer_ findAll
Write the findAll method in the Action

//Properties passed from the page
private Integer curPage = 1;
private Integer pageSize;
public void setCurPage(Integer curPage) {
	if(curPage==null)curPage=1;
	else this.curPage = curPage;
}
public void setPageSize(Integer pageSize) {
	this.pageSize = pageSize;
}
//Method of paging query of customers
public String findAll(){
	System.out.println("Yes```");
	//It is best to use the DetachedCriteria object (conditional query -- with paging)
	DetachedCriteria criteria = DetachedCriteria.forClass(Customer.class);
	//Call the business layer to query
	PageBean<Customer> pageBean = customerService.findAll(criteria, curPage, pageSize);
	//ServletActionContext.getRequest().setAttribute("pageBean", pageBean);  The reset fails
	ActionContext.getContext().getValueStack().push(pageBean);
	System.out.println(pageBean.getPageSize());
	return "customer_list";
}

Modify Service

@Override
//Method of querying customers by page in the business layer:
public PageBean<Customer> findAll(DetachedCriteria criteria, Integer curPage, Integer pageSize) {
	PageBean<Customer> pageBean = new PageBean<Customer>();
	// Encapsulate current pages:
	pageBean.setCurPage(curPage);
	System.out.println("Here:"+pageSize);
	// Number of records displayed per page:
	pageBean.setPageSize(pageSize);
	// Total number of DAO calls and encapsulated records
	Integer totalCount = dao.getTotalCount(criteria);
	pageBean.setTotalCount(totalCount);
	// Call DAO to query all objects
	List<Customer> list = dao.findAll(criteria, pageBean.getCurPage(), pageBean.getPageSize());
	// Test output
	for (Customer customer : list) {
		System.out.println(customer);
	}
	// Number of encapsulated pages
	pageBean.setPageCount(list.size());
	// Encapsulates the list attribute in the pageBean
	pageBean.setList(list);
	return pageBean;
}

Write Dao

@Override
public Integer getTotalCount(DetachedCriteria criteria) {
	// select count(*) from xxx where condition;
	criteria.setProjection(Projections.rowCount());
	List<Long> findByCriteria = (List<Long>) this.getHibernateTemplate().findByCriteria(criteria);
	if(findByCriteria.size()>0)return findByCriteria.get(0).intValue();
	return 0;
}
@Override
public List<Customer> findAll(DetachedCriteria criteria, Integer curPage, Integer pageSize) {
	criteria.setProjection(null);
	return (List<Customer>) this.getHibernateTemplate().findByCriteria(criteria, (curPage-1)*pageSize, pageSize);
}

struts configuration page Jump

<package name="customer" extends="struts-default" namespace="/">
	<action name="customer_*" class="customerAction" method="{1}">
		<result name="saveUI">/jsp/customer/add.jsp</result>
		<result name="customer_list">/jsp/customer/list.jsp</result>
	</action>
</package>

On the list Display data in JSP (version 1: corresponding to the case where pageBean in action is stored in request, the stored value stack cannot be displayed)

<TR>
	<TD>
		<TABLE id=grid
			style="BORDER-TOP-WIDTH: 0px; FONT-WEIGHT: normal; BORDER-LEFT-WIDTH: 0px; BORDER-LEFT-COLOR: #cccccc; BORDER-BOTTOM-WIDTH: 0px; BORDER-BOTTOM-COLOR: #cccccc; WIDTH: 100%; BORDER-TOP-COLOR: #cccccc; FONT-STYLE: normal; BACKGROUND-COLOR: #cccccc; BORDER-RIGHT-WIDTH: 0px; TEXT-DECORATION: none; BORDER-RIGHT-COLOR: #cccccc"
			cellSpacing=1 cellPadding=2 rules=all border=0>
			<TBODY>
				<TR
					style="FONT-WEIGHT: bold; FONT-STYLE: normal; BACKGROUND-COLOR: #eeeeee; TEXT-DECORATION: none">
					<TD>Customer name</TD>
					<TD>Customer level</TD>
					<TD>Customer source</TD>
					<TD>contacts</TD>
					<TD>Telephone</TD>
					<TD>mobile phone</TD>
					<TD>operation</TD>
				</TR>
				<s:iterator value="#request.pageBean.list">
				<TR
					style="FONT-WEIGHT: normal; FONT-STYLE: normal; BACKGROUND-COLOR: white; TEXT-DECORATION: none">
					<TD><s:property value="cust_name"/></TD>
					<TD><s:property value="cust_level.dict_item_name"/></TD>
					<TD><s:property value="cust_source.dict_item_name"/></TD>
					<TD><s:property value="cust_industry.dict_item_name"/></TD>
					<TD><s:property value="cust_phone"/></TD>
					<TD><s:property value="cust_mobile"/></TD>
					<TD>
					<a href="${pageContext.request.contextPath }/customerServlet?method=edit&custId=<s:property value="cust_id"/>">modify</a>
					&nbsp;&nbsp;
					<a href="${pageContext.request.contextPath }/customerServlet?method=delete&custId=<s:property value="cust_id"/>">delete</a>
					</TD>
				</TR>
				</s:iterator>
			</TBODY>
		</TABLE>
	</TD>
</TR>
<TR>
	<TD><SPAN id=pagelink>
			<DIV style="LINE-HEIGHT: 20px; HEIGHT: 20px; TEXT-ALIGN: right">
				common[<B><s:property value="#request.pageBean.totalCount"/></B>]Records,[<B><s:property value="#request. pageBean. Totalpage "/ > < / b >] page
				,Display per page
				<select name="pageSize">
					<option value="3" <s:if test="%{#request.pageBean.pageSize==3}">selected="selected"</s:if>>3</option>
					<option value="5" <s:if test="%{#request.pageBean.pageSize==5}">selected="selected"</s:if>>5</option>
					<option value="10" <s:if test="%{#request.pageBean.pageSize==10}">selected="selected"</s:if>>10</option>
				</select>
				strip
				[<A name="curPage" href="javascript:to_page(<s:property value="#request. pageBean. Curpage "/ > - 1)" > previous page < / a >]
				<B><s:property value="#request.pageBean.curPage"/></B>
				[<A name="curPage" href="javascript:to_page(<s:property value="#request. pageBean. Curpage "/ > + 1)" > next page < / a >] 
				reach
				<input type="text" size="3" id="page" name="curPage" />
				page
				<input type="button" value="Go" onclick="to_page()"/>
			</DIV>
	</SPAN></TD>
</TR>

On the list Display data in JSP (version 2: corresponding to the case where pageBean in action is stored in the value stack)

<TR>
	<TD>
		<TABLE id=grid
			style="BORDER-TOP-WIDTH: 0px; FONT-WEIGHT: normal; BORDER-LEFT-WIDTH: 0px; BORDER-LEFT-COLOR: #cccccc; BORDER-BOTTOM-WIDTH: 0px; BORDER-BOTTOM-COLOR: #cccccc; WIDTH: 100%; BORDER-TOP-COLOR: #cccccc; FONT-STYLE: normal; BACKGROUND-COLOR: #cccccc; BORDER-RIGHT-WIDTH: 0px; TEXT-DECORATION: none; BORDER-RIGHT-COLOR: #cccccc"
			cellSpacing=1 cellPadding=2 rules=all border=0>
			<TBODY>
				<TR
					style="FONT-WEIGHT: bold; FONT-STYLE: normal; BACKGROUND-COLOR: #eeeeee; TEXT-DECORATION: none">
					<TD>Customer name</TD>
					<TD>Customer level</TD>
					<TD>Customer source</TD>
					<TD>contacts</TD>
					<TD>Telephone</TD>
					<TD>mobile phone</TD>
					<TD>operation</TD>
				</TR>
				<s:iterator value="list">
				<TR
					style="FONT-WEIGHT: normal; FONT-STYLE: normal; BACKGROUND-COLOR: white; TEXT-DECORATION: none">
					<TD><s:property value="cust_name"/></TD>
					<TD><s:property value="cust_level.dict_item_name"/></TD>
					<TD><s:property value="cust_source.dict_item_name"/></TD>
					<TD><s:property value="cust_industry.dict_item_name"/></TD>
					<TD><s:property value="cust_phone"/></TD>
					<TD><s:property value="cust_mobile"/></TD>
					<TD>
					<a href="${pageContext.request.contextPath }/customer_edit?cust_id=<s:property value="cust_id"/>">modify</a>
					&nbsp;&nbsp;
					<a href="${pageContext.request.contextPath }/customer_delete?cust_id=<s:property value="cust_id"/>">delete</a>
					</TD>
				</TR>
				</s:iterator>
			</TBODY>
		</TABLE>
	</TD>
</TR>
<TR>
	<TD><SPAN id=pagelink>
			<DIV style="LINE-HEIGHT: 20px; HEIGHT: 20px; TEXT-ALIGN: right">
				common[<B><s:property value="totalCount"/></B>]Records,[<B><s:property value="totalPage"/></B>]page
				,Display per page
				<select name="pageSize" onchange="to_page()">
					<option value="3" <s:if test="pageSize==3">selected="selected"</s:if>>3</option>
					<option value="5" <s:if test="pageSize==5">selected="selected"</s:if>>5</option>
					<option value="10" <s:if test="pageSize==10">selected="selected"</s:if>>10</option>
				</select>
				strip
				<s:if test="curPage!=1">
					[<A name="curPage" href="javascript:to_page(<s:property value="curPage"/>-1)">next page before</A>]
				</s:if>
				<B><s:property value="curPage"/></B>
				<s:if test="curPage!=totalPage">
					[<A name="curPage" href="javascript:to_page(<s:property value="curPage"/>+1)">Next page</A>] 
				</s:if>
				reach
				<input type="text" size="3" id="page" name="curPage" />
				page
				<input type="button" value="Go" onclick="to_page()"/>
			</DIV>
	</SPAN></TD>
</TR>

be careful:
1. Here, due to the forgetting of struts 2, I am not very familiar with the writing method of forced parsing of s:if. When forced parsing, I should unload these judgments in {}
2. A problem I always encounter when writing is that when I jump to the page, the drop-down box always displays 10 items per page, because selected is written outside s:if, because selected has only one value, that is, selected, so it can't be written outside, it should be written inside
3. The meaning of various properties of pageBean, such as pageCount and pageSize, is difficult to confuse
4. To configure the filter of InView, if it is not configured, information cannot be displayed asynchronously
5. The object of offline query runs through to the end, so after statistical query, you must clear the statistical query conditions and then check other things
6. As long as it's an error that can't get in the web page, look at ApplicationContext first Whether there are errors in XML, and then check them in turn

Topics: Hibernate Spring ssh crm struts2