使用Maven構(gòu)建 基于SpringMVC+Spring+Mybatis(SSM)高效便捷開發(fā)框架

本項目是一個整合 SpringMVC+Spring+MyBatis(SSM) 框架的 Demo。提供視頻部署教程

擁有高效率便捷開發(fā)模式,使開發(fā)人員更專注于業(yè)務(wù),達(dá)到面向業(yè)務(wù)開發(fā)。

項目使用 Maven 構(gòu)建,便于項目管理,支持 Oracle、MySql 等主流數(shù)據(jù)庫。

前端展示界面采用基于 Boostrap 實現(xiàn)的響應(yīng)式布局,并集成了一系列的動畫效果插件,整體界面簡潔、美觀大方并可優(yōu)雅的與后臺完成交互操作。

項目封裝了一系列常用方法、部署運(yùn)行簡單,便于個人或企業(yè)進(jìn)行高效開發(fā)。

項目已提交至Github請前往https://github.com/micyo202/yan-demo查看詳情。

一、項目開發(fā)環(huán)境&工具(Environment&Tools)

  • MacOS Sierra / Windows 7
  • MySql 5.7
  • JDK 1.8
  • CentOS 7
  • IntelliJ IDEA 2017.2.5 / Eclipse 4.6.1
  • Navicat Premium 11.1.12
  • Maven 3.3.9
  • Jetty 9.4.6.v20170531 / Tomcat 9.0

二、Maven配置(pom.xml)

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.yan</groupId>
    <artifactId>yan_demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    
    <name>yan_demo</name>
    <description>基于 SpringMVC+Spring+Mybatis 開發(fā)的 Yan Frame Demo.</description>
    
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.framework.version>4.3.11.RELEASE</spring.framework.version>
        <aspectj.version>1.8.10</aspectj.version>
        <shiro.version>1.4.0</shiro.version>
        <jackson.version>2.9.1</jackson.version>
        <logback.version>1.2.3</logback.version>
    </properties>
    
    <dependencies>
        <!-- 添加 junit 依賴包 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version> 
            <scope>test</scope>
        </dependency>
        
        <!-- 添加 commons 依賴包 -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.3</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.6</version>
        </dependency>

        <!-- 添加 spring 依賴包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.framework.version}</version>
            <scope>test</scope>
        </dependency>

        <!-- 添加 aspectJ 依賴包 -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
        
        <!-- 添加 shiro 依賴包 -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>${shiro.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-web</artifactId>
            <version>${shiro.version}</version>
        </dependency>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring</artifactId>
        <version>${shiro.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-quartz</artifactId>
        <version>${shiro.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-ehcache</artifactId>
        <version>${shiro.version}</version>
    </dependency>
        
        <!-- 添加 mybatis 依賴包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.1</version>
        </dependency>
        
        <!-- 添加 mybatis 分頁插件 -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.1.1</version>
        </dependency>
         
        <!-- 添加 druid 依賴包 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.3</version>
        </dependency>
         
        <!-- 添加 mysql 驅(qū)動 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.44</version>
        </dependency>

        <!-- 添加 jackson 依賴包 -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        
        <!-- 添加 servlet 依賴包 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        
        <!-- 添加 jstl 依賴包 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        
        <!-- 添加 log 依賴包 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
        </dependency>
        
        <!-- 添加 dom4j 依賴包(用于解析 xml)-->
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>

    </dependencies>
    
    <build>
        <plugins>
            <!-- 添加 jetty 插件(命令運(yùn)行方式:進(jìn)入工程目錄執(zhí)行:mvn jetty:run 啟動服務(wù)) -->
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.4.6.v20170531</version>
                <configuration>
                    <!-- 指定監(jiān)控的掃描時間間隔,0為關(guān)閉jetty自身的熱部署 -->
                    <scanIntervalSeconds>0</scanIntervalSeconds>
                    <webAppConfig>
                        <contextPath>/yan_demo</contextPath>
                    </webAppConfig>
                    <httpConnector>
                        <port>8888</port>
                    </httpConnector>
                </configuration>
            </plugin>
            
            <!-- 添加 mybatis-generator 插件(命令運(yùn)行方式:進(jìn)入工程目錄執(zhí)行:mvn mybatis-generator:generate 生成代碼) -->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.5</version>
            </plugin>
            
        </plugins>
    </build>
    
</project>

三、項目結(jié)構(gòu)(Construction)

  • com.yan.common:通用功能模塊(包含:用戶登錄、菜單、后臺管理等...)
  • com.yan.core:框架核心模塊(包括基礎(chǔ)的控制器、過濾器、攔截器、類加載器、注入器、注解、以及框架封裝的核心方法部分)
  • com.yan.demo:業(yè)務(wù)模塊(根據(jù)實際項目名稱換掉demo名稱,所有業(yè)務(wù)模塊均在該路徑下)
  • com.yan.**.controller:控制器路徑,存放自己編寫業(yè)務(wù)處理的控制器(繼承BaseController)
  • com.yan.**.mapper:持久層映射接口類路徑(mbg生成mybatis對應(yīng)的Mapper映射接口類)
  • com.yan.**.model:模型類路徑(mbg生成的模型以及自定義模型)
  • com.yan.junit:單元測試模塊(便于撰寫單元測試代碼)
  • resources/database:數(shù)據(jù)庫sql文件(數(shù)據(jù)庫表結(jié)構(gòu)的*.sql文件,包含Yan Frame框架所需的基本系統(tǒng)數(shù)據(jù)表,如:用戶表、權(quán)限表、菜單表等...)
  • resources/mybatis:mapper映射文件(所有mybatis的sql模板*.xml文件)
  • resources/properties:配置文件(如:系統(tǒng)基本配置、數(shù)據(jù)庫配置、日志配置、MyBatis generator配置)
  • resources/spring:spring的配置文件(命名規(guī)范:spring-*.xml)
  • webapp/common:公共路徑(前臺框架的通用*.jsp頭文件,頁面僅需引入這里面對應(yīng)的jsp即可)
  • webapp/resources:靜態(tài)資源路徑(包含了js、css、images、doc、plugins等)
  • webapp/views:視圖路徑(所有業(yè)務(wù)功能的*.jsp頁面)

四、常用方法(Methods)

方法均在繼承于BaseController的類中使用this.metodName;進(jìn)行調(diào)用(其中methodName代表需要調(diào)用的方法名稱)
方法名 參數(shù) 返回值 描述
getSession HttpSession 服務(wù)器會話 獲取服務(wù)器會話 session 對象
setSession session 服務(wù)器會話 設(shè)置服務(wù)器會話 session 對象
getRequest HttpServletRequest 用戶請求 獲取用戶請求 request 對象
setRequest request 用戶請求 設(shè)置用戶請求 request 對象
getResponse HttpServletResponse 服務(wù)器響應(yīng)結(jié)果 獲取服務(wù)器響應(yīng)結(jié)果 response 對象
setResponse response 服務(wù)器響應(yīng)結(jié)果 設(shè)置服務(wù)器響應(yīng)結(jié)果 response 對象
getSessionUser TbSysUser 用戶對象 獲取登錄成功后 session 中的存儲的用戶信息
getMapper type 生成的 Mapper 接口對象類型 T 泛型,傳入?yún)?shù)對象的類型Mapper 獲取 mapper 對象
getMapper DelegateMapper 通用 mapper,查看自定義 sqlMap 的代理 mapper 對象 獲取 delegateMapper 對象
setDataSource dataSource 數(shù)據(jù)源名稱(必須是spring配置中包含的名稱) 動態(tài)切換數(shù)據(jù)源方法,設(shè)置數(shù)據(jù)源名稱
clearDataSource 清除數(shù)據(jù)源,在切換完數(shù)據(jù)源后,進(jìn)行清理,將數(shù)據(jù)源還原為默認(rèn)數(shù)據(jù)源
offsetPage offset 起始數(shù)量;limit 限制條數(shù) 分頁查詢范圍,參數(shù)均由 bootstrapTable 分頁插件進(jìn)行傳入,無需人工控制,只需調(diào)用方法即可
resultPage list 查詢到的分頁結(jié)果,為 Page 對象 PageModel<T> 自定義的分頁模型,T 為查詢的對象 分頁結(jié)果集對象
resultMsg status 狀態(tài)值(可根據(jù)需求任意設(shè)置,無強(qiáng)制標(biāo)準(zhǔn));msg 消息內(nèi)容;res 返回的對象 MsgModel 自定義消息模型 消息返回對象
fileUpLoad request 上傳方法中傳遞的 request 對象,并非父類中的 request 對象 List<String> 上傳文件成功后的新文件名稱,以集合形式返回 文件上傳方法,支持多個文件上傳
fileDownLoad fileName 需要下載的文件名稱 ResponseEntity<byte[]> 下載的文件,在瀏覽器會進(jìn)行下載 文件下載方法
isNull obj 需要進(jìn)行判斷的對象 boolean 為null或空返回 true,否則返回 false 判斷對象是否為null,或空
obj2Str obj 需要轉(zhuǎn)換的對象 String 對象的值(為null則返回"") 對象轉(zhuǎn)換為 String,通常用于獲取 Map 集合中的對象時使用
getUUID String 32位主鍵字符串 生成 uuid 主鍵,長度為32位,且為大寫模式
base64Encoder str 需要進(jìn)行編碼的字符串 String 進(jìn)行編碼后的結(jié)果字符串 對字符串進(jìn)行 base64 編碼
base64Decoder str 已進(jìn)行 base64 編碼的編碼字符串 String 解碼后的原字符串 對字符串進(jìn)行 base64 解碼
md5 str 需要進(jìn)行 md5 加密的字符串 String 加密后的結(jié)果 對字符串進(jìn)行 md5 加密算法
currentDate pattern 獲取系統(tǒng)時間的格式,如:yyyy-MM-dd HH:mm:ss String 返回格式化后的當(dāng)前時間 獲取系統(tǒng)當(dāng)前時間
timeStamp2Date timestamp 需要進(jìn)行轉(zhuǎn)換的時間戳;pattern 轉(zhuǎn)換后的格式 String 格式化后的日期 時間戳轉(zhuǎn)換成日期
date2TimeStamp dateStr 需要進(jìn)行轉(zhuǎn)換的日期字符串;pattern 日期的格式 String 轉(zhuǎn)換后的時間戳 日期轉(zhuǎn)換為時間戳
readFromFile filePath 文件路徑(絕對路徑) String 讀取的文件內(nèi)容 從指定文件中讀取文件內(nèi)容
writeToFile content 需要寫入文件中的內(nèi)容 filePath 文件路徑(絕對路徑) 將內(nèi)容寫入到指定文件中(寫入會覆蓋文件原有內(nèi)容,建議先讀取,再寫入,將讀取的內(nèi)容與需要寫入的內(nèi)容并在一起進(jìn)行寫入)
generatePath path 文件夾路徑(絕對路徑) 生成指定路徑文件夾,先進(jìn)行判斷文件夾是否存在,若不存在則創(chuàng)建對應(yīng)目錄的文件夾,若存在則不進(jìn)行任何操作
generateFile path 文件路徑(絕對路徑) 生成指定路徑的文件,先進(jìn)行判斷文件是否存在,若不存在則進(jìn)行創(chuàng)建文件,若存在則不進(jìn)行任何操作
propertiesValue key 資源文件中的 key 值 String 讀取到的 key 對應(yīng)的 value 值 讀取 properties 文件中的值,讀取 classpath 下 /properties/config.properties 配置文件
propertiesValue resource 資源文件路徑(對應(yīng) classpath 中的路徑);key 資源文件中的 key 值 String 讀取到的 key 對應(yīng)的 value 值 讀取指定路徑 properties 文件中的值,會從 classpath 路徑下進(jìn)行查找資源文件

五、示例代碼(Codes)

創(chuàng)建一個繼承與BaseController的控制器
@Controller
public class XxxController extends BaseController {
    ...
}
獲取日志日志記錄Logger對象
// 使用注解獲取
@LogInject
private static Logger log;

// 使用工廠方法獲取
private static Logger log = LoggerFactory.getLogger(XxxController.class);
獲取mapper對象
// 注解方式獲取delegateMapper
@MapperInject
private DelegateMapper delegateMapper;
// 注解方式獲取對象對應(yīng)的mapper
@MapperInject(XxxMapper.class)
private XxxMapper mapper;

// 獲取delegateMapper
this.getMapper();
// 獲取對象對應(yīng)的mapper
this.getMapper(XxxMapper.class);
動態(tài)切換數(shù)據(jù)源
// 注解切換數(shù)據(jù)源,默認(rèn)切換擴(kuò)展數(shù)據(jù)源
@DynamicDataSource
public String init(){
    ...
}

// 注解切換數(shù)據(jù)源,傳入ENUM類型的數(shù)據(jù)源名稱
@DynamicDataSource(DataSourceName.EXTEND)
public String init(){
    ...
}

// 調(diào)用父類方法執(zhí)行切換數(shù)據(jù)源(參數(shù)名稱建議使用框架中已經(jīng)定義好的,DataSourceName.DEFAULT/EXTEND.getName())
this.setDataSource("extendDataSource");
    ...
this.clearDataSource();
分頁查詢后臺代碼
@RequestMapping("/list")
@ResponseBody
public PageModel<Xxx> list(int offset, int limit) {
    // 調(diào)用父類方法傳入分頁參數(shù)
    this.offsetPage(offset, limit);
    List<Xxx> list = mapper.selectByExample(null); // 調(diào)用查詢方法
    return this.resultPage(list);
}
分頁查詢前臺代碼
<table id="table"><table>

$('#table').bsTable({
        url: '${pageContext.request.contextPath}/xxx/list',
        idField: 'id',
        columns: [
            {field: 'state', checkbox: true},
            {field: 'id', title: 'id', align: 'center'},
            ...
            ]
    });
文件上傳
@RequestMapping("/upload")
public String upload(HttpServletRequest request) {
    // 調(diào)用父類的上傳方法,在jsp中必須指定form為enctype="multipart/form-data"
    List<String> fileNames = this.fileUpLoad(request);
    return "success";
}
文件下載(在jsp頁面使用通用的下載方法,使用restful風(fēng)格)
<a href="${pageContext.request.contextPath}/文件名稱/download">文件下載</a>
自定義文件下載后臺方法
@RequestMapping("/download")
public ResponseEntity<byte[]> download(String fileName) {
    // 調(diào)用父類文件下載方法
    return this.fileDownLoad(fileName);
}
常用DelegateMapper及對象Mapper方法
// 使用自定義sql模板查詢單個對象
Demo demo = delegateMapper.selectOne(statement);
Demo demo = delegateMapper.selectOne(statement, parameter);
        
// 使用自定義sql模板查詢對象集合
List<Demo> list = delegateMapper.selectList(statement);
List<Demo> list = delegateMapper.selectList(statement, parameter);

// 使用自定義sql模板有范圍的查詢,(每次返回指定的對象條數(shù)集合)
List<Demo> list = delegateMapper.selectList(statement, parameter, rowBounds);

// 使用自定義sql模板進(jìn)行分頁查詢
PageModel<Demo> page = delegateMapper.selectPagination(statement, offset, limit);
PageModel<Demo> page = delegateMapper.selectPagination(statement, parameter, offset, limit);

// 使用自定義sql模板保存
int res = delegateMapper.insert(statement);
int res = delegateMapper.insert(statement, parameter);

// 使用自定義sql模板修改
int res = delegateMapper.update(statement);
int res = delegateMapper.update(statement, parameter);

// 使用自定義sql模板刪除
int res = delegateMapper.delete(statement);
int res = delegateMapper.delete(statement, parameter);

// 使用對象方法根據(jù)主鍵查詢
Demo demo = mapper.selectByPrimaryKey(id);

// 使用對象方法根據(jù)criteria查詢
List<Demo> list = mapper.selectByExample(example);

// 使用對象方法根據(jù)criteria分頁查詢
this.offsetPage(offset, limit);
List<Demo> list = mapper.selectByExample(example);
this.resultPage(list); // 返回的結(jié)果集

// 使用對象方法添加
int res = mapper.insert(record);
int res = mapper.insertSelective(record);

// 使用對象方法根據(jù)主鍵修改
int res = mapper.updateByPrimaryKey(record);
int res = mapper.updateByPrimaryKeySelective(record);

// 使用對象方法根據(jù)criteria修改
int res = mapper.updateByExample(record, example);
int res = mapper.updateByExampleSelective(record, example);

// 使用對象方法根據(jù)主鍵刪除
int res = mapper.deleteByPrimaryKey(productCode);

// 使用對象方法刪除根據(jù)criteria刪除
int res = mapper.deleteByExample(example);

更多方法使用請參考項目中API文檔或demo模塊下的代碼

六、效果預(yù)覽(Preview)

login

web

mobile

七、許可證(License)

MIT License

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. 簡介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存儲過程以及高級映射的優(yōu)秀的...
    笨鳥慢飛閱讀 6,282評論 0 4
  • Spring 技術(shù)筆記Day 1 預(yù)熱知識一、 基本術(shù)語Blob類型,二進(jìn)制對象Object Graph:對象圖...
    OchardBird閱讀 1,087評論 0 2
  • SSM框架整合理解 把IntelliJ IDEA+Maven+Spring + SpringMVC + MyBat...
    青年馬土豆閱讀 10,004評論 0 21
  • 公司的手寫板,讓我測試下怎么樣,我臨摹了自己畫過的蝴蝶,只是改了顏色,畫完了,領(lǐng)導(dǎo)問怎么樣,我說挺好用的,還是這個...
    辣媽趙十八閱讀 552評論 8 4
  • 有一群這樣的人,假惺惺,披著羊皮的狼,覺得自己很聰明卻不知自己的所作所為被別人看的很透,只不過不揭穿而已,這個社會...
    在路上的少年閱讀 423評論 0 0

友情鏈接更多精彩內(nèi)容