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> <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> <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