喜歡就點個讚唄!
GitHub項目 ssm-learn-crm
show me the code and take to me,作的出來更要說的明白
git clone https://github.com/buerbl/ssm-learn-crm.git
咱們須要作一個客戶系統,使用者能夠在系統上面保存、編輯、刪除、客戶信息。javascript
此次咱們選擇 ssm 三大框架搭建系統的後端,前端頁面的話用 JSP 以及 JQuery EasyUI;數據庫使用 MySQL;項目構想使用 Maven 工具。css
技術 | 做用 |
---|---|
Spring | 管理對象,管理事務等 |
SpringMVC | 路徑跳轉,請求訪問等 |
Mybatis | 數據獲取等 |
JQuery EasyUI | 頁面展現等 |
MySQL | 存取數據等 |
IDEA | 快速寫代碼等 |
Navicat | 數據庫可視化軟件 |
咱們須要保存客戶的名字、性別、聯繫方式和地址,所以咱們的數據庫腳本以下html
CREATE table t_customer( id int PRIMARY KEY auto_increment, name VARCHAR(20), gender char(1), telephone VARCHAR(20), address VARCHAR(50) );
一次性導入咱們須要的jar,依賴以下前端
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.3.RELEASE</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.4.2</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.26</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>4.3.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.3.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.3.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.3.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>4.3.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>4.3.3.RELEASE</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.3</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.3.3.RELEASE</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.12</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.6.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.6.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.6.0</version> </dependency> </dependencies>
可能當咱們編譯的時候,咱們發現 webapp 的文件並無編譯進來,咱們須要在 pom.xml 中加入以下,告訴 Mavne 須要編譯特定文件。java
<build> <resources> <resource> <directory>src/main/webapp</directory> <filtering>true</filtering> </resource> </resources> </build>
來到這裏的話,咱們須要創建文件夾,準備開始寫代碼。通常按照套路的話,我喜歡以下的規則mysql
文件夾 | 做用 |
---|---|
controller | 控制層代碼 |
domain | 實體類代碼 |
dao | Mapper代碼 |
service | 服務層代碼 |
咱們根據數據庫字段編寫實體類代碼,代碼以下,我使用了 lombok 框架,這個東西須要 IDEA 安裝一個 lombok 插件。jquery
package com.buer.domain; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; import lombok.ToString; /** * @Description: * @Author: boolean * @Date: 2019/12/22 11:51 */ @Getter @Setter @ToString @AllArgsConstructor public class Customer { private Integer id; private String name; private String gender; private String telephone; private String address; }
有個問題,這些字段是怎樣和數據庫字段一一對應的呢?下面揭曉。git
這裏咱們須要的 Mybatis 要上場了,首先咱們須要以下Mapper代碼github
package com.buer.dao; import com.buer.domain.Customer; import java.util.List; public interface CustomerMapper { /** * 添加客戶 */ void saveCustomer(Customer customer); /** * 查詢全部客戶 * @return */ List<Customer> list(); /*** * 查找某個客戶 * @param id * @return */ Customer findById(Integer id); }
有了 Mapper 代碼,咱們須要給 Mapper 配上相應的 xml 文件。以下web
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- 該文件編寫mybatis中的mapper接口裏面的方法提供對應的sql語句 --> <mapper namespace="com.buer.dao.CustomerMapper"> <!-- 添加客戶 --> <insert id="saveCustomer" parameterType="com.buer.domain.Customer"> INSERT INTO ssm.t_customer ( NAME, gender, telephone, address ) VALUES ( #{name}, #{gender}, #{telephone}, #{address} ) </insert> <select id="list" resultType="com.buer.domain.Customer"> select * from t_customer </select> <select id="findById" resultType="com.buer.domain.Customer"> select * from t_customer where id = #{id} </select> </mapper>
解答上面的問題,實體類字段是怎樣和數據庫字段一一對應,經過 resultType 來自動映射。
先來接口層的代碼。代碼以下
package com.buer.service; import com.buer.domain.Customer; import java.util.List; public interface IcustomerService { /** * 添加客戶 */ void saveCustomer(Customer customer); /** * 返回全部數據 * @return */ List<Customer> list(); /** * 修數據 * @return */ Customer findById(Integer id); }
而後實現接口,代碼以下
package com.buer.service.Impl; import com.buer.dao.CustomerMapper; import com.buer.domain.Customer; import com.buer.service.IcustomerService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.List; /** * @Description: * @Author: boolean * @Date: 2019/12/22 18:28 */ @Service("customerService") public class IcustomerServiceImpl implements IcustomerService { @Resource private CustomerMapper customerMapper; @Override @Transactional public void saveCustomer(Customer customer) { customerMapper.saveCustomer(customer); } @Override public List<Customer> list() { return customerMapper.list(); } @Override public Customer findById(Integer id) { return customerMapper.findById(id); } }
這裏咱們看到@Service("customerService")
,@Resource
, @Transactional
,這些註解他們的做用是啥子哦?請看下面
註解 | 做用 |
---|---|
@Service("customerService") | 告訴 Spring, 這是一個叫 customerService 的東西,你要照顧好她,給他在初始化的時候建立一個對象。 |
@Resource | Java裏面的註解,注入對象 |
@Transactional | 告訴 Spring,須要開始事務 |
這裏就是 SpringMVC 的舞臺了。代碼以下
package com.buer.controller; import com.buer.domain.Customer; import com.buer.service.IcustomerService; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; import java.util.List; /** * @Description: * @Author: boolean * @Date: 2019/12/22 18:50 */ @Controller @RequestMapping("/customer") public class CustomerController { @Resource private IcustomerService service; @RequestMapping("/index") public String test(){ System.out.println("ssss"); return "index"; } @RequestMapping("/save") public String save(Customer customer){ System.out.println("save"); service.saveCustomer(customer); return "success"; } @RequestMapping("/list") @ResponseBody public List<Customer> list(){ System.out.println("list"); return service.list(); } @RequestMapping("/findById") @ResponseBody public Customer findById(Integer id){ System.out.println("findById"); return service.findById(id); } }
註解 | 做用 |
---|---|
@Controller | 告訴 SpringMVC, 這是你負責的代碼 |
@RequestMapping("/save") | 告訴 SpringMVC,用 「/save」路徑訪問 |
@ResponseBody | 告訴 SpringMVC,須要返回JSON |
以上就是代碼的編寫,可是尚未完成哈,咱們須要一些配置文件。
咱們要鏈接數據庫,代碼以下
jdbc.url=jdbc:mysql://localhost:3306/ssm jdbc.driverClass=com.mysql.jdbc.Driver jdbc.user=root jdbc.password=123456
咱們要告訴 Spring 鏈接數據庫,以及咱們寫的代碼在哪裏,怎麼去操做咱們的代碼。代碼以下
<?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"> <!-- 讀取jdbc.properties --> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 建立DataSource --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="url" value="${jdbc.url}"/> <property name="driverClassName" value="${jdbc.driverClass}"/> <property name="username" value="${jdbc.user}"/> <property name="password" value="${jdbc.password}"/> <property name="maxActive" value="10"/> <property name="maxIdle" value="5"/> </bean> <!-- 建立SqlSessionFactory對象 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 關聯鏈接池 --> <property name="dataSource" ref="dataSource"/> <!-- 加載mapper.xml --> <property name="mapperLocations" value="classpath:mapper/*.xml"/> </bean> <!-- Mapper全部接口的掃描 --> <!--注意:若是使用Mapper接口包掃描,那麼每一個Mapper接口在Spring容器中的id名稱爲類名: 例如 CustomerMapper -> customerMapper--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 配置Mapper接口所在包路徑 --> <property name="basePackage" value="com.buer.dao"></property> </bean> <!-- 開啓Spring的IOC註解掃描 --> <context:component-scan base-package="com.buer"/> <!-- 開啓Spring的事務 --> <!-- -事務管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 啓用Spring事務註解 --> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>
咱們須要告訴 SpringMVC,他須要的代碼在哪裏,怎麼去操做咱們的代碼
咱們須要啓動項目了,以及一些字體指定。代碼以下
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>01.mybatis</display-name> <!-- 配置SpringMVC編碼過濾器 --> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 啓動SpringMVC --> <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 參數:讀取spring-mvc.xml --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> <!-- 啓動spring --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 修改路徑 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> </web-app>
這裏的話,後端就搭起來了。
咱們須要編寫首頁,代碼以下
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>booleanbl 公衆號 客戶關係管理系統</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <script type="text/javascript" src="easyui/jquery.min.js"></script> <script type="text/javascript" src="easyui/jquery.easyui.min.js"></script> <script type="text/javascript" src="easyui/locale/easyui-lang-zh_CN.js"></script> <link rel="stylesheet" type="text/css" href="easyui/themes/icon.css"> <link id="themeLink" rel="stylesheet" type="text/css" href="easyui/themes/default/easyui.css"> <style type="text/css"> ul{ line-height: 30px; } </style> </head> <body class="easyui-layout"> <!-- 頂部 --> <div data-options="region:'north',split:true" style="height:80px;"> <!-- logo --> <div id="logo"> <img src="images/20191223003101.png"/> </div> <!-- 登陸用戶信息 --> <div id="loginDiv" style="position: absolute;right: 20px;top: 20px;"> 歡迎你,[超級管理員],你使用[192.156.21.22]IP登陸! </div> <div id="themesDiv" style="position: absolute;right: 20px;top:40px;"> <a href="javascript:void(0)" id="mb" class="easyui-menubutton" data-options="menu:'#Themesmeus',iconCls:'icon-edit'">切換風格</a> <div id="Themesmeus" style="width:150px;"> <div>default</div> <div>gray</div> <div>black</div> <div>bootstrap</div> <div>material</div> <div>metro</div> </div> </div> </div> <!-- 底部 --> <div data-options="region:'south',split:true" style="height:30px;"> <div id="copyrightDiv" style="text-align: center;"> booleanbl出品©2018版權全部 </div> </div> <!-- 左邊系統菜單 --> <div data-options="region:'west',title:'系統菜單',split:true" style="width:200px;"> <div id="aa" class="easyui-accordion" style="width:193px;" data-options="border:0,multiple:true" > <div title="系統管理" data-options="iconCls:'icon-reload',selected:true" style="padding:10px;"> <ul> <li><a href="javascript:void(0)" pageUrl="customer_manage.jsp">客戶管理</a></li> </ul> </div> </div> </div> <!-- 中間編輯區域 --> <div data-options="region:'center'" style="padding:5px;background:#eee;"> <div id="tt" class="easyui-tabs" style="width:500px;height:250px;" data-options="fit:true"> <div title="起始頁" style="padding:20px;display:none;"> 歡迎登陸booleanbl客戶關係管理系統 </div> </div> </div> <script type="text/javascript"> $(function(){ //給a標籤綁定時間 $("a[pageUrl]").click(function(){ //1.獲取pageUrl屬性值(須要跳轉的頁面地址) var pageUrl = $(this).attr("pageUrl"); //獲取a標籤的內容,標題 var title = $(this).text(); //2.判斷是否存在指定標題的選項卡 if( $("#tt").tabs("exists",title) ) { //3.若是存在,則選項該選項卡 $("#tt").tabs("select",title); }else{ //4.若是不存在,則添加選項卡 $("#tt").tabs("add",{ title:title, content:"<iframe src='"+pageUrl+"' width='100%' height='100%' frameborder='0'><iframe>", closable:true }); } }); //點擊切換模塊菜單的時候,進行切換模塊 $("#Themesmeus").menu({ onClick:function(item){ //1.獲取須要改變的模塊名稱 var themeName = item.text; //2.獲取link標籤的href屬性 var href= $("#themeLink").attr("href"); //3.更改href的屬性值 // easyui/themes/default/easyui.css href = href.substring(0,href.indexOf("themes"))+"themes/"+themeName+"/easyui.css"; //4.更新link的href屬性 $("#themeLink").attr("href",href); } }); }); </script> </body> </html>
咱們須要詳情頁,代碼以下
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>客戶管理</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- 導入easyui的資源文件 --> <script type="text/javascript" src="easyui/jquery.min.js"></script> <script type="text/javascript" src="easyui/jquery.easyui.min.js"></script> <script type="text/javascript" src="easyui/locale/easyui-lang-zh_CN.js"></script> <link rel="stylesheet" type="text/css" href="easyui/themes/icon.css"> <link id="themeLink" rel="stylesheet" type="text/css" href="easyui/themes/default/easyui.css"> </head> <body> <table id="list"></table> <!-- 工具條 --> <div id="tb"> <a id="addBtn" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-add',plain:true">添加</a> <a id="editBtn" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-edit',plain:true">修改</a> <a id="deleteBtn" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-remove',plain:true">刪除</a> </div> <!-- 編輯窗口 --> <div id="win" class="easyui-window" title="客戶數據編輯" style="width:500px;height:300px" data-options="iconCls:'icon-save',modal:true,closed:true"> <form id="editForm" method="post"> <%--提供id隱藏域 --%> <input type="hidden" name="id"> 客戶姓名:<input type="text" name="name" class="easyui-validatebox" data-options="required:true"/><br/> 客戶性別: <input type="radio" name="gender" value="男"/>男 <input type="radio" name="gender" value="女"/>女 <br/> 客戶手機:<input type="text" name="telephone" class="easyui-validatebox" data-options="required:true"/><br/> 客戶住址:<input type="text" name="address" class="easyui-validatebox" data-options="required:true"/><br/> <a id="saveBtn" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-save'">保存</a> </form> </div> <script type="text/javascript"> $(function(){ $("#list").datagrid({ //url:後臺數據查詢的地址 url:"customer/list.action", //columns:填充的列數據 //field:後臺對象的屬性 //tille:列標題 columns:[[ { field:"id", title:"客戶編號", width:100, checkbox:true }, { field:"name", title:"客戶姓名", width:200 }, { field:"gender", title:"客戶性別", width:200 }, { field:"telephone", title:"客戶手機", width:200 }, { field:"address", title:"客戶住址", width:200 } ]], //顯示分頁 pagination:true, //工具條 toolbar:"#tb" }); //打開編輯窗口 $("#addBtn").click(function(){ //清空表單數據 $("#editForm").form("clear"); $("#win").window("open"); }); //保存數據 $("#saveBtn").click(function(){ $("#editForm").form("submit",{ //url: 提交到後臺的地址 url:"customer/save.action", //onSubmit: 表單提交前的回調函數,true:提交表單 false:不提交表單 onSubmit:function(){ //判斷表單的驗證是否都經過了 return $("#editForm").form("validate"); }, //success:服務器執行完畢回調函數 success:function(data){ //data: 服務器返回的數據,類型字符串類 //要求Controller返回的數據格式: //成功:{success:true} 失敗:{success:false,msg:錯誤信息} //把data字符串類型轉換對象類型 data = eval("("+data+")"); if(data.success){ //關閉窗口 $("#win").window("close"); //刷新datagrid $("#list").datagrid("reload"); $.messager.alert("提示","保存成功","info"); }else{ $.messager.alert("提示","保存失敗:"+data.msg,"error"); } } }); }); //修改數據 $("#editBtn").click(function(){ //判斷只能選擇一行 var rows = $("#list").datagrid("getSelections"); if(rows.length!=1){ $.messager.alert("提示","修改操做只能選擇一行","warning"); return; } //表單回顯 $("#editForm").form("load","customer/findById.action?id="+rows[0].id); $("#win").window("open"); }); //刪除 $("#deleteBtn").click(function(){ var rows =$("#list").datagrid("getSelections"); if(rows.length==0){ $.messager.alert("提示","刪除操做至少選擇一行","warning"); return; } //格式: id=1&id=2&id=3 $.messager.confirm("提示","確認刪除數據嗎?",function(value){ if(value){ var idStr = ""; //遍歷數據 $(rows).each(function(i){ idStr+=("id="+rows[i].id+"&"); }); idStr = idStr.substring(0,idStr.length-1); //傳遞到後臺 $.post("customer/delete.action",idStr,function(data){ if(data.success){ //刷新datagrid $("#list").datagrid("reload"); $.messager.alert("提示","刪除成功","info"); }else{ $.messager.alert("提示","刪除失敗:"+data.msg,"error"); } },"json"); } }); }); }); </script> </body> </html>
緣由是沒有轉換json返回
@ResponseBody