项目:我的博客系统 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层。完成主要的先后端功能。

相关文章
相关标签/搜索