我不是一个架构师
2017-04-06 09:48
190 查看
简介
一系列的文章是以我现在带的一个项目为基础,从新开始一个后台管理类型的项目(qyAdmin–权限管理模块)为推动力来完成,里面有很多东西需要我去注意和学习的地方,太多。成果
登录首页
这是基于Metronic框架的,后续有时间的话可以研究metronic系列的博客集
技术架构
这篇文章主要的内容就是搭建项目的基础架构SpringBoot 1.5.1
Mybatis 3.3.8
Thymeleaf 3.0
BootStrap 3 和前端框架Metronic
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=50001
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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 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}") 117ef 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; } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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; } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
封装的基础接口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;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
尝试的小白
第一篇先写到这里,写的比较粗糙,源码先不分享了,现在还是一个半成品,后续我将把用户、部门的增删改查功能做出来之后分享到github上,希望大家一起学习。转自:山竹之七语:我不是一个架构师
相关文章推荐
- 架构师应该是一种角色,而不是一个职位
- 如何让自己成为一个优秀的Java架构师,而不是码农
- 不想当架构师的程序员不是一个好的程序员
- 架构师应该是一种角色,而不是一个职位
- 如何在WebBrowser打开的网页链接后直接在WebBrowser打开而不是新弹出一个IE窗口来打开
- 一个不是很通用的数据管理类。
- 做一个研究者,而不是程序员
- 经尉迟方兄提点,终于明白为什么不是一个简单的26进制程序了
- ASP.NET直接下载一个文件,而不是在IE中打开它
- 真正的问题——这不是一个笑话
- 自己写的一个asp.net分页类(sqlserver).注意是类,不是存储过程但原理一样
- 架构师不是建筑师
- 一个并不是很好解决web打印方案的例子
- 我不是一个骗子
- 一个让人不得不转的故事-《通宵达旦工资只有3200 博客网架构师艰难浪迹于北京》
- 一个让人不得不转的故事-《通宵达旦工资只有3200 博客网架构师艰难浪迹于北京》
- dos下怎样实现一个程序执行完后自动执行另一个程序,不是批处理
- ASP.NET直接下载一个文件,而不是在IE中打开它
- Response.redirect到一个新页面时,保证不是缓存的方法
- 一个让人不得不转的故事-《通宵达旦工资只有3200 博客网架构师艰难浪迹于北京》