SpringBoot学习之整合SSM+pagehelper+druid+单元测试

在阅读本博客之前有几点注意:

1、环境要安装好,JDK8Maven3.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

最后送给大家一句话,你的对手在看书,你的仇人在磨刀,你的闺蜜在减肥,隔壁老王在练腰,我们必须不断学习,否则我们将被学习者超越。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一杯咖啡半杯糖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值