介绍
于软件行业混迹了很多年,谈不上做了哪些很牛的大项目,林林总总也服务过好几个公司,虽与大牛级别的人物大相径庭,但我还是能自信已经是超越了菜鸟级,无论是简单还是复杂点的项目,若独立去做也还是勉强可以接受与完成。我深知自身知识比较薄弱,不咋会写技能技术之类的文章,许多东西都无从下手或下口,希望努力能够有所弥补吧。
开发中用了许多东西,平常我却少于总结,许多仿佛就是为了适应工作,完成工作而用,用过了一段时间不用就又忘记了,因此自己想找些简单的东西,写写记记,万一能使自己有所进步呢。
下面就简单搭建一个近几年开发中常使用的框架SSM(Spring+SpringMVC+Mybatis),使用maven作为项目开发管理工具。
Maven整合SSM
• 我的开发工具:idea2018.1.2;
• 系统:Windows 10;
• jdk版本:jdk8;
- 用Idea 创建一个maven web项目:springmvc-test
• 选择File-New-Moudle:
• 选择Maven-勾选Create from archetype-选中org.apache.maven.archetypes:maven-archetype-webapp:
• 你的项目包结构,项目名
• 一直下一步(next),直到完成(finish),编辑器会加载出你创建的项目。项目结构是src-main和pom.xml。在src-main下建立java,resources,test目录,并对目录进行标注(Sources,Resources,Tests)。
• 在webapp–WEB-INF下创建static,views目录,static里用于存放静态文件CSS,js,images。Views 存放jsp视图文件。当然若是前后端分离,请忽略。最后的项目结构如图:
- 配置文件
• pom.xml引入依赖包
<?xmlversion="1.0"encoding="UTF-8"?>
<projectxmlns="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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lk.springmvc.demo</groupId>
<artifactId>springmvc-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>springmvc-testMavenWebapp</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<spring.version>5.0.7.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--常用工具包-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.2</version>
</dependency>
<!--log日志-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
<!--数据库连接池-->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<!--添加mybatis的核心包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!--添加mybatis与Spring整合的核心包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<!--json-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
<!--文件上传依赖包-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<!--引入jstl标签-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--spring相关包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!--添加spring-web包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!--添加spring-jdbc包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<!--为了方便进行单元测试,添加spring-test包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
<build>
<finalName>springmvc-test</finalName>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<pluginManagement><!--lockdownpluginsversionstoavoidusingMavendefaults(maybemovedtoparentpom)-->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<!--seehttp://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging-->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
• 配置数据库连接信息文件:jdbc.properties(注:我引用了最新的MySQL数据库驱动,有早期版本配置略有差别)
#######jdbc############
#mysql-connector-java5之前的之前的驱动
#jdbc.driverClassName=com.mysql.jdbc.Driver
#jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
#我当前引用的最新版本,所以改用mysql-connector-java6以后的驱动
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
#url
jdbc.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false
#####
jdbc.username=root
jdbc.password=123456
dbcp.maxActive=5
dbcp.maxIdle=200
• spring-context.xml配置
主要引入数据源配置,配置一个数据源DataSource,配置SqlSessionFactoryBean,用于注册并扫描mapper中的sql语句,配置MapperScannerConfigurer,自动扫描DAO接口,配置注解方式事务,配置自动扫描包,注解等。
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="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"xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd">
<!--引入配置文件方式一多个用逗号隔开-->
<!--<context:property-placeholderlocation="classpath:jdbc.properties"/>-->
<!--引入配置文件方式二-->
<beanid="config"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<propertyname="location"value="classpath:jdbc.properties"/>
</bean>
<!--引入多个配置文件方式-->
<!--<beanid="config"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<propertyname="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>-->
<!--配置dbcp数据源-->
<beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close">
<propertyname="maxActive"value="${dbcp.maxActive}"/>
<propertyname="maxIdle"value="${dbcp.maxIdle}"/>
<propertyname="driverClassName"value="${jdbc.driverClassName}"/>
<propertyname="url"value="${jdbc.url}"/>
<propertyname="username"value="${jdbc.username}"/>
<propertyname="password"value="${jdbc.password}"/>
<propertyname="maxWait"value="1000"/>
<propertyname="removeAbandoned"value="true"/>
<propertyname="removeAbandonedTimeout"value="60"/>
<propertyname="defaultAutoCommit"value="true"/>
</bean>
<!--MyBatisSQLSessionFactory-->
<beanid="sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean">
<propertyname="dataSource"ref="dataSource"/>
</bean>
<beanid="sqlSession"class="org.mybatis.spring.SqlSessionTemplate">
<constructor-argindex="0"ref="sqlSessionFactory"/>
</bean>
<!--MybatisMapperScannerConfigurer自动扫描将Mapper接口生成代理注入到Spring-->
<beanid="mapperScanner"class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<propertyname="basePackage"value="com.lk.springmvc.demo.pojo,com.lk.springmvc.demo.dao"/>
<propertyname="sqlSessionFactoryBeanName"value="sqlSessionFactory"/>
</bean>
<!--事务配置-->
<beanid="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<propertyname="dataSource"ref="dataSource"/>
</bean>
<tx:annotation-driventransaction-manager="transactionManager"/>
<!--扫描-->
<context:component-scanbase-package="com.lk.springmvc.demo.service.impl"/>
</beans>
• spring-servlet.xml配置
主要配置SpringMVC前端控制器扫描包,对视图的解析,配置静态资源,json转换器,上传文件,拦截器等
<?xmlversion="1.0"encoding="UTF-8"?>
<beans:beansxmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/cachehttp://www.springframework.org/schema/cache/spring-cache.xsd">
<!--静态文件-->
<resourcesmapping="/static/**"location="/WEB-INF/static/"/>
<!--自动扫描controller包下的所有类-->
<context:component-scanbase-package="com.lk.springmvc.demo.controller"/>
<!--视图解析器-->
<beans:beanid="resourceViewResolver"class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:propertyname="prefix"value="/WEB-INF/views/"/>
<beans:propertyname="suffix"value=".jsp"/>
<beans:propertyname="order"value="0"/>
</beans:bean>
<!--json配置-->
<annotation-driven>
<message-converters>
<beans:beanid="stringHttpMessageConverter"class="org.springframework.http.converter.StringHttpMessageConverter">
<beans:propertyname="supportedMediaTypes">
<beans:list>
<beans:value>text/html;charset=UTF-8</beans:value>
<beans:value>application/json;charset=UTF-8</beans:value>
</beans:list>
</beans:property>
</beans:bean>
<beans:beanid="mappingJackson2HttpMessageConverter"class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<beans:propertyname="supportedMediaTypes">
<beans:list>
<beans:value>text/html;charset=UTF-8</beans:value>
<beans:value>application/json;charset=UTF-8</beans:value>
</beans:list>
</beans:property>
</beans:bean>
</message-converters>
</annotation-driven>
<!--上传文件配置-->
<beans:beanid="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:propertyname="maxUploadSize"value="1024000000"/>
</beans:bean>
<!--其他拦截器配置等-->
</beans:beans>
• log4j.properties日志输出信息配置
#配置根Logger后面是若干个Appender
log4j.rootLogger=DEBUG,A1,R
#log4j.rootLogger=INFO,A1,R
#ConsoleAppender输出
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-ddHH:mm:ss,SSS}[%c]-[%p]%m%n
#File输出一天一个文件,输出路径可以定制,一般在根路径下
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=log.txt
#log4j.appender.R.MaxFileSize=500KB
#log4j.appender.R.MaxBackupIndex=10
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-ddHH:mm:ss,SSS}[%t][%c][%p]-%m%n
•web.xml配置
配置监听器,过滤器,初始化容器加载的配置文件路径,springMVC核心控制器
<?xmlversion="1.0"encoding="UTF-8"?>
<web-appxmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<display-name>SpringMVCTest</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--配置springmvcDispatcherServlet -->
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--编码过滤器UTF-8-->
<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>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
至此,可在webapp下创建一个index.jsp页面,将项目添加至Tomcat中,启动,浏览器地址上访问: http://localhost:8080/spmvc ,若不出意外,项目应该是可以正常运行的。通过web.xml配置的默认欢迎页面,会加载出index.jsp内容,我的项目在浏览器上会显示出HelloWorld!
![]()
![]()
当然,这么多配置文件,在编写时,不可避免会有书写上的错误,或者引入包的缺失等,遇到这些情况,要根据错误提示信息,耐心寻找原因,解决错误。
示例数据库表
表字段根据需求创建,这里为了完整只是简单的举例。
CREATE DATABASE `test` ;
USE `test`;
/*Table structure for table `user` */
CREATE TABLE `user` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(30) DEFAULT NULL,
`password` VARCHAR(50) DEFAULT NULL,
`sex` INT(11) DEFAULT NULL,
`createtime` DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8;
编写Controller与对应的业务界面
indexController:简单测试,没有任何业务层逻辑。
@Controller
public class indexController{
private final static Logger log=LoggerFactory.getLogger(indexController.class);
@RequestMapping("index")
public String index(){
return "index";
}
@RequestMapping("json")
@ResponseBody
public String json(){
return "success:0";
}
}
QueryController:简单实现了对用户表的增删改查操作
@Controller
@RequestMapping("user")
public class QueryController{
@Autowired
private UserService userService;
@RequestMapping("ulist")
public String getListUser(Model model){
List<Map<String,Object>> list=userService.findAll();
model.addAttribute("list",list);
return "user/ulist";
}
/**
*新增页面
*@return
*/
@RequestMapping("addIndex")
public String add(){
return "user/add";
}
/**
*新增
*@paramuser
*@return
*/
@RequestMapping("add")
public String toAdd(User user){
userService.insertUser(user);
return "redirect:/user/ulist";
}
/**
*更新页面
*@paramid
*@return
*/
@RequestMapping("editIndex")
public ModelAndView edit(intid){
ModelAndView model=new ModelAndView("user/edit");
Map<String,Object> map=newHashMap<>();
map.put("id",id);
List list=userService.findByMap(map);
model.addObject("user",list.get(0));
return model;
}
/**
*更新
*@paramuser
*@return
*/
@RequestMapping("edit")
public ModelAndView toEdit(User user){
ModelAndView model=new ModelAndView("redirect:/user/ulist");
userService.updateUser(user);
return model;
}
/**
*删除
*@paramid
*@return
*/
@RequestMapping("del")
public ModelAndView del(int id){
ModelAndView model=new ModelAndView("redirect:/user/ulist");
userService.deleteUserById(id);
return model;
}
}
对应视图层页面
![]()
启动项目,访问地址: http://localhost:8080/spmvc/user/ulist ,最后执行预览效果如图
业务逻辑层比较简单,只是实现了用户的增删改查接口。数据层和实体层,我这里是自己写的,大家可以使用Mybatis Generator自动生成实体类、DAO接口以及Mapping映射文件,其教程很多。
UserMapper:使用mybatis注解sql
/**
*可使用mybatis注解sql
*用@Select注解sql语句
*@return
*/
@Select("select * from user")
List<Map<String,Object>> queryBySelect();
}
UserExtendMapper:通过mybatis提供的各种标签实现动态拼接sql语句
@Repository
public interface UserExtendMapper extends UserMapper{
/**
*添加
*@paramuser
*/
void insert(User user);
/**
*多条件查询
*@parammap
*@return
*/
List<User> query(Map<String,Object> map);
/**
*更新
*@paramuser
*/
void updateUser(User user);
/**
*删除
*@paramid
*/
void delById(int id);
}
UserExtendMapper.xml文件
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEmapperPUBLIC"-//mybatis.org//DTDMapper3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lk.springmvc.demo.dao.UserExtendMapper">
<insert id="insert" parameterType="com.lk.springmvc.demo.pojo.User">
insert into user(username,password,sex)values(#{username},#{password},#{sex})
</insert>
<select id="query" parameterType="java.util.Map" resultType="com.lk.springmvc.demo.pojo.User">
select*from user
<where>
<if test="id!=null">
and id=#{id}
</if>
<if test="name!=null and name!=''">
and username like'%${name}%'
</if>
</where>
</select>
<update id="updateUser" parameterType="com.lk.springmvc.demo.pojo.User">
update user set username=#{username},password=#{password},sex=#{sex}
where id=#{id}
</update>
<delete id="delById" parameterType="java.lang.Integer">
delete from user
where id=#{id}
</delete>
</mapper>
以上就是我搭建一个完整SSM框架的过程,不足之处请谅解指正,若感兴趣那就尝试着自己搭建一个吧,以便更好的理解知识。光看不练等于白看,没有看出来的系统,只有敲出来的代码。
项目源代码地址
https://gitee.com/keli88/spring-boot-demo/tree/master/springmvc-test