項目:我的博客系統 Part2 框架搭建與基本功能實現

項目:我的博客系統 Part2前端

 

1、框架搭建

搭建Spring + SpringMVC + MyBatis框架java

1.Spring與MyBatis整合

整合Spring與MyBatis;mysql

首先pom注入相應的jar包:git

  <properties>
      <spring.version>4.1.1.RELEASE</spring.version>
  </properties>

    <dependencies>

        <!-- spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
        </dependency>


        <!-- junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>


        <!--Velocity須要的jar包-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-tools</artifactId>
            <version>2.0</version>
        </dependency>

        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!--數據庫鏈接池-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.15</version>
        </dependency>

        <!--MyBatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.3.0</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.2.3</version>
        </dependency>

        <!--log-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.7</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.7</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.7</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>4.1.1</version>
        </dependency>

        <!-- JSTL -->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>

    </dependencies>
View Code

 

而後配置spring-mybatis.xml文件:github

  • 開啓註解,自動掃描包:
        <context:annotation-config/>
        <context:component-scan base-package="com.leng.blogTMY"/>

     

  • 導入數據庫配置文件jdbc.properties:
        <!--導入數據鏈接池配置文件-->
        <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="location" value="classpath:jdbc.properties"/>
            <property name="fileEncoding" value="utf-8"/>
        </bean>

     

  • 配置數據庫鏈接池:
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="${driverClassName}"/>
            <property name="url" value="${url}"/>
            <property name="username" value="${username}"/>
            <property name="password" value="${password}"/>
    
            <!-- 初始化鏈接大小 -->
            <property name="initialSize" value="${initialSize}"/>
            <!-- 鏈接池最大數量 -->
            <property name="maxActive" value="${maxActive}"/>
            <!-- 鏈接池最大空閒 -->
            <property name="maxIdle" value="${maxIdle}"/>
            <!-- 鏈接池最小空閒 -->
            <property name="minIdle" value="${minIdle}"/>
            <!-- 獲取鏈接最大等待時間 -->
            <property name="maxWait" value="${maxWait}"/>
        </bean>

     

  • 配置sqlSessionFactory,掃描mapper包的xml文件:
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            <!--<property name="mapperLocations" value="classpdaopper/*.xml"/>-->
            <property name="mapperLocations" value="classpath:mapper/*.xml" />
            <property name="typeAliasesPackage" value="com.leng.blogTMY.model"/>
            <property name="plugins">
                <array>
                    <bean class="com.github.pagehelper.PageHelper">
                        <property name="properties">
                            <value>
                                reasonable=true
                            </value>
                        </property>
                    </bean>
                </array>
            </property>
        </bean>

     

  • 掃描dao接口:
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="com.leng.blogTMY.dao"/>
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        </bean>

     

  • 配置事務管理:
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
        </bean>

     

完整的spring-mybatis文件:web

<?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: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/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
    <context:annotation-config/>
    <context:component-scan base-package="com.leng.blogTMY"/>

    <!--導入數據鏈接池配置文件-->
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:jdbc.properties"/>
        <property name="fileEncoding" value="utf-8"/>
    </bean>

    <!--數據鏈接池配置-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${driverClassName}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>

        <!-- 初始化鏈接大小 -->
        <property name="initialSize" value="${initialSize}"/>
        <!-- 鏈接池最大數量 -->
        <property name="maxActive" value="${maxActive}"/>
        <!-- 鏈接池最大空閒 -->
        <property name="maxIdle" value="${maxIdle}"/>
        <!-- 鏈接池最小空閒 -->
        <property name="minIdle" value="${minIdle}"/>
        <!-- 獲取鏈接最大等待時間 -->
        <property name="maxWait" value="${maxWait}"/>
    </bean>

    <!--Spring Mybatis整合-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!--<property name="mapperLocations" value="classpdaopper/*.xml"/>-->
        <property name="mapperLocations" value="classpath:mapper/*.xml" />
        <property name="typeAliasesPackage" value="com.leng.blogTMY.model"/>
        <property name="plugins">
            <array>
                <bean class="com.github.pagehelper.PageHelper">
                    <property name="properties">
                        <value>
                            reasonable=true
                        </value>
                    </property>
                </bean>
            </array>
        </property>
    </bean>

    <!-- DAO接口所在包名,Spring會自動查找其下的類 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.leng.blogTMY.dao"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>

    <!-- (事務管理)transaction manager, use JtaTransactionManager for global tx -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

</beans>
View Code

jdbc.properties:spring

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/blogTMY?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
username=root
password=xxxxx

initialSize=0
maxActive=20
maxIdle=20
minIdle=1
maxWait=60000
View Code

注意,url後面必定要加上編碼設置utf-8,不然存入數據庫的數據會出現亂碼狀況!!sql

url=jdbc:mysql://localhost:3306/blogTMY?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull

以上爲Spring與MyBatis的整合。數據庫

 

2.SpringMVC配置

  • 開啓註解,掃描包:
        <context:component-scan base-package="com.leng.blogTMY"/>
    
        <mvc:annotation-driven/>

     

  • 配置視圖處理器viewResolver:
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="order" value="1"/>
            <property name="viewClass" value="com.leng.blogTMY.util.JspResourceView"/>
            <property name="prefix" value="/WEB-INF/jsp/" />
            <property name="suffix" value=".jsp"/>
        </bean>

     

  • 配置攔截器:
        <mvc:interceptors>
            <mvc:interceptor>
                <mvc:mapping path="/manage"/>
                <mvc:mapping path="/manage/*"/>
                <mvc:mapping path="/manage/**"/>
                <bean class="com.leng.blogTMY.interceptor.LoginInterceptor"/>
            </mvc:interceptor>
        </mvc:interceptors>

     

以上爲SpringMVC配置內容。apache

 

3.web.xml配置

  • 引入spring-mybatis.xml:
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mybatis.xml</param-value>
        </context-param>

     

  • 配置listener監聽器:
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>

     

  • 配置DispatcherServlet:
        <servlet>
            <servlet-name>mvc-dispatcher</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:spring-mvc.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>mvc-dispatcher</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>

     

  • 配置filter過濾器:
        <filter>
            <filter-name>encodingFilter</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>
            <init-param>
                <param-name>forceEncoding</param-name>
                <param-value>true</param-value>
            </init-param>
        </filter>
    
        <filter-mapping>
            <filter-name>encodingFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>

     

以上爲web.xml的主要配置。

至此,Spring+SpringMVC+MyBatis框架搭建完成。

能夠寫一個簡單的mvc工做流程測試框架。

 

2、Blog的基本功能

blog基本功能包括文章的增刪改查,用戶的信息,文章的分類等。

因此簡單肯定model層能夠包括:User、Article、Category;

 

1.model層的編寫:

  • User類:包括id、用戶名、密碼、暱稱等;
  • Article類:包括文章id、用戶id、分類id、文章的標題、內容、markDown等;
  • Category類:包括分類id、name;

user和article是一對多的關係;

article和category是多對一的關係;

 

2.model.dto包:

爲何須要dto包?

數據傳輸對象DTO自己並非業務對象。數據傳輸對象是根據UI的需求進行設計的,而不 是根據領域對象進行設計的。好比,Customer領域對象可能會包含一些諸如FirstName, LastName, Email, Address等信息。但若是UI上不打算顯示Address的信息,那麼CustomerDTO中也無需包含這個 Address的數據

  簡單來講Model面向業務,咱們是經過業務來定義Model的。而DTO是面向界面UI,是經過UI的需求來定義的。經過DTO咱們實現了表現層與Model之間的解耦,表現層不引用Model,若是開發過程當中咱們的模型改變了,而界面沒變,咱們就只須要改Model而不須要去改表現層中的東西。

  • UserDto:刪去user類的password;
  • ArticleDto:Article類的userid應改成user,category應改成category;
    /**
     * Created by leng on 2017/7/2.
     * id  文章id
     * title    文章標題
     * content  文章內容
     * putDate  文章發佈日期
     * clicks   點擊次數
     * remark   評論
     * picture  圖片
     * isDraft  是否草稿 默認0
     * category 分類
     * user     用戶
     */
    public class ArticleDto {
        private Integer id;
        private String title;
        private  String content;
        private  String markDown;
        private String pubDate;
        private Integer clicks;
        private String remark;
        private String picture;
        private Integer isDraft;
        private Category category;
        private UserDto user;
    
    //getter, setter, tostring...
    
    }

     

  • 增長ArticleLiteDto:做爲列表顯示的article,保留id、標題、簡介、發佈日期等,而不須要內容和markDown內容;
    package com.leng.blogTMY.model.dto;
    
    /**
     * Created by leng on 2017/7/2.
     * ArticleLiteDto 是用來在 首頁 中顯示文章的基本狀況的。好比 標題 發佈日期 有些blog 還會顯示內容簡介.
     * 能夠減小對數據庫的讀取訪問量.在首頁中顯示不須要顯示文章的內容和markdown內容.
     */
    public class ArticleLiteDto {
        private Integer id;
        private String title;
        private String pubDate;
        private Integer clicks;
        private String remark;
        private UserDto user;
    
    //getter, setter...
    
        @Override
        public String toString() {
            return "ArticleLiteDto{" +
                    "id=" + id +
                    ", title='" + title + '\'' +
                    ", pubDate='" + pubDate + '\'' +
                    ", clicks=" + clicks +
                    ", remark='" + remark + '\'' +
                    ", user=" + user +
                    '}';
        }
    }

     

  • CategoryDto:增長categoryCount屬性,在前端顯示category下文章的數目;

 

3.dao包接口:

  • UserDao:包括用戶的登陸、增刪改查;
  • ArticleDao:基本功能-文章的增刪改查;獲取列表分頁顯示;獲取上一篇、下一篇;獲取某分類文章getByCategory;
    /**
     * Created by leng on 2017/7/2.
     */
    
    @Repository
    public interface ArticleDao {
        //搜索文章根據文章標題
        List<ArticleDto> search(Article a_title) throws Exception;
    
        //分頁
        List<ArticleDto> pagerAction(Pager pager) throws Exception;
    
        //獲取文章Dto
        ArticleDto getArticleDto(Integer id) throws Exception;
    
        //獲取上一篇文章
        ArticleLiteDto getPreArticleDto(Integer id) throws Exception;
    
        //獲取下一篇文章
        ArticleLiteDto getNextArticleDto(Integer id) throws Exception;
    
        //獲取某分類下文章
        List<ArticleLiteDto> getByCategory(int categoryId) throws Exception;
    
        //歸檔
        List<ArticleLiteDto> archive() throws Exception;
    
        //更新點擊
        void updateArticleClicks(Integer clicks, Integer id) throws Exception;
    
        //更新文章
        void update(Article article) throws Exception;
    
        //保存文章
        void save(Article article) throws Exception;
    
        //刪除文章
        void delete(Integer id) throws Exception;
    
        //數量統計
        int count() throws Exception;
    }

     

  • CategoryDao:增刪改查;獲取總數count;

 

4.dao接口的實現mapper包:

編寫xml配置文件實現dao接口的方法;

注意mapper文件夾下的xml文件要放在resource包下,不然有可能不被掃描的。

或者在pom的<build>裏添加以下配置:

      <resources>
          <resource>
              <directory>src/main/java</directory>
              <includes>
                  <include>**/*.xml</include>
              </includes>
          </resource>
          <resource>
              <directory>src/main/resources</directory>
          </resource>
      </resources>

 

mapper的xml文件編寫的幾點注意點:

  1.namespace要和對應dao接口包名稱一致;

  2.方法名要和id一致;

不然會出現Invalid bound statement (not found) Mybatis綁定失敗

 UserMapper和ArticleMapper都比較常規;須要注意的是resultMap的要注意column和property的值不能寫錯,column對應數據庫,property對應model;

比較特殊的是獲取Category下的categoryCount須要用到RIGHT JOIN

    <select id="all" resultMap="categoryDto">
        SELECT
            t_category.categoryId,
            t_category.categoryName,
            COUNT(articleId) AS categoryCount
        FROM t_article
            RIGHT JOIN t_category ON t_article.categoryId = t_category.categoryId
        GROUP BY t_category.categoryId
    </select>

 

5.Service包及實現Impl

與Dao接口方法相似;

其中分頁方法須要編寫分頁工具類Pager:

屬性包括:pageSize、currentPage、totalRecord、totalPage;以及firstPage、lastPage、prePage、nextPage;

package com.leng.blogTMY.util;

/**
 * Created by leng on 2017/7/2.
 */
public class Pager {
    private int pageSize;//每頁顯示數據條數
    private int currentPage;//當前頁面
    private int totalRecord;//總數據條數
    private int totalPage;//總頁面數

    public int getTotalPage() {
        return totalPage;
    }

    //首頁
    private int firstPage;
    //末頁
    private int lastPage;
    //上一頁
    private int prePage;
    //下一頁
    private int nextPage;

    public Pager() {
    }

    public Pager(int currentPage, int pageSize, int totalRecord) {
        this.pageSize = pageSize;
        this.totalRecord = totalRecord;
        this.totalPage = calculateTotalPage();
        //負責計算 傳入的 頁面索引 是否超出最大頁面數值 超出就設置爲最大頁面索引
        this.currentPage = currentPage > totalPage ? totalPage : currentPage;
    }

    private int calculateTotalPage() {
        this.totalPage = this.totalRecord / this.pageSize;
        if (totalRecord % pageSize != 0) {
            this.totalPage = this.totalPage + 1;
        }
        return totalPage;
    }

// getter, setter...

    public int getFirstPage() {
        this.firstPage = 1;
        return this.firstPage;
    }

    public int getLastPage() {
        this.lastPage = totalPage;
        return lastPage;
    }

    public int getPrePage() {
        if (this.currentPage <= 1) {
            this.prePage = firstPage;
        }else {
            this.prePage = this.currentPage - 1;
        }
        return this.prePage;
    }

    public int getNextPage(){
        if(this.currentPage >= totalPage){
            this.nextPage = totalPage;
        }else {
            this.nextPage = this.currentPage + 1;
        }
        return this.nextPage;
    }


    public int getStartIndex(){
        return (currentPage-1)*pageSize;
    }
}

 

以上完成了業務邏輯的編寫。經過JUnit4寫測試類來測試service各方法。

下一部分會開始編寫controller層。完成主要的先後端功能。

相關文章
相關標籤/搜索