快速搭建一个简单的spring-boot工程(ssm)
本示例工程整合spring-web、spring-jdbc、mybatis、druid、pageHelper等主流框架,附件为整个工程代码,下载后可以直接运行。
1、通过 SPRING INITIALIZR新建一个web工程,可先将Web,Aspects,JDBC,MyBatis,MySQL等依赖引入;
2、将生成的web工程导入IDE,本人用的STS;
3、本示例会将druid、pageHelper集成到项目中,故先添加相关依赖;
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.26</version> </dependency> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>4.1.6</version> </dependency>
4、SPRING INITIALIZR默认生成的配置文件名称为application.properties,本示例使用application.yml(可以直接修改后缀),由于引入了数据库连接驱动,这里直接启动会报异常,我们先配置application.yml文件;
spring: datasource: url: jdbc:mysql://localhost:3306/bds?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull username: root password: root driver-class-name: com.mysql.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource initialSize: 5 minIdle: 5 maxActive: 20 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true logSlowSql: true filters: stat,wall,log4j connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 useGlobalDataSourceStat: true druid: loginUsername: lihua loginPassword: lihua mvc: view: prefix: /WEB-INF/ suffix: .jsp server: port: 8083 tomcat: uri-encoding: UTF-8 mybatis: mapper-locations: - classpath*:mapper/mysql/*.xml type-aliases-package: com.huatech.domain
5、创建数据库表(为演示方便,本示例创建user表)
-- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `create_time` datetime DEFAULT NULL, `username` varchar(32) DEFAULT NULL, `email` varchar(32) DEFAULT NULL, `remark` varchar(128) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8;
6、新建user 实体类,简单实现三层(DAO/Service/Controller)代码
package com.huatech.domain; import java.util.Date; import org.springframework.format.annotation.DateTimeFormat; import com.fasterxml.jackson.annotation.JsonFormat; public class User { private Long id; // 日期类型输出到页面格式 @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") // 页面字符串格式化为日期 @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") private Date createTime; private String username; private String email; private String remark; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } @Override public String toString() { return "User [id=" + id + ", createTime=" + createTime + ", username=" + username + ", email=" + email + ", remark=" + remark + "]"; } }
package com.huatech.mapper; import java.util.List; import com.huatech.domain.User; /** * Dao Interface:UserMapper * @author lh * @version 3.0 * @date 2017-12-26 */ public interface UserMapper { void insert(User user); User get(Long id); List<User> findList(User model); }
package com.huatech.service; import java.util.List; import com.huatech.domain.User; public interface UserService { void insert(User user); User get(Long id); List<User> findList(User model); }
package com.huatech.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.huatech.domain.User; import com.huatech.mapper.UserMapper; import com.huatech.service.UserService; @Service("userService") public class UserServiceImpl implements UserService{ @Autowired private UserMapper dao; @Override public void insert(User user) { dao.insert(user); } @Override public User get(Long id) { return dao.get(id); } @Override public List<User> findList(User model) { return dao.findList(model); } }
package com.huatech.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.huatech.domain.User; import com.huatech.service.UserService; @Controller public class UserController { @Autowired private UserService userService; @GetMapping(value="/user/addPage") public String addPage(){ return "user/addPage"; } @PostMapping(value="/user/doAdd") @ResponseBody public User doAdd(User user){ userService.insert(user); return user; } }
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.huatech.mapper.UserMapper"> <resultMap type="com.huatech.domain.User" id="userResultMap"> <result property="id" column="ID"/> <result property="createTime" column="CREATE_TIME"/> <result property="username" column="USERNAME"/> <result property="email" column="EMAIL"/> <result property="remark" column="REMARK"/> </resultMap> <sql id="table_columns"> ID, CREATE_TIME, USERNAME, EMAIL, REMARK </sql> <sql id="entity_properties"> #{id}, #{createTime}, #{username}, #{email}, #{remark} </sql> <!-- 使用like用法:columnName like concat('%',#{columnName},'%') --> <sql id="page_where"> <trim prefix="where" prefixOverrides="and | or "> <if test="id != null">and ID = #{id}</if> <if test="createTime != null">and CREATE_TIME = #{createTime}</if> <if test="username != null and username != ''">and USERNAME = #{username}</if> <if test="email != null and email != ''">and EMAIL = #{email}</if> <if test="remark != null and remark != ''">and REMARK = #{remark}</if> </trim> <if test="page != null and page.sort!=null and page.sort!=''"> order by ${page.sort} ${page.order} </if> <!-- <if test="page == null or page.sort == null or page.sort == ''">order by sort </if> --> </sql> <insert id="insert" parameterType="com.huatech.domain.User" useGeneratedKeys="true" keyProperty="id"> insert into user( CREATE_TIME, USERNAME, EMAIL, REMARK ) values ( #{createTime}, #{username}, #{email}, #{remark} ) </insert> <insert id="insertBatch" parameterType="java.util.List"> insert into user( CREATE_TIME, USERNAME, EMAIL, REMARK ) values <foreach collection="list" item="item" index="index" separator=","> ( #{item.createTime}, #{item.username}, #{item.email}, #{item.remark} ) </foreach> </insert> <update id="update" parameterType="com.huatech.domain.User"> update user <trim prefix="set" suffixOverrides=","> <if test="createTime != null">CREATE_TIME = #{createTime},</if> <if test="username != null and username != ''">USERNAME = #{username},</if> <if test="email != null and email != ''">EMAIL = #{email},</if> <if test="remark != null and remark != ''">REMARK = #{remark},</if> </trim> <where>id = #{id}</where> </update> <select id="findAll" resultMap="userResultMap"> select <include refid="table_columns" /> from user </select> <select id="findList" resultMap="userResultMap"> select <include refid="table_columns" /> from user <include refid="page_where" /> </select> <select id="getCount" resultType="int" > select count(id) from user <include refid="page_where" /> </select> <select id="get" resultMap="userResultMap" parameterType="String" > select <include refid="table_columns" /> from user where id = #{id} </select> <!-- 其他自定义SQL --> </mapper>
7、MVC层配置,包括首页视图配置、设置字符编码过滤器、设置转换器等等;
package com.huatech.supports; import java.nio.charset.Charset; import java.util.List; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.filter.CharacterEncodingFilter; import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class ServletConfig extends WebMvcConfigurerAdapter { private static final String CHARSET = "UTF-8"; @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { Charset charset = Charset.forName(CHARSET); StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(charset); MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(); converters.add(stringConverter); converters.add(jsonConverter); super.configureMessageConverters(converters); } @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer.favorPathExtension(false); } @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("index"); } @Bean public FilterRegistrationBean filterRegistrationBean() { FilterRegistrationBean registrationBean = new FilterRegistrationBean(); CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); characterEncodingFilter.setForceEncoding(true); characterEncodingFilter.setEncoding(CHARSET); registrationBean.setFilter(characterEncodingFilter); return registrationBean; } }
8、druid配置
package com.huatech.supports; import java.sql.SQLException; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.support.http.StatViewServlet; import com.alibaba.druid.support.http.WebStatFilter; @Configuration public class DruidConfig { @Value("${spring.datasource.url}") private String dbUrl; @Value("${spring.datasource.username}") private String username; @Value("${spring.datasource.password}") private String password; @Value("${spring.datasource.driver-class-name}") private String driverClassName; @Value("${spring.datasource.initialSize}") private int initialSize; @Value("${spring.datasource.minIdle}") private int minIdle; @Value("${spring.datasource.maxActive}") private int maxActive; @Value("${spring.datasource.maxWait}") private int maxWait; @Value("${spring.datasource.timeBetweenEvictionRunsMillis}") private int timeBetweenEvictionRunsMillis; @Value("${spring.datasource.minEvictableIdleTimeMillis}") private int minEvictableIdleTimeMillis; @Value("${spring.datasource.validationQuery}") private String validationQuery; @Value("${spring.datasource.testWhileIdle}") private boolean testWhileIdle; @Value("${spring.datasource.testOnBorrow}") private boolean testOnBorrow; @Value("${spring.datasource.testOnReturn}") private boolean testOnReturn; @Value("${spring.datasource.poolPreparedStatements}") private boolean poolPreparedStatements; @Value("${spring.datasource.filters}") private String filters; @Value("${spring.datasource.logSlowSql}") private String logSlowSql; @Value("${spring.druid.loginUsername}") private String loginUsername; @Value("${spring.druid.loginPassword}") private String loginPassword; @Bean @Primary public DataSource dataSource() { // @Primary 注解作用是当程序选择dataSource时选择被注解的这个 DruidDataSource datasource = new DruidDataSource(); datasource.setUrl(dbUrl); datasource.setUsername(username); datasource.setPassword(password); datasource.setDriverClassName(driverClassName); datasource.setInitialSize(initialSize); datasource.setMinIdle(minIdle); datasource.setMaxActive(maxActive); datasource.setMaxWait(maxWait); datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); datasource.setValidationQuery(validationQuery); datasource.setTestWhileIdle(testWhileIdle); datasource.setTestOnBorrow(testOnBorrow); datasource.setTestOnReturn(testOnReturn); datasource.setPoolPreparedStatements(poolPreparedStatements); try { datasource.setFilters(filters); } catch (SQLException e) { e.printStackTrace(); } return datasource; } @Bean public ServletRegistrationBean druidServlet() { ServletRegistrationBean reg = new ServletRegistrationBean(); reg.setServlet(new StatViewServlet()); reg.addUrlMappings("/druid/*"); reg.addInitParameter("loginUsername", loginUsername); reg.addInitParameter("loginPassword", loginPassword); reg.addInitParameter("logSlowSql", logSlowSql); return reg; } @Bean public FilterRegistrationBean filterRegistrationBean() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter(new WebStatFilter()); filterRegistrationBean.addUrlPatterns("/*"); filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); filterRegistrationBean.addInitParameter("profileEnable", "true"); return filterRegistrationBean; } }
9、PageHelper配置
package com.huatech.supports; import java.util.Properties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.github.pagehelper.PageHelper; @Configuration public class PageHelperConfig { /** * 配置mybatis的分页插件pageHelper * @return */ @Bean public PageHelper pageHelper(){ PageHelper pageHelper = new PageHelper(); Properties properties = new Properties(); properties.setProperty("offsetAsPageNum","true"); properties.setProperty("rowBoundsWithCount","true"); properties.setProperty("reasonable","true"); //properties.setProperty("autoRuntimeDialect","true"); //properties.setProperty("dialect","mysql"); //配置mysql数据库的方言 pageHelper.setProperties(properties); return pageHelper; } }
10、开启事务并配置Mapper扫包路径
package com.huatech; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.support.SpringBootServletInitializer; import org.springframework.transaction.annotation.EnableTransactionManagement; @SpringBootApplication @EnableTransactionManagement @MapperScan("com.huatech.mapper") public class SpringBootSsmDemoApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(SpringBootSsmDemoApplication.class); } public static void main(String[] args) { SpringApplication.run(SpringBootSsmDemoApplication.class, args); } }
整合过程中遇到的问题:
1、web工程可以正常启动,但是不能访问。请检查你的pom文件是否引入tomcat插件依赖。
<!-- Provided --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <scope>provided</scope> </dependency>
2、中文乱码问题
如果是数据库层面乱码,请检查一下数据库和表的编码格式是否为utf-8,另外检查一下application.yml中spring.datasource.url中是否设置编码格式?useUnicode=true&characterEncoding=UTF-8。
如果是程序中出现乱码,比如页面输出乱码,请检查CharacterEncodingFilter设置的编码方式和MessageConverter的编码方式,可以参考ServletConfig.java类。具体配置如下:
@Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { Charset charset = Charset.forName(CHARSET); StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(charset); MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(); converters.add(stringConverter); converters.add(jsonConverter); super.configureMessageConverters(converters); }
@Bean public FilterRegistrationBean filterRegistrationBean() { FilterRegistrationBean registrationBean = new FilterRegistrationBean(); CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); characterEncodingFilter.setForceEncoding(true); characterEncodingFilter.setEncoding(CHARSET); registrationBean.setFilter(characterEncodingFilter); return registrationBean; }
另一种情况可能是web server编码格式未正确设置所致,在application.yml中配置如下:
server: port: 8083 tomcat: uri-encoding: UTF-8
3、Druid配置未起作用,请检查application.yml中spring.datasource.type是否正确设置。