年底因为各种事情比较忙,很久没有更新,最近在家宅着顺便填下之前的坑。
后端部分:
一、创建maven工程导入依赖(在上一篇中可以找到pom文件)和配置spring及整合springMVC、Mybatis
- 我用的是IDEA,创建maven-web工程的教程有很多,我就不多废话了;
- web.xml
<?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>article</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 启动spring容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- springMVC前端控制器 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 取消过滤html页面 -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<!-- 过滤字符编码 -->
<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>
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 将页面普通的请求转为rest风格的请求 -->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
- applicationContext.xml
<?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-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<context:component-scan base-package="com.luofc">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- 配置连接池 -->
<context:property-placeholder location="classpath:dbconfig.properties"/>
<bean id="pooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 配置整合mybatis -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 指定mybatis全局配置文件位置 -->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<property name="dataSource" ref="pooledDataSource"></property>
<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
</bean>
<!-- 配置可以執行批量操作的sqlsession -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
<constructor-arg name="executorType" value="BATCH"></constructor-arg>
</bean>
<!-- 配置扫描器,把mybatis的接口实现类加入IOC容器中 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 扫描所有dao接口的实现,加入IOC -->
<property name="basePackage" value="com.luofc.article"></property>
</bean>
<!-- 配置事务控制 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="pooledDataSource"></property>
</bean>
<!-- 开启基于XML配置的事务 -->
<aop:config>
<aop:pointcut expression="execution(* com.jiafu.article.service..*(..))" id="txPoint"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
</aop:config>
<!-- 配置事务的增强 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" read-only="false"/>
<tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
</tx:attributes>
</tx:advice>
</beans>
- 连接池配置文件:dbconfig.properties,大家根据自己数据库的库名和用域名及密码配置,我的如下:
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/luofc
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.user=root
jdbc.password=root
- 配置springMVC
- 配置视图解析器时要注意,使用jsp页面和html页面的配置有很大区别,我把两种配置都写出来了,大家可以根据自己的需要配置(我使用的是html页面,jsp页面的配置我注释掉了)
- 另外,此配置文件的位置需要注意;它不能放在resources中,而需要放在WEB-INF下,与web.xml在同一目录下。
<?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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
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-4.3.xsd">
<!-- springMVC配置 -->
<context:component-scan base-package="com.luofc" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- 配置html视图解析器 -->
<bean id="freemarkerConfiguration"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:freemarker.properties" />
</bean>
<bean id="freemarkerConfig"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="freemarkerSettings" ref="freemarkerConfiguration"/>
<property name="templateLoaderPath" value="/WEB-INF/views/"/>
</bean>
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="suffix" value=".html"/>
<property name="order" value="0"/>
<property name="contentType" value="text/html;charset=UTF-8"/>
</bean>
<!-- 配置JSP视图解析器
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="1"/>
</bean>-->
<!--配置文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding">
<value>UTF-8</value>
</property>
<property name="maxUploadSize">
<value>32505856</value><!-- 上传文件大小限制为31M,31*1024*1024 -->
</property>
<property name="maxInMemorySize">
<value>4096</value>
</property>
</bean>
<!-- 将springMVC不能处理的请求交给tomcat -->
<mvc:default-servlet-handler/>
<!-- 支持springMVC高级应用,如JSR303校验、快捷ajax -->
<mvc:annotation-driven/>
<!-- 配置springMvc拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller -->
<mvc:mapping path="/**" />
<!-- 不需要拦截的地址 -->
<!-- <mvc:exclude-mapping path="/" />
<mvc:exclude-mapping path="/timeout" />
<mvc:exclude-mapping path="/template/**" /> -->
<mvc:exclude-mapping path="/login" />
<mvc:exclude-mapping path="/static/**" />
<mvc:exclude-mapping path="/bin/**" />
<mvc:exclude-mapping path="/lib/**" />
<mvc:exclude-mapping path="/temp/**" />
<bean class="com.jiafu.article.utils.loginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
- 配置Mybatis
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<package name="com.luofc.article.bean"/>
</typeAliases>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 分页合理化参数配置,该配置用于解决后期导航条页数显示出现负数的bug -->
<property name="reasonable" value="true"/>
</plugin>
</plugins>
</configuration>
二、使用Mybatis逆向工程生成基础类
创建基础类
- 在第一篇中说到因为想偷个懒,用的是mybatis的逆向生成实体类、Dao层接口和对应mapper,所以第一步就是先创建数据库,数据库结构如下:
- article表
- article_1表
- article_2表
- user表
- article表
- 配置Mybatis逆向工程
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<!-- Mybatis逆向工程的配置文件 -->
<generatorConfiguration>
<context id="DB2Tables" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!-- 数据库连接 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/hztyhz"
userId="root"
password="root">
</jdbcConnection>
<javaTypeResolver >
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- 指定javabean生成的位置 -->
<javaModelGenerator targetPackage="com.jiafu.article.bean" targetProject=".\src\main\java">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- 指定sql映射文件生成的位置 -->
<sqlMapGenerator targetPackage="mapper" targetProject=".\src\main\resources">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- 指定Dao接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.jiafu.article.dao" targetProject=".\src\main\java">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 指定数据库中每一个表的生成策略;tableName后写需要读取的表名,domainObjectName后写生成的类名-->
<table tableName="user" domainObjectName="User" ></table>
<table tableName="article" domainObjectName="Article" ></table>
<table tableName="article_1" domainObjectName="ArticleFa" ></table>
<table tableName="article_2" domainObjectName="ArticleWei" ></table>
</context>
</generatorConfiguration>
- Mybatis逆向工程运行主程序
package com.luofc.article.test;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* @author:luoFc
* @date:2019/10/22-18:55
* @emal:523232622@qq.com
* @Description:(运行Mybatis逆向工程的方法)
*/
public class MBGRun {
public static void main(String[] args) throws Exception {
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
File configFile = new File("./src/main/resources/MBG.xml"); //指定逆向工程配置文件路径
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
}
}
直接运行main方法后可自动生成实体类、Dao层接口和mapper。
三、编写service层
- UserService
package com.luofc.article.service;
import com.luofc.article.bean.User;
import com.luofc.article.dao.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author:luoFc
* @date:2019/10/22-19:28
* @emal:523232622@qq.com
* @Description:(用户管理的业务层)
*/
@Service
public class UserService {
@Autowired
UserMapper userMapper;
//通过用户名查找一个用户(用于登陆查询)
public User findByUserName(String username) {
return userMapper.selectByName(username);
}
//查询所有用户(用于后期用户管理功能)
public List<User> findAllUser(){
return userMapper.selectByExample(null);
}
//添加用户(用于后期用户管理功能)
public void insertUser(User user){
userMapper.insert(user);
}
//通过ID删除用户(用于后期用户管理功能)
public void deleteUser(Integer id){
userMapper.deleteByPrimaryKey(id);
}
}
- ArticleService
- MyBatis逆向工程生成的Dao层接口和mapper有一定的局限性,通过作者名查询文章这一方法并没有相关Dao层和mapper支持,所以我们后续还要完善这部分;
package com.luofc.article.service;
import com.luofc.article.bean.Article;
import com.luofc.article.bean.ArticleExample;
import com.luofc.article.dao.ArticleMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author:luoFc
* @date:2019/10/22-19:27
* @emal:523232622@qq.com
* @Description:(文章处理的业务层)
*/
@Service
public class ArticleService {
//自动装配文章的Mapper
@Autowired
ArticleMapper articleMapper;
@Autowired
ArticleExample articleExample;
//保存文章
public boolean addArticle(Article article) {
Integer num = articleMapper.insertSelective(article);
if (num == 0){
return false;
}
return true;
}
//通过ID删除一篇文章
public boolean deleteArticleById(Integer id) {
Integer num = articleMapper.deleteByPrimaryKey(id);
if (num == 0){
return false;
}
return true;
}
//查询所有文章
public List<Article> getAllArticle() {
articleExample.setOrderByClause("id DESC");
return articleMapper.selectByExample(articleExample);
}
//通过作者查询文章(用于对不同的写作用户进行分类展示)
public List<Article> getArticleByZuozhe(String zuozhe){
if (zuozhe != null){
List<Article> list = articleMapper.selectByZuozhe(zuozhe);
return list;
}
return null;
}
//通过id查询已发布文章
public Article getArticleById(Integer id){
return articleMapper.selectByPrimaryKey(id);
}
}
- ArticleFaService
- 同样根据需要,通过作者名查询待发布文章这一方法也没有Dao层和mapper支持,后面一起完善;
package com.luofc.article.service;
import com.luofc.article.bean.ArticleFa;
import com.luofc.article.dao.ArticleFaMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author:luoFc
* @date:2019/10/24-18:52
* @emal:523232622@qq.com
* @Description:(待发布文章的业务层)
*/
@Service
public class ArticleFaService {
@Autowired
ArticleFaMapper articleFaMapper;
//增加一篇待发布文章
public boolean addArticleFa(ArticleFa articleFa){
Integer i = articleFaMapper.insert(articleFa);
if (i == 0){
return false;
}
return true;
}
//根据id删除待发布文章
public boolean deleteArticleFaById(Integer fid){
Integer i = articleFaMapper.deleteByPrimaryKey(fid);
if (i == 0){
return false;
}
return true;
}
//根据主键修改一篇未发布文章
public boolean updateArticleFaById(ArticleFa articleFa){
Integer i = articleFaMapper.updateByPrimaryKeySelective(articleFa);
if (i == 0){
return false;
}
return true;
}
//查询所有的待发布文章
public List<ArticleFa> getAllArticleFas(){
return articleFaMapper.selectByExample(null);
}
//根据作者名查询所有待发布文章
public List<ArticleFa> getArticleFasByZuozhew(String zuozhe){
if (zuozhe != null){
return articleFaMapper.selectByZuozhe(zuozhe);
}
return null;
}
//根据id查询一篇待发布文章
public ArticleFa getArticleFaById(Integer fid){
return articleFaMapper.selectByPrimaryKey(fid);
}
}
- ArticleWeiService
- 同样根据需要,通过作者名查询未审核文章这一方法也没有Dao层和mapper支持,后面一起完善;
package com.luofc.article.service;
import com.luofc.article.bean.ArticleWei;
import com.luofc.article.dao.ArticleWeiMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author:luoFc
* @date:2019/10/23-16:49
* @emal:523232622@qq.com
* @Description:(未审核文章的业务层)
*/
@Service
public class ArticleWeiService {
@Autowired
ArticleWeiMapper articleWeiMapper;
//增加一篇未审核文章
public boolean addArticleWei(ArticleWei articleWei){
Integer i = articleWeiMapper.insertSelective(articleWei);
if (i == 0){
return false;
}
return true;
}
//根据id删除未审核文章
public boolean deleteArticleWeiById(Integer wid){
Integer i = articleWeiMapper.deleteByPrimaryKey(wid);
if (i == 0){
return false;
}
return true;
}
//根据主键更新未审核文章
public boolean updateArticleWeiById(ArticleWei articleWei){
int i = articleWeiMapper.updateByPrimaryKeySelective(articleWei);
if (i == 0){
return false;
}
return true;
}
//查询所有未审核文章
public List<ArticleWei> getAllArticleWeis(){
return articleWeiMapper.selectByExample(null);
}
//通过作者查询所有未审核文章
public List<ArticleWei> getArticleWeisByZuozhew(String zuozhe){
if (zuozhe != null){
return articleWeiMapper.selectByZuozhe(zuozhe);
}
return null;
}
//通过id查询未审核文章
public ArticleWei getArticleWeiById(Integer wid){
return articleWeiMapper.selectByPrimaryKey(wid);
}
}
四、根据需求完善逆向工程生成的Dao层接口、mapper
- 在Dao层ArticleMapper接口中添加:
//基于mybatis逆向工程新添加,用于查找不同写作用户的文章
List<Article> selectByZuozhe(String zuozhe);
- 在resource文件夹下mapper包中的ArticleMapper里面添加:
<!--用于查询不同写作用户的文章,注意jdbcType=VARCHAR中的类型为mysql数据库中的类型-->
<select id="selectByZuozhe" parameterType="java.lang.String" resultMap="ResultMapWithBLOBs">
select
<include refid="Base_Column_List" />
,
<include refid="Blob_Column_List" />
from article
where zuozhe = #{zuozhe,jdbcType=VARCHAR}
</select>
- 在Dao层接口ArticleFaMapper中添加:
//luoFc增加根据用户查询待发布文章
List<ArticleFa> selectByZuozhe(String zuozhe);
- 在resource文件夹下mapper包中的ArticleFa里面添加:
<!--根据用户查询待发布文章-->
<select id="selectByZuozhe" parameterType="java.lang.String" resultMap="ResultMapWithBLOBs">
select
<include refid="Base_Column_List" />
,
<include refid="Blob_Column_List" />
from article_1
where fzuozhe = #{fzuozhe,jdbcType=VARCHAR}
</select>
- 在Dao层接口ArticleWeiMapper中添加:
//luoFc添加,用于通过作者查询未审核文章
List<ArticleWei> selectByZuozhe(String zuozhe);
- 在resource文件夹下mapper包中的ArticleWei里面添加:
<select id="selectByZuozhe" parameterType="java.lang.String" resultMap="ResultMapWithBLOBs">
select
<include refid="Base_Column_List" />
,
<include refid="Blob_Column_List" />
from aritcle_2
where wzuozhe = #{wzuozhe,jdbcType=VARCHAR}
</select>
到目前为止,所有的业务逻辑和后端的基础部分已经完成,接下来就是导入前端页面和编写各种controller了。如果有任何疑问可以加我QQ或者给我写邮件。
PS:如果是新手,我建议在整合spring+springMVC+Mybatis的时候应该分步测试,详细教程可以去网上找找,我自己看的是heima的整合教程。对新人来说多了解各个框架的基础和底层实现原理非常有用。