在阅读本博客之前有几点注意:
1、环境要安装好,JDK8,Maven3.2,其他的请参考我的上一篇博客
http://blog.csdn.net/sinat_23225111/article/details/77984344
2、这篇博客只是个demo,具体的边界检查之类的没有写,大家可以根据我的例子进行扩展。
首先我们要总体看下目录结构
接下来我们要在 src/main/resources中写application.yml文件,用于SpringBoot配置(名字不能变,会出错,关于配置文件的其他名字,这里离先不讨论)
# ‘#’号代表注释,配置port我们可以使用下面的代码,我这里配置端口为8081
# 关于配置文件 必须在‘:’后加一个空格 分层结构 所以这条配置相当于 server.port=8081
server:
port: 8081
#这里配置数据库连接池druid,这是一个很强大的数据库连接池,我程序中有整合,想玩的同学可以试试
spring:
datasource:
driverClass: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8
username: root
password: 12345
platform: mysql
type: com.alibaba.druid.pool.DruidDataSource
# 下面为连接池的补充设置,应用到上面所有数据源中
# 初始化大小,最小,最大
initialSize: 1
minIdle: 3
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 30000
validationQuery: select 'x'
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,slf4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
写主函数,注意主函数位置要在其他java文件的上一层,大家可以回过头去看我上面的目录结构。
package com.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
/**
* @author shan
* @time 创建时间:2017年9月15日 下午1:59:16
* @SpringBootApplication= (默认属性)@Configuration + @EnableAutoConfiguration + @ComponentScan。还需要排除某一些默认类,否则会报错
*/
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class })
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
写Druid的配置,关于Druid的使用:SpringBoot启动后直接访问 http://localhost:8081/druid/ 即可。里面即是sql的监控
package com.springboot.config;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
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;
/**
* @author shan
* @date 2017年9月20日
* SpringBoot就是简化Spring的配置,省略了一堆xml
* 所以 @Configuration相当于xml中的<beans>标签
* @Bean相当于xml中的<bean>标签
*/
@Configuration
public class DruidConfiguration {
private static final Logger logger = LoggerFactory.getLogger(DruidConfiguration.class);
private static final String DB_PREFIX = "spring.datasource";
@Bean
public ServletRegistrationBean druidServlet() {
logger.info("init Druid Servlet Configuration ");
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
// IP白名单
servletRegistrationBean.addInitParameter("allow", "192.168.2.25,127.0.0.1");
// IP黑名单(共同存在时,deny优先于allow)
servletRegistrationBean.addInitParameter("deny", "192.168.1.100");
//控制台管理用户
servletRegistrationBean.addInitParameter("loginUsername", "admin");
servletRegistrationBean.addInitParameter("loginPassword", "admin");
//是否能够重置数据 禁用HTML页面上的“Reset All”功能
servletRegistrationBean.addInitParameter("resetEnable", "false");
return servletRegistrationBean;
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return filterRegistrationBean;
}
/*
* 解决 spring.datasource.filters=stat,wall,log4j 无法正常注册进去
* @ConfigurationProperties(prefix = DB_PREFIX) 把yml文件中的配置直接封装金javabean 还有一种方法是@Value 直接注入
*/
@ConfigurationProperties(prefix = DB_PREFIX)
class IDataSourceProperties {
private String url;
private String username;
private String password;
private String driverClass;
private int initialSize;
private int minIdle;
private int maxActive;
private int maxWait;
private int timeBetweenEvictionRunsMillis;
private int minEvictableIdleTimeMillis;
private String validationQuery;
private boolean testWhileIdle;
private boolean testOnBorrow;
private boolean testOnReturn;
private boolean poolPreparedStatements;
private int maxPoolPreparedStatementPerConnectionSize;
private String filters;
private String connectionProperties;
@Bean //声明其为Bean实例
@Primary //在同样的DataSource中,首先使用被标注的DataSource
public DataSource dataSource() {
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(url);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClass);
//configuration
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);
datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
try {
datasource.setFilters(filters);
} catch (SQLException e) {
logger.error("druid configuration initialization filter: " + e);
}
datasource.setConnectionProperties(connectionProperties);
return datasource;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDriverClass() {
return driverClass;
}
public void setDriverClass(String driverClass) {
this.driverClass = driverClass;
}
public int getInitialSize() {
return initialSize;
}
public void setInitialSize(int initialSize) {
this.initialSize = initialSize;
}
public int getMinIdle() {
return minIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public int getMaxActive() {
return maxActive;
}
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
public int getMaxWait() {
return maxWait;
}
public void setMaxWait(int maxWait) {
this.maxWait = maxWait;
}
public int getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRunsMillis;
}
public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
public int getMinEvictableIdleTimeMillis() {
return minEvictableIdleTimeMillis;
}
public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
public String getValidationQuery() {
return validationQuery;
}
public void setValidationQuery(String validationQuery) {
this.validationQuery = validationQuery;
}
public boolean isTestWhileIdle() {
return testWhileIdle;
}
public void setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
public boolean isTestOnBorrow() {
return testOnBorrow;
}
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
public boolean isTestOnReturn() {
return testOnReturn;
}
public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
public boolean isPoolPreparedStatements() {
return poolPreparedStatements;
}
public void setPoolPreparedStatements(boolean poolPreparedStatements) {
this.poolPreparedStatements = poolPreparedStatements;
}
public int getMaxPoolPreparedStatementPerConnectionSize() {
return maxPoolPreparedStatementPerConnectionSize;
}
public void setMaxPoolPreparedStatementPerConnectionSize(int maxPoolPreparedStatementPerConnectionSize) {
this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
}
public String getFilters() {
return filters;
}
public void setFilters(String filters) {
this.filters = filters;
}
public String getConnectionProperties() {
return connectionProperties;
}
public void setConnectionProperties(String connectionProperties) {
this.connectionProperties = connectionProperties;
}
}
}
写mybits整合的代码
package com.springboot.config;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.alibaba.druid.pool.DruidDataSource;
import com.github.pagehelper.PageHelper;
/**
*
* @author shan
* @date 2017年9月20日
* @EnableTransactionManagement是开启事务的注解
* @MapperScan(basePackages = "com.springboot.mapper")标注你的mapper层的java文件放在那个包中,必须写
*/
@EnableTransactionManagement
@Configuration
@MapperScan(basePackages = "com.springboot.mapper")
public class MybatisConfiguration {
private static Log logger = LogFactory.getLog(MybatisConfiguration.class);
@Autowired
private DataSource dataSource;
// 提供SqlSeesion
@Bean
public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
// 添加pageHelper插件
sqlSessionFactoryBean.setPlugins(new Interceptor[] { pageHelper() });
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
//这里最好把路径写进yml中,之后通过@Value注入,减少硬编码,这里只是举个反例
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:/mapper/*.xml"));
return sqlSessionFactoryBean.getObject();
}
@Bean
public PageHelper pageHelper() {
PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
properties.setProperty("reasonable", "true");
properties.setProperty("supportMethodsArguments", "true");
properties.setProperty("returnPageInfo", "check");
properties.setProperty("params", "count=countSql");
pageHelper.setProperties(properties);
return pageHelper;
}
@Bean
public PlatformTransactionManager transactionManager() {
//把数据源放进spring事务管理器
return new DataSourceTransactionManager(dataSource);
}
}
写controller层
package com.springboot.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.github.pagehelper.PageInfo;
import com.springboot.entity.Classify;
import com.springboot.service.ClassifyService;
/**
* @author shan
* @time 创建时间:2017年9月14日 下午2:12:18
* @RestController = @Controller + @ResponseBody
*/
@RestController
public class ClassifyController {
@Autowired
private ClassifyService classifyService;
/**@GetMapping("/getData") = @RequestMapping(value="/getData",method=RequestMethod.GET)
* 有Get就有post put delete
*/
//@GetMapping("/getData" )
public List<Classify> getClassify() {
return classifyService.getClassify();
}
@GetMapping("/getPage/{id}")
public PageInfo<Classify> getClassify(@PathVariable("id") Integer id) {
return classifyService.getPage(id);
}
}
写Service层,接口
package com.springboot.service;
import java.util.List;
import com.github.pagehelper.PageInfo;
import com.springboot.entity.Classify;
/**
* @author shan
* @time 创建时间:2017年9月20日 下午7:21:38
*
*/
public interface ClassifyService {
/**创建得到所有的分类信息*/
List<Classify> getClassify();
/**创建分页信息*/
public PageInfo<Classify> getPage(Integer pageNum);
}
service实现层
package com.springboot.service.imp;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.springboot.entity.Classify;
import com.springboot.mapper.ClassifyMapper;
import com.springboot.service.ClassifyService;
/**
* @author shan
* @time 创建时间:2017年9月20日 下午7:22:00
*
*/
@Service
public class ClassifyServiceImp implements ClassifyService {
@Autowired
private ClassifyMapper classifyMapper;
public List<Classify> getClassify() {
return classifyMapper.selectAll();
}
public PageInfo<Classify> getPage(Integer pageNum) {
//每页显示的数量
int pageSize = 3;
//从数据库查询分页信息
List<Classify> listPage=null;
//开始分页,我为了多分几页,才设置的这么小的
PageHelper.startPage(pageNum, 2);
listPage=classifyMapper.selectAll();
//要显示的导航数
int navigatePages=6;
//生成分页数据
PageInfo<Classify> pageInfo = new PageInfo(listPage, navigatePages);
return pageInfo;
}
}
mapper层,其实mapper和mapper.xml我是通过mybatis-generator-maven-plugin生成的 ,直接执行maven命令
package com.springboot.mapper;
import com.springboot.entity.Classify;
import java.util.List;
public interface ClassifyMapper {
int deleteByPrimaryKey(Integer id);
int insert(Classify record);
Classify selectByPrimaryKey(Integer id);
List<Classify> selectAll();
int updateByPrimaryKey(Classify record);
}
mapper.xml
<?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.springboot.mapper.ClassifyMapper" >
<resultMap id="BaseResultMap" type="com.springboot.entity.Classify" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="classifyName" property="classifyname" jdbcType="VARCHAR" />
</resultMap>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
delete from classify
where id = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="com.springboot.entity.Classify" >
insert into classify (id, classifyName)
values (#{id,jdbcType=INTEGER}, #{classifyname,jdbcType=VARCHAR})
</insert>
<update id="updateByPrimaryKey" parameterType="com.springboot.entity.Classify" >
update classify
set classifyName = #{classifyname,jdbcType=VARCHAR}
where id = #{id,jdbcType=INTEGER}
</update>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
select id, classifyName
from classify
where id = #{id,jdbcType=INTEGER}
</select>
<select id="selectAll" resultMap="BaseResultMap" >
select id, classifyName
from classify
</select>
</mapper>
javabean,特少对吧 ,我用了java黑科技lombok ,有兴趣的可以学一下
package com.springboot.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Classify {
private Integer id;
private String classifyname;
}
执行我们直接执行主函数main就行了,SpringBoot内嵌tomcat,很方便。
执行结果
别忘了进行单元测试,单元测试写法
package com.springboottest;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import com.springboot.DemoApplication;
import com.springboot.entity.Classify;
import com.springboot.mapper.ClassifyMapper;
import com.springboot.service.ClassifyService;
/**
* @author shan
* @time 创建时间:2017年9月18日 下午2:42:10
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
//指定SpringBoot工程的Application启动类
//支持web项目
@WebAppConfiguration
@SpringBootTest(classes = DemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.MOCK)
public class AddotherClassify {
@Autowired
private ClassifyService classifyService;
@Test
public void testAddStudent() throws Exception {
List<Classify> classify = classifyService.getClassify();
classify.stream().forEach(System.out::println);
}
}
代码已附在github上: https://github.com/CharlsShan/springboot-demo