您的位置:首页 > 编程语言 > Java开发

QiYuAdmin-架构搭建一(SpringBoot实战)

2017-02-25 15:24 246 查看

简介

工作5年了,现在自我定义是一个产品的研发经理,去年公司老板要每个人拿着自己的PPT在他面前做年终总结,我其中有一条是今年要写一套技术博客文集 then just do it。接下来的一系列的文章是以我现在带的一个项目为基础,从新开始一个后台管理类型的项目(QiYuAdmin–后台管理系统)为推动力来完成,里面有很多东西需要我去注意和学习的地方,太多。

成果

登录



首页



技术架构

这篇文章主要的内容就是搭建项目的基础架构

SpringBoot 1.5.1

Mybatis 3.3.8

Thymeleaf 3.0

BootStrap 3

SpringBoot和Druid集成

SpringBoot、通用Mapper集成和分页插件集成

自己封装的基础接口BaseService

Maven3.3.9、intellij idea2016、MySQL、Tomcat

基于Maven创建SpringBoot项目



解释一下以上几个模块的作用

* qiyu-framework-web:Metronic框架和一些插件

* qiyu-framework-core:整个项目的核心模块

* qiyu-amin-web:qyAdmin所有的页面和自定义静态资源

* qiyu-admin-auth:权限模块

SpringBoot集成Druid





源码网上搜索一大堆,还是贴出来吧

Application.properties配置:

# DataSource settings
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driverClassName = com.mysql.jdbc.Driver
#连接池的配置信息
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
# 配置获取连接等待超时的时间
spring.datasource.maxWait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.timeBetweenEvictionRunsMillis=60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
spring.datasource.filters=stat,wall,log4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000


Bean配置:

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 javax.sql.DataSource;
import java.sql.SQLException;

/**
* alibaba druid数据库连接池
*
* @author zhangqing
* @date 2017年02月25日
*/
@Configuration
public class DruidDBConfig {
private Logger logger = LoggerFactory.getLogger(DruidDBConfig.class);
@Value("${spring.datasource.url}")
private String dbUrl;

@Value("${spring.datasource.username}")
private String username;

@Value("${spring.datasource.password}")
private String password;

@Value("${spring.datasource.driverClassName}")
private String d
4000
riverClassName;

@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.filters}")
private String filters;

@Value("{spring.datasource.connectionProperties}")
private String connectionProperties;

@Bean(initMethod = "init", destroyMethod = "close")   //声明其为Bean实例
@Primary  //在同样的DataSource中,首先使用被标注的DataSource
public DataSource dataSource() {
DruidDataSource datasource = new DruidDataSource();

datasource.setUrl(this.dbUrl);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);

//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);
try {
datasource.setFilters(filters);
} catch (SQLException e) {
logger.error("druid configuration initialization filter", e);
}
datasource.setConnectionProperties(connectionProperties);

return datasource;
}

@Bean
public ServletRegistrationBean druidServlet() {
ServletRegistrationBean reg = new ServletRegistrationBean();
reg.setServlet(new StatViewServlet());
reg.addUrlMappings("/druid/*");
reg.addInitParameter("allow", "127.0.0.1"); //白名单
reg.addInitParameter("deny",""); //黑名单
reg.addInitParameter("loginUsername", "admin");
reg.addInitParameter("loginPassword", "admin");
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/*");
return filterRegistrationBean;
}
}


SpringBoot集成Mybatis

import com.github.pagehelper.PageHelper;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Properties;

/**
* MyBatis基础配置
*/
@Configuration
@EnableTransactionManagement
public class MyBatisConfig implements TransactionManagementConfigurer {

@Resource
DataSource dataSource;

@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactoryBean() {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setTypeAliasesPackage("com.qiyu.admin.*.model");

//分页插件
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);

//添加插件
bean.setPlugins(new Interceptor[]{pageHelper});

//添加XML目录
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
try {
bean.setMapperLocations(resolver.getResources("classpath*:mapper/*Mapper.xml"));
return bean.getObject();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}

@Bean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}

@Bean
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
return new DataSourceTransactionManager(dataSource);
}
}


import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import tk.mybatis.spring.mapper.MapperScannerConfigurer;

import java.util.Properties;

/**
* MyBatis扫描接口,使用的tk.mybatis.spring.mapper.MapperScannerConfigurer,
*/
@Configuration
//注意,由于MapperScannerConfigurer执行的比较早,所以必须有下面的注解
@AutoConfigureAfter(MyBatisConfig.class)
public class MyBatisMapperScannerConfig {

@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
mapperScannerConfigurer.setBasePackage("com.qiyu.admin.*.mapper");
Properties properties = new Properties();
properties.setProperty("mappers", "com.qiyu.framework.base.BaseMapper");
properties.setProperty("notEmpty", "false");
properties.setProperty("IDENTITY", "MYSQL");
mapperScannerConfigurer.setProperties(properties);
return mapperScannerConfigurer;
}

}


封装的基础接口BaseService

这个是自己封装的接口,没啥技术含量就是为了方便

import com.qiyu.framework.util.PagedResult;

import java.util.List;

/**
*
* 基础接口
* @author zhangqing
* @date 2016年09月02日
*/

public interface BaseService<T extends BaseModel>{
/**
*
* 增加一个实体,增加所有字段
* @param pojo
* @return 返回实体类
*/
public T insert(T pojo) throws Exception;

/**
*
* 增加一个实体,只会增加不是null的字段
* @param pojo
* @return 返回实体类
*/
public T insertSelective(T pojo)throws Exception;

/**
* 根据主键进行更新一个实体类,更新所有字段
* @param pojo
* @return 修改成功状态
*/
public T updateByPrimaryKey(T pojo)throws Exception;

/**
* 根据主键进行更新一个实体类,只会更新不是null的字段
* @param pojo
* @return
*/
public T updateByPrimaryKeySelective(T pojo)throws Exception;

/**
* 根据实体类中字段不为null的条件进行删除,条件全部使用=号and条件
* @param key
* @return
*/
public int delete(T key)throws Exception;

/**
* 通过主键进行删除,这里最多只会删除一条数据
* 单个字段做主键时,可以直接写主键的值
* 联合主键时,key可以是实体类,也可以是Map
* @param key
* @return
*/
public int deleteByPrimaryKey(Object key)throws Exception;

/**
* 根据主键的集合批量删除数据
* @param keys
* @return 是否删除成功
*/
public boolean deleteByPrimaryKeyList(List<String> keys)throws Exception;

/**
* 根据实体类不为null的字段进行查询集合,条件全部使用=号and条件
* @param pojo
* @return
*/
public List<T> select(T pojo)throws Exception;

/**
* 根据实体类不为null的字段查询总数,条件全部使用=号and条件
* @param pojo
* @return
*/
public int selectCount(T pojo)throws Exception;

/**
* 根据主键进行查询,必须保证结果唯一
* 单个字段做主键时,可以直接写主键的值
* 联合主键时,key可以是实体类,也可以是Map
* @param key
* @return
*/
public T selectByPrimaryKey(Object key)throws Exception;

/**
* 查询所有实体集合
* @return
*/
public List<T> selectAll()throws Exception;

/**
* 查询分页
* @param pageNo
* @param pageSize
* @param pojo
* @return
*/
public PagedResult<T> findPageList(Integer pageNo, Integer pageSize, T pojo)throws Exception;


尝试的小白

第一篇先写到这里,写的比较粗糙,源码先不分享了,现在还是一个半成品,后续我将把用户、部门的增删改查功能做出来之后分享到github上,希望大家一起学习。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐