├── README.md
├── pom.xml
└── src
└── main
├── java
└── com
│ └── fei
│ └── springboot
│ ├── Application.java
│ ├── config
│ ├── mybatis
│ │ ├── DatasourceConfig.java
│ │ ├── MybatisConfiguration.java
│ │ └── SqlPrintInterceptor.java
│ └── redis
│ │ └── RedisConfiguration.java
│ ├── controller
│ └── UserController.java
│ ├── dao
│ ├── UserMapper.java
│ └── UserMapper.xml
│ ├── domain
│ └── User.java
│ └── service
│ └── UserService.java
└── resources
├── application.yml
├── logback.xml
└── mybatis-config.xml
/README.md:
--------------------------------------------------------------------------------
1 | # spring-boot-mybatis-redis
2 | spring boot+mybatis+redis数据缓存整合
3 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 | com.fei.springboot
4 | springboot-mybatis-redis
5 | 0.0.1-SNAPSHOT
6 |
7 |
8 |
9 | alimaven
10 | http://maven.aliyun.com/nexus/content/repositories/central/
11 |
12 | true
13 |
14 |
15 | true
16 |
17 |
18 |
19 |
20 |
21 |
22 | alimaven
23 | http://maven.aliyun.com/nexus/content/repositories/central/
24 |
25 | true
26 |
27 |
28 | true
29 |
30 |
31 |
32 |
33 |
34 |
35 | UTF-8
36 | UTF-8
37 |
38 | UTF-8
39 |
40 | 1.5.2.RELEASE
41 |
42 |
43 |
44 | org.springframework.boot
45 | spring-boot-starter-parent
46 | 1.5.2.RELEASE
47 |
48 |
49 |
50 |
51 | org.springframework.boot
52 | spring-boot-starter-web
53 |
54 |
55 |
56 | org.mybatis.spring.boot
57 | mybatis-spring-boot-starter
58 | 1.3.0
59 |
60 |
61 |
62 | org.springframework.boot
63 | spring-boot-starter-redis
64 | 1.4.3.RELEASE
65 |
66 |
67 |
68 | mysql
69 | mysql-connector-java
70 |
71 |
72 | com.alibaba
73 | druid
74 | 1.1.10
75 |
76 |
77 |
78 |
79 | com.github.pagehelper
80 | pagehelper
81 | 4.1.6
82 |
83 |
84 |
85 |
86 |
87 | src
88 |
89 |
90 | maven-compiler-plugin
91 |
92 |
93 | 1.7
94 | 1.7
95 | UTF-8
96 |
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/src/main/java/com/fei/springboot/Application.java:
--------------------------------------------------------------------------------
1 | package com.fei.springboot;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.boot.builder.SpringApplicationBuilder;
7 | import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
8 | import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
9 | import org.springframework.boot.web.support.SpringBootServletInitializer;
10 | import org.springframework.context.annotation.ComponentScan;
11 |
12 | @EnableAutoConfiguration
13 | @ComponentScan(basePackages={"com.fei.springboot"})
14 | @SpringBootApplication
15 | public class Application extends SpringBootServletInitializer implements EmbeddedServletContainerCustomizer{
16 |
17 | @Override
18 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
19 | return application.sources(Application.class);
20 | }
21 |
22 |
23 | public static void main(String[] args) throws Exception {
24 | SpringApplication.run(Application.class, args);
25 | }
26 |
27 | public void customize(ConfigurableEmbeddedServletContainer configurableEmbeddedServletContainer) {
28 | // configurableEmbeddedServletContainer.setPort(9090);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/fei/springboot/config/mybatis/DatasourceConfig.java:
--------------------------------------------------------------------------------
1 | package com.fei.springboot.config.mybatis;
2 |
3 | import java.sql.SQLException;
4 |
5 | import javax.sql.DataSource;
6 |
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import org.springframework.beans.factory.annotation.Value;
10 | import org.springframework.boot.web.servlet.FilterRegistrationBean;
11 | import org.springframework.boot.web.servlet.ServletRegistrationBean;
12 | import org.springframework.context.annotation.Bean;
13 | import org.springframework.context.annotation.Configuration;
14 | import org.springframework.context.annotation.Primary;
15 |
16 | import com.alibaba.druid.pool.DruidDataSource;
17 | import com.alibaba.druid.support.http.StatViewServlet;
18 | import com.alibaba.druid.support.http.WebStatFilter;
19 |
20 | @Configuration
21 | public class DatasourceConfig {
22 | private Logger logger = LoggerFactory.getLogger(DatasourceConfig.class);
23 |
24 | @Value("${spring.datasource.url}")
25 | private String dbUrl;
26 |
27 | @Value("${spring.datasource.type}")
28 | private String dbType;
29 |
30 | @Value("${spring.datasource.username}")
31 | private String username;
32 |
33 | @Value("${spring.datasource.password}")
34 | private String password;
35 |
36 | @Value("${spring.datasource.driver-class-name}")
37 | private String driverClassName;
38 |
39 | @Value("${spring.datasource.initialSize}")
40 | private int initialSize;
41 |
42 | @Value("${spring.datasource.minIdle}")
43 | private int minIdle;
44 |
45 | @Value("${spring.datasource.maxActive}")
46 | private int maxActive;
47 |
48 | @Value("${spring.datasource.maxWait}")
49 | private int maxWait;
50 |
51 | @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
52 | private int timeBetweenEvictionRunsMillis;
53 |
54 | @Value("${spring.datasource.minEvictableIdleTimeMillis}")
55 | private int minEvictableIdleTimeMillis;
56 |
57 | @Value("${spring.datasource.validationQuery}")
58 | private String validationQuery;
59 |
60 | @Value("${spring.datasource.testWhileIdle}")
61 | private boolean testWhileIdle;
62 |
63 | @Value("${spring.datasource.testOnBorrow}")
64 | private boolean testOnBorrow;
65 |
66 | @Value("${spring.datasource.testOnReturn}")
67 | private boolean testOnReturn;
68 |
69 | @Value("${spring.datasource.poolPreparedStatements}")
70 | private boolean poolPreparedStatements;
71 |
72 | @Value("${spring.datasource.filters}")
73 | private String filters;
74 |
75 | @Value("${spring.datasource.connectionProperties}")
76 | private String connectionProperties;
77 |
78 | @Value("${spring.datasource.useGlobalDataSourceStat}")
79 | private boolean useGlobalDataSourceStat;
80 |
81 | @Value("${spring.datasource.druidLoginName}")
82 | private String druidLoginName;
83 |
84 | @Value("${spring.datasource.druidPassword}")
85 | private String druidPassword;
86 |
87 | @Bean(name="dataSource",destroyMethod = "close", initMethod="init")
88 | @Primary //不要漏了这
89 | public DataSource dataSource(){
90 | DruidDataSource datasource = new DruidDataSource();
91 | try {
92 | datasource.setUrl(this.dbUrl);
93 | datasource.setDbType(dbType);
94 | datasource.setUsername(username);
95 | datasource.setPassword(password);
96 | datasource.setDriverClassName(driverClassName);
97 | datasource.setInitialSize(initialSize);
98 | datasource.setMinIdle(minIdle);
99 | datasource.setMaxActive(maxActive);
100 | datasource.setMaxWait(maxWait);
101 | datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
102 | datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
103 | datasource.setValidationQuery(validationQuery);
104 | datasource.setTestWhileIdle(testWhileIdle);
105 | datasource.setTestOnBorrow(testOnBorrow);
106 | datasource.setTestOnReturn(testOnReturn);
107 | datasource.setPoolPreparedStatements(poolPreparedStatements);
108 | datasource.setFilters(filters);
109 | } catch (SQLException e) {
110 | logger.error("druid configuration initialization filter", e);
111 | }
112 | return datasource;
113 | }
114 |
115 | ///////// 下面是druid 监控访问的设置 /////////////////
116 | @Bean
117 | public ServletRegistrationBean druidServlet() {
118 | ServletRegistrationBean reg = new ServletRegistrationBean();
119 | reg.setServlet(new StatViewServlet());
120 | reg.addUrlMappings("/druid/*"); //url 匹配
121 | reg.addInitParameter("allow", "192.168.16.110,127.0.0.1"); // IP白名单 (没有配置或者为空,则允许所有访问)
122 | reg.addInitParameter("deny", "192.168.16.111"); //IP黑名单 (存在共同时,deny优先于allow)
123 | reg.addInitParameter("loginUsername", this.druidLoginName);//登录名
124 | reg.addInitParameter("loginPassword", this.druidPassword);//登录密码
125 | reg.addInitParameter("resetEnable", "false"); // 禁用HTML页面上的“Reset All”功能
126 | return reg;
127 | }
128 |
129 | @Bean(name="druidWebStatFilter")
130 | public FilterRegistrationBean filterRegistrationBean() {
131 | FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
132 | filterRegistrationBean.setFilter(new WebStatFilter());
133 | filterRegistrationBean.addUrlPatterns("/*");
134 | filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); //忽略资源
135 | filterRegistrationBean.addInitParameter("profileEnable", "true");
136 | filterRegistrationBean.addInitParameter("principalCookieName", "USER_COOKIE");
137 | filterRegistrationBean.addInitParameter("principalSessionName", "USER_SESSION");
138 | return filterRegistrationBean;
139 | }
140 |
141 | }
--------------------------------------------------------------------------------
/src/main/java/com/fei/springboot/config/mybatis/MybatisConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.fei.springboot.config.mybatis;
2 |
3 | import java.io.IOException;
4 | import java.util.Properties;
5 |
6 | import javax.sql.DataSource;
7 |
8 | import org.apache.commons.logging.Log;
9 | import org.apache.commons.logging.LogFactory;
10 | import org.apache.ibatis.plugin.Interceptor;
11 | import org.apache.ibatis.session.SqlSessionFactory;
12 | import org.mybatis.spring.SqlSessionFactoryBean;
13 | import org.mybatis.spring.SqlSessionTemplate;
14 | import org.mybatis.spring.annotation.MapperScan;
15 | import org.springframework.beans.factory.annotation.Autowired;
16 | import org.springframework.beans.factory.annotation.Qualifier;
17 | import org.springframework.beans.factory.annotation.Value;
18 | import org.springframework.boot.autoconfigure.AutoConfigureAfter;
19 | import org.springframework.boot.context.properties.ConfigurationProperties;
20 | import org.springframework.context.annotation.Bean;
21 | import org.springframework.context.annotation.Configuration;
22 | import org.springframework.context.annotation.Primary;
23 | import org.springframework.core.io.DefaultResourceLoader;
24 | import org.springframework.core.io.Resource;
25 | import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
26 | import org.springframework.jdbc.datasource.DataSourceTransactionManager;
27 | import org.springframework.transaction.PlatformTransactionManager;
28 | import org.springframework.transaction.annotation.EnableTransactionManagement;
29 | import org.springframework.transaction.annotation.TransactionManagementConfigurer;
30 |
31 | import com.github.pagehelper.PageHelper;
32 | /**
33 | * mybatis的相关配置设置
34 | * @author Jfei
35 | *
36 | */
37 | @Configuration
38 | @AutoConfigureAfter(DatasourceConfig.class)
39 | @ConfigurationProperties
40 | @EnableTransactionManagement
41 | //@MapperScan("com.fei.springboot.dao")
42 | public class MybatisConfiguration implements TransactionManagementConfigurer{
43 |
44 | private static Log logger = LogFactory.getLog(MybatisConfiguration.class);
45 |
46 | // 配置类型别名
47 | @Value("${mybatis.typeAliasesPackage}")
48 | private String typeAliasesPackage;
49 |
50 | // 配置mapper的扫描,找到所有的mapper.xml映射文件
51 | // @Value("${mybatis.mapperLocations : classpath:com/fei/springboot/dao/*.xml}")
52 | @Value("${mybatis.mapperLocations}")
53 | private String mapperLocations;
54 |
55 | // 加载全局的配置文件
56 | @Value("${mybatis.configLocation}")
57 | private String configLocation;
58 |
59 | @Autowired
60 | private DataSource dataSource;
61 |
62 | // 提供SqlSeesion
63 | @Bean(name = "sqlSessionFactory")
64 | @Primary
65 | public SqlSessionFactory sqlSessionFactory() {
66 | try {
67 | SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
68 | sessionFactoryBean.setDataSource(dataSource);
69 |
70 | // 读取配置
71 | sessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
72 |
73 | //设置mapper.xml文件所在位置
74 | Resource[] resources = new PathMatchingResourcePatternResolver().getResources(mapperLocations);
75 | sessionFactoryBean.setMapperLocations(resources);
76 | //设置mybatis-config.xml配置文件位置
77 | sessionFactoryBean.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
78 |
79 | //添加分页插件、打印sql插件
80 | Interceptor[] plugins = new Interceptor[]{pageHelper(),sqlPrintInterceptor()};
81 | sessionFactoryBean.setPlugins(plugins);
82 |
83 | return sessionFactoryBean.getObject();
84 | } catch (IOException e) {
85 | logger.error("mybatis resolver mapper*xml is error",e);
86 | return null;
87 | } catch (Exception e) {
88 | logger.error("mybatis sqlSessionFactoryBean create error",e);
89 | return null;
90 | }
91 | }
92 |
93 | @Bean
94 | public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
95 | return new SqlSessionTemplate(sqlSessionFactory);
96 | }
97 |
98 | //事务管理
99 | @Bean
100 | public PlatformTransactionManager annotationDrivenTransactionManager() {
101 | return new DataSourceTransactionManager(dataSource);
102 | }
103 |
104 | //将要执行的sql进行日志打印(不想拦截,就把这方法注释掉)
105 | @Bean
106 | public SqlPrintInterceptor sqlPrintInterceptor(){
107 | return new SqlPrintInterceptor();
108 | }
109 |
110 | /**
111 | * 分页插件
112 | * @param dataSource
113 | * @return
114 | */
115 |
116 | //
117 | //
118 | //
119 | //
120 | //
121 | //
122 | //
123 | //
124 | //
125 | //
126 | //
127 | //
128 | //
129 | //
130 | //
131 | //
132 | //
133 | //
134 | //
135 | //
136 | //
137 | //
138 | //
139 | //
140 | //
141 | @Bean
142 | public PageHelper pageHelper() {
143 | PageHelper pageHelper = new PageHelper();
144 | Properties p = new Properties();
145 | p.setProperty("offsetAsPageNum", "true");
146 | p.setProperty("rowBoundsWithCount", "true");
147 | p.setProperty("reasonable", "true");
148 | p.setProperty("returnPageInfo", "check");
149 | p.setProperty("params", "count=countSql");
150 | pageHelper.setProperties(p);
151 | return pageHelper;
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/src/main/java/com/fei/springboot/config/mybatis/SqlPrintInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.fei.springboot.config.mybatis;
2 | import org.apache.commons.logging.Log;
3 | import org.apache.commons.logging.LogFactory;
4 | import org.apache.ibatis.executor.Executor;
5 | import org.apache.ibatis.mapping.BoundSql;
6 | import org.apache.ibatis.mapping.MappedStatement;
7 | import org.apache.ibatis.mapping.ParameterMapping;
8 | import org.apache.ibatis.mapping.ParameterMode;
9 | import org.apache.ibatis.plugin.*;
10 | import org.apache.ibatis.reflection.MetaObject;
11 | import org.apache.ibatis.session.Configuration;
12 | import org.apache.ibatis.session.ResultHandler;
13 | import org.apache.ibatis.session.RowBounds;
14 | import org.apache.ibatis.type.TypeHandlerRegistry;
15 |
16 | import java.text.DateFormat;
17 | import java.text.SimpleDateFormat;
18 | import java.util.Date;
19 | import java.util.List;
20 | import java.util.Properties;
21 | import java.util.regex.Matcher;
22 |
23 | /**
24 | * MyBatis 将mybatis要执行的sql拦截打印出来
25 | *
26 | * @since 1.0.0
27 | */
28 | @Intercepts
29 | ({
30 | @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
31 | @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
32 | })
33 | public class SqlPrintInterceptor implements Interceptor {
34 |
35 | private static Log logger = LogFactory.getLog(SqlPrintInterceptor.class);
36 |
37 | private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
38 |
39 | @Override
40 | public Object intercept(Invocation invocation) throws Throwable {
41 | MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
42 | Object parameterObject = null;
43 | if (invocation.getArgs().length > 1) {
44 | parameterObject = invocation.getArgs()[1];
45 | }
46 |
47 | long start = System.currentTimeMillis();
48 |
49 | Object result = invocation.proceed();
50 |
51 | String statementId = mappedStatement.getId();
52 | BoundSql boundSql = mappedStatement.getBoundSql(parameterObject);
53 | Configuration configuration = mappedStatement.getConfiguration();
54 | String sql = getSql(boundSql, parameterObject, configuration);
55 |
56 | long end = System.currentTimeMillis();
57 | long timing = end - start;
58 | if(logger.isInfoEnabled()){
59 | logger.info("执行sql耗时:" + timing + " ms" + " - id:" + statementId + " - Sql:" );
60 | logger.info(" "+sql);
61 | }
62 |
63 | return result;
64 | }
65 |
66 | @Override
67 | public Object plugin(Object target) {
68 | if (target instanceof Executor) {
69 | return Plugin.wrap(target, this);
70 | }
71 | return target;
72 | }
73 |
74 | @Override
75 | public void setProperties(Properties properties) {
76 | }
77 |
78 | private String getSql(BoundSql boundSql, Object parameterObject, Configuration configuration) {
79 | String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
80 | List parameterMappings = boundSql.getParameterMappings();
81 | TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
82 | if (parameterMappings != null) {
83 | for (int i = 0; i < parameterMappings.size(); i++) {
84 | ParameterMapping parameterMapping = parameterMappings.get(i);
85 | if (parameterMapping.getMode() != ParameterMode.OUT) {
86 | Object value;
87 | String propertyName = parameterMapping.getProperty();
88 | if (boundSql.hasAdditionalParameter(propertyName)) {
89 | value = boundSql.getAdditionalParameter(propertyName);
90 | } else if (parameterObject == null) {
91 | value = null;
92 | } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
93 | value = parameterObject;
94 | } else {
95 | MetaObject metaObject = configuration.newMetaObject(parameterObject);
96 | value = metaObject.getValue(propertyName);
97 | }
98 | sql = replacePlaceholder(sql, value);
99 | }
100 | }
101 | }
102 | return sql;
103 | }
104 |
105 | private String replacePlaceholder(String sql, Object propertyValue) {
106 | String result;
107 | if (propertyValue != null) {
108 | if (propertyValue instanceof String) {
109 | result = "'" + propertyValue + "'";
110 | } else if (propertyValue instanceof Date) {
111 | result = "'" + DATE_FORMAT.format(propertyValue) + "'";
112 | } else {
113 | result = propertyValue.toString();
114 | }
115 | } else {
116 | result = "null";
117 | }
118 | return sql.replaceFirst("\\?", Matcher.quoteReplacement(result));
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/src/main/java/com/fei/springboot/config/redis/RedisConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.fei.springboot.config.redis;
2 |
3 | import java.lang.reflect.Method;
4 |
5 | import org.springframework.cache.CacheManager;
6 | import org.springframework.cache.annotation.CachingConfigurerSupport;
7 | import org.springframework.cache.annotation.EnableCaching;
8 | import org.springframework.cache.interceptor.KeyGenerator;
9 | import org.springframework.context.annotation.Bean;
10 | import org.springframework.context.annotation.Configuration;
11 | import org.springframework.data.redis.cache.RedisCacheManager;
12 | import org.springframework.data.redis.connection.RedisConnectionFactory;
13 | import org.springframework.data.redis.core.RedisTemplate;
14 | import org.springframework.data.redis.core.StringRedisTemplate;
15 | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
16 |
17 | import com.fasterxml.jackson.annotation.PropertyAccessor;
18 | import com.fasterxml.jackson.annotation.JsonAutoDetect;
19 | import com.fasterxml.jackson.databind.ObjectMapper;
20 |
21 | @Configuration
22 | @EnableCaching
23 | public class RedisConfiguration extends CachingConfigurerSupport{
24 |
25 | // 缓存数据时Key的生成器,可以依据业务和技术场景自行定制
26 | @Bean
27 | public KeyGenerator keyGenerator() {
28 | return new KeyGenerator() {
29 | @Override
30 | public Object generate(Object target, Method method, Object... params) {
31 | StringBuilder sb = new StringBuilder();
32 | //类名+方法名
33 | sb.append(target.getClass().getName());
34 | sb.append(method.getName());
35 | for (Object obj : params) {
36 | sb.append(obj.toString());
37 | }
38 | return sb.toString();
39 | }
40 |
41 | };
42 | }
43 |
44 | @SuppressWarnings("rawtypes")
45 | @Bean
46 | public CacheManager cacheManager(RedisTemplate redisTemplate) {
47 | RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
48 | //设置缓存过期时间
49 | // rcm.setDefaultExpiration(60);//秒,便于测试
50 | return rcm;
51 | }
52 |
53 | @Bean
54 | public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
55 | StringRedisTemplate template = new StringRedisTemplate(factory);
56 | Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
57 | ObjectMapper om = new ObjectMapper();
58 | om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
59 | om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
60 | jackson2JsonRedisSerializer.setObjectMapper(om);
61 | template.setValueSerializer(jackson2JsonRedisSerializer);
62 | template.afterPropertiesSet();
63 | return template;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/com/fei/springboot/controller/UserController.java:
--------------------------------------------------------------------------------
1 | package com.fei.springboot.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.stereotype.Controller;
5 | import org.springframework.web.bind.annotation.PathVariable;
6 | import org.springframework.web.bind.annotation.RequestMapping;
7 | import org.springframework.web.bind.annotation.ResponseBody;
8 |
9 | import com.fei.springboot.domain.User;
10 | import com.fei.springboot.service.UserService;
11 | import com.github.pagehelper.PageInfo;
12 |
13 | @Controller
14 | @RequestMapping("/user")
15 | public class UserController {
16 |
17 |
18 | @Autowired
19 | private UserService userService;
20 |
21 | @RequestMapping("/hello")
22 | @ResponseBody
23 | public String hello(){
24 | return "hello";
25 | }
26 | /**
27 | * 测试插入
28 | * @return
29 | */
30 | @RequestMapping("/add")
31 | @ResponseBody
32 | public String add(String id,String userName){
33 | User u = new User();
34 | u.setId(id);
35 | u.setUserName(userName);
36 | this.userService.insertUser(u);
37 | return u.getId()+" " + u.getUserName();
38 | }
39 |
40 | /**
41 | * 测试根据id查询
42 | * @return
43 | */
44 | @RequestMapping("/get/{id}")
45 | @ResponseBody
46 | public String findById(@PathVariable("id")String id){
47 | User u = this.userService.findById(id);
48 | return u== null ? "找不到对象" :( u.getId()+" " + u.getUserName());
49 | }
50 |
51 |
52 | /**
53 | * 测试修改
54 | * @return
55 | */
56 | @RequestMapping("/update")
57 | @ResponseBody
58 | public String update(String id,String userName){
59 | User u = new User();
60 | u.setId(id);
61 | u.setUserName(userName);
62 | this.userService.updateUser(u);
63 | return u.getId()+" " + u.getUserName();
64 | }
65 |
66 | /**
67 | * 测试删除
68 | * @return
69 | */
70 | @RequestMapping("/delete/{id}")
71 | @ResponseBody
72 | public String delete(@PathVariable("id")String id){
73 | this.userService.deleteById(id);
74 | return "success";
75 | }
76 |
77 | /**
78 | * 测试全部
79 | * @return
80 | */
81 | @RequestMapping("/deleteAll")
82 | @ResponseBody
83 | public String deleteAll(){
84 | this.userService.deleteAll();
85 | return "success";
86 | }
87 |
88 |
89 |
90 | /**
91 | * 测试分页插件
92 | * @return
93 | */
94 | @RequestMapping("/queryPage")
95 | @ResponseBody
96 | public String queryPage(){
97 | PageInfo page = this.userService.queryPage("tes", 1, 2);
98 | System.out.println("总页数=" + page.getPages());
99 | System.out.println("总记录数=" + page.getTotal()) ;
100 | for(User u : page.getList()){
101 | System.out.println(u.getId() + " \t " + u.getUserName());
102 | }
103 | return page.toString();
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/main/java/com/fei/springboot/dao/UserMapper.java:
--------------------------------------------------------------------------------
1 | package com.fei.springboot.dao;
2 |
3 | import java.util.List;
4 |
5 | import org.apache.ibatis.annotations.Delete;
6 | import org.apache.ibatis.annotations.Insert;
7 | import org.apache.ibatis.annotations.Mapper;
8 | import org.apache.ibatis.annotations.Param;
9 | import org.apache.ibatis.annotations.Select;
10 | import org.apache.ibatis.annotations.Update;
11 |
12 | import com.fei.springboot.domain.User;
13 |
14 | @Mapper
15 | public interface UserMapper {
16 |
17 | @Insert("insert sys_user(id,user_name) values(#{id},#{userName})")
18 | void insert(User u);
19 |
20 | @Update("update sys_user set user_name = #{userName} where id=#{id} ")
21 | void update(User u);
22 |
23 | @Delete("delete from sys_user where id=#{id} ")
24 | void delete(@Param("id")String id);
25 |
26 | @Select("select id,user_name from sys_user where id=#{id} ")
27 | User find(@Param("id")String id);
28 |
29 | //注:方法名和要UserMapper.xml中的id一致
30 | List query(@Param("userName")String userName);
31 |
32 | @Delete("delete from sys_user")
33 | void deleteAll();
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/fei/springboot/dao/UserMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
14 |
--------------------------------------------------------------------------------
/src/main/java/com/fei/springboot/domain/User.java:
--------------------------------------------------------------------------------
1 | package com.fei.springboot.domain;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * 放进redis中的对象,必须Serializable序列化
7 | * @author Jfei
8 | *
9 | */
10 | public class User {
11 |
12 |
13 | private String id;
14 |
15 | private String userName;
16 |
17 | public String getId() {
18 | return id;
19 | }
20 |
21 | public void setId(String id) {
22 | this.id = id;
23 | }
24 |
25 | public String getUserName() {
26 | return userName;
27 | }
28 |
29 | public void setUserName(String userName) {
30 | this.userName = userName;
31 | }
32 |
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/fei/springboot/service/UserService.java:
--------------------------------------------------------------------------------
1 | package com.fei.springboot.service;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.cache.annotation.CacheConfig;
5 | import org.springframework.cache.annotation.CacheEvict;
6 | import org.springframework.cache.annotation.CachePut;
7 | import org.springframework.cache.annotation.Cacheable;
8 | import org.springframework.stereotype.Service;
9 | import org.springframework.transaction.annotation.Isolation;
10 | import org.springframework.transaction.annotation.Propagation;
11 | import org.springframework.transaction.annotation.Transactional;
12 |
13 | import com.fei.springboot.dao.UserMapper;
14 | import com.fei.springboot.domain.User;
15 | import com.github.pagehelper.Page;
16 | import com.github.pagehelper.PageHelper;
17 | import com.github.pagehelper.PageInfo;
18 |
19 | @Service
20 | @CacheConfig(cacheNames="userCache") // 本类内方法指定使用缓存时,默认的名称就是userCache
21 | @Transactional(propagation=Propagation.REQUIRED,readOnly=false,rollbackFor=Exception.class)
22 | public class UserService {
23 |
24 | @Autowired
25 | private UserMapper userMapper;
26 |
27 | // 因为必须要有返回值,才能保存到数据库中,如果保存的对象的某些字段是需要数据库生成的,
28 | //那保存对象进数据库的时候,就没必要放到缓存了
29 | @CachePut(key="#p0.id") //#p0表示第一个参数
30 | //必须要有返回值,否则没数据放到缓存中
31 | public User insertUser(User u){
32 | this.userMapper.insert(u);
33 | //u对象中可能只有只几个有效字段,其他字段值靠数据库生成,比如id
34 | return this.userMapper.find(u.getId());
35 | }
36 |
37 |
38 | @CachePut(key="#p0.id")
39 | public User updateUser(User u){
40 | this.userMapper.update(u);
41 | //可能只是更新某几个字段而已,所以查次数据库把数据全部拿出来全部
42 | return this.userMapper.find(u.getId());
43 | }
44 |
45 | @Cacheable(key="#p0") // @Cacheable 会先查询缓存,如果缓存中存在,则不执行方法
46 | public User findById(String id){
47 | System.err.println("根据id=" + id +"获取用户对象,从数据库中获取");
48 | return this.userMapper.find(id);
49 | }
50 |
51 | @CacheEvict(key="#p0") //删除缓存名称为userCache,key等于指定的id对应的缓存
52 | public void deleteById(String id){
53 | this.userMapper.delete(id);
54 | }
55 |
56 | //清空缓存名称为userCache(看类名上的注解)下的所有缓存
57 | //如果数据失败了,缓存时不会清除的
58 | @CacheEvict(allEntries = true)
59 | public void deleteAll(){
60 | this.userMapper.deleteAll();
61 | }
62 |
63 | public PageInfo queryPage(String userName,int pageNum,int pageSize){
64 | Page page = PageHelper.startPage(pageNum, pageSize);
65 | //PageHelper会自动拦截到下面这查询sql
66 | this.userMapper.query(userName);
67 | return page.toPageInfo();
68 | }
69 |
70 |
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | logging:
2 | config: classpath:logback.xml
3 | path: d:/logs
4 | server:
5 | port: 80
6 | session-timeout: 60
7 |
8 |
9 | mybatis:
10 | mapperLocations: classpath:/com/fei/springboot/dao/*.xml
11 | typeAliasesPackage: com.fei.springboot.dao
12 | mapperScanPackage: com.fei.springboot.dao
13 | configLocation: classpath:/mybatis-config.xml
14 |
15 | spring:
16 | datasource:
17 | name: db
18 | type: com.alibaba.druid.pool.DruidDataSource
19 | url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8
20 | username: root
21 | password: root
22 | driver-class-name: com.mysql.jdbc.Driver
23 | minIdle: 5
24 | maxActive: 100
25 | initialSize: 10
26 | maxWait: 60000
27 | timeBetweenEvictionRunsMillis: 60000
28 | minEvictableIdleTimeMillis: 300000
29 | validationQuery: select 'x'
30 | testWhileIdle: true
31 | testOnBorrow: false
32 | testOnReturn: false
33 | poolPreparedStatements: true
34 | maxPoolPreparedStatementPerConnectionSize: 50
35 | removeAbandoned: true
36 | filters: stat # ,wall,log4j # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
37 | connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
38 | useGlobalDataSourceStat: true # 合并多个DruidDataSource的监控数据
39 | druidLoginName: wjf # 登录druid的账号
40 | druidPassword: wjf # 登录druid的密码
41 | cachePrepStmts: true # 开启二级缓存
42 | redis:
43 | database: 0
44 | host: 127.0.0.1
45 | port: 6379
46 | password:
47 | pool:
48 | max-active: 8
49 | max-wait: -1
50 | max-idle: 8
51 | min-idle: 0
52 | timeout: 0
--------------------------------------------------------------------------------
/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
8 |
9 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
10 |
11 |
12 |
13 |
14 | ${LOG_PATH}/info.log
15 |
16 | ${LOG_PATH}/info-%d{yyyyMMdd}.log.%i
17 |
18 | 500MB
19 |
20 | 2
21 |
22 |
23 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n
24 |
25 |
26 |
27 |
28 |
29 |
30 | ERROR
31 |
32 | ${LOG_PATH}/error.log
33 |
34 | ${LOG_PATH}/error-%d{yyyyMMdd}.log.%i
35 |
36 |
37 | 500MB
38 |
39 | 2
40 |
41 |
42 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/src/main/resources/mybatis-config.xml:
--------------------------------------------------------------------------------
1 |
2 |
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 |
--------------------------------------------------------------------------------