SpringBoot+Mybatis+Redis basic configuration

In fact, SpringBoot is still relatively unfamiliar. Basically, self-study is completed by online learning resources, so this blog does not belong to the category of knowledge. It is just a detailed annotation of the integrated code after collecting and consulting the information. Not much nonsense, this article is just a record of learning results.

First create the SpringBoot project, I use IDEA software, Eclipse software should be similar to this.

-------------------------------------------About Spring---- -------------------------------------------------

Summary of basic knowledge about mybatis+maven

Detailed configuration of spring+springmvc+mybatis integration in maven

SpringBoot+Mybatis+Redis basic configuration

Vue+Mysql+SpringBoot simple addition, deletion, modification and check

1. Choose create new project

 2. Select the option Spring Inltlalizr on the left, and choose your own JDK version for SDK on the right, and the rest will remain unchanged.

3. Fill in the corresponding picture prompt information in group and arifact.

4. To enter this step, you only need to select the required module.

5. Finally, create the project name and project path.

The above are the steps to create a springboot project. In fact, it is a big push on Baidu and there is no technical difficulty.

You cannot change the created project path, otherwise springboot will not recognize it and report an exception.

Project structure:

The conf package and webapp are packages I created by myself. It is correct to create without these two.

Let me talk about my personal understanding of springboot first!

Mybatis configuration

If you have a certain understanding of other frameworks before learning springboot, then this should not be difficult. From the initial xml configuration to the properties or yml file configuration, it can be achieved with the configuration of the java file. Let's start with the earliest mybatis, the initial configuration of mybatis is a lot of xml, the following example:

Take the mybatis-config.xml file as an example

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 配置全局属性 -->
    <settings>
        <!--允许返回多个结果集-->
        <setting name="multipleResultSetsEnabled" value="true"></setting>
        <!-- 使用jdbc的getGeneratedKeys获取数据库自增主键值 -->
        <setting name="useGeneratedKeys" value="true" />
        <!-- 使用列别名替换列名 默认:true -->
        <setting name="useColumnLabel" value="true" />
        <!-- 开启驼峰命名转换:Table{create_time} -> Entity{createTime} -->
        <setting name="mapUnderscoreToCamelCase" value="true" />
        <!--二级缓存开关-->
        <setting name="cacheEnabled" value="true"></setting>
        <!--允许返回多个结果集-->
        <setting name="multipleResultSetsEnabled" value="true"></setting>
        <!--日志-->
        <setting name="logImpl" value="LOG4J"></setting>
        <!-- 延迟加载总开关( 查询时,关闭关联对象即时加载以提高性能) -->
        <setting name="lazyLoadingEnabled" value="false"/>
        <!-- 侵入懒加载,设置为false则按需加载,否则会全部加载 -->
        <setting name="aggressiveLazyLoading" value="false"/>
        <!--设置一个时限,以决定让驱动器等待数据库回应的多长时间为超时-->
        <setting name="defaultStatementTimeout" value="25000" />
    </settings>
    <!-- mybatis分页插件 -->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>
</configuration>

Then to the application.properties configuration, the following is an example:

#mybatis
#mybatis-config.xml配置文件的路径
#mybatis.configLocation=classpath:mybatis-config.xml
#SQL语句映射文件
#mybatis.mapper-locaitons= classpath*:com/example/mapper/*.xml
mybatis.mapper-locations=classpath*:mapper/*.xml
# 类的别名的包
mybatis.type-aliases-package=com.example.model
#驼峰命名法
mybatis.configuration.mapUnderscoreToCamelCase=true
#允许返回多个结果集
mybatis.configuration.multipleResultSetsEnabled=true
#使用jdbc的getGeneratedKeys获取数据库自增主键值
mybatis.configuration.useGeneratedKeys=true
#日志
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#延迟加载总开关( 查询时,关闭关联对象即时加载以提高性能)
mybatis.configuration.lazyLoadingEnabled=false
#侵入懒加载,设置为false则按需加载,否则会全部加载
mybatis.configuration.aggressiveLazyLoading=false

#pagehelper分页插件配置
pagehelper.helperDialect=mysql
#启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页
pagehelper.reasonable=true
#设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用
pagehelper.offset-as-page-num=true
#设置为true时,使用RowBounds分页会进行count查询
pagehelper.row-bounds-with-count=true

Just like key-value pairs, it simplifies the complex xml code, leaving the most important code, you can try what mybatis can configure in xml, and properties can also be configured.

The yml file is also very similar, because of personal habits, so the properties used, but the yml file is actually more convenient.

In the previous applicationContext.xml configuration, <beans><bean></bean></beans> used @Configuration and @Bean annotations to be replaced. If you want to perform the previous xml configuration, you can use java code, such as the configuration of connecting to the database. It can also be implemented using java code, just like returning to the basic implementation.

But I feel that I can be lazy, so I use the properties configuration.

C3P0 connection pool configuration

Because I used the c3p0 connection pool, I wrote a new application-c3p0.properties file to distinguish it, using @PropertySource("classpath:c3p0.properties") to identify this file.

@PropertySource

It is used to read the configuration file, as long as the file named application-*, use the classpath to input the file you named, and it will be recognized.

However, some configuration is needed to use the c3p0 connection pool. This xml configuration:

<bean class="com.mchange.v2.c3p0.ComboPooledDataSource">
 </bean>

You need DataSoruceConfig.java configuration

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.core.env.Environment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

/**
 * @ClassName DataSourceConfig
 * @Description TODO
 * @Author lisonglin
 * @Date 2019/1/13 15:53
 * @Version 1.0
 */
@Configuration   //声明为配置类,相当于<beans>标签
//加上这个注解,使得支持事务
@EnableTransactionManagement
public class DataSourceConfig {

    @Value(value = "${mybatis.type-aliases-package}")
    private String typeAliasesPackage;

    @Autowired
    private Environment env;

    @Bean(name = "dataSource")  //对象及名称,相当于<bean>标签
    @Primary        //优先注入
    //属性注入,将配置中的c3p0注入
    @ConfigurationProperties(prefix = "c3p0")
    public DataSource createDataSource(){
        return DataSourceBuilder.create() // 创建数据源构建对象
                .type(ComboPooledDataSource.class) // 设置数据源类型
                .build(); // 构建数据源对象
    }

}

The @ConfigurationProperties annotation is actually based on the configuration starting with spring.datasource, which is equivalent to adding a prefix to the front, and the key value needs to be identified by this.

##数据库c3p0
spring.datasource.c3p0.jdbcUrl=mysql://localhost:3306/how2java?useUnicode=true&characterEncoding=utf8&useSSL=false
spring.datasource.c3p0.user=root
spring.datasource.c3p0.password=123456
spring.datasource.c3p0.driverClass=com.mysql.jdbc.Driver

Then there are some c3p0 connection pool management configurations

##连接池大小管理
#连接池中保留的最小连接数。Default:3(规范值:20,可根据系统链路总体性能进行更改)
spring.datasource.c3p0.minPoolSize=2
#连接池中保留的最大连接数。Default:15(规范值:100~500之间,可根据系统链路总体性能进行更改)
spring.datasource.c3p0.maxPoolSize=10
##连接池的大小和连接的生存时间管理规范
##连接的最大空闲时间,单位秒,如果超过这个时间,某个数据库连接还没有被使用,则会断开掉这个连接。如果为0,则永远不会断开连接,即回收此连接。Default:0(规范值:120,无特殊情况不建议修改)
spring.datasource.c3p0.maxIdleTime=120
#当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default:3(规范值:5,无特殊情况不建议修改)
spring.datasource.c3p0.acquireIncrement=3
#初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default:3(规范值:20,可根据系统链路总体性能进行更改)
spring.datasource.c3p0.initialPoolSize=3
##重连接相关规范
##从数据库获取新连接失败后重复尝试的次数。Default:30
spring.datasource.c3p0.acquireRetryAttempts=30
##两次连接中间隔时间,单位毫秒。Default:1000
spring.datasource.c3p0.acquireRetryDelay=1000
spring.datasource.c3p0.breakAfterAcquireFailure=false
spring.datasource.c3p0.testConnectionOnCheckout=false

##当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,如设为0则无限期等待。单位毫秒。Default:0(不建议此配置使用)
#spring.datasource.c3p0.checkoutTimeout=0

##配置连接的生存时间,超过这个时间的连接将由连接池自动断开丢弃掉。当然正在使用的连接不会马上断开,而是等待 它close再断开。配置为0的时候则不会对连接的生存时间进行限制。(规范值:0,除非使用其他类型数据库)
spring.datasource.c3p0.maxConnectionAge=0

##配置PreparedStatement缓存规范
#连接池为数据源缓存的PreparedStatement的总数。default: 0
spring.datasource.c3p0.maxStatements=1000
##定义了连接池内单个连接所拥有的最大缓存statements数。Default:0(规范值:5,无特殊情况不建议修改)
spring.datasource.c3p0.maxStatementsPerConnection=5

##配置连接测试
##SQL检测语句。Default:null
spring.datasource.c3p0.preferredTestQuery=SELECT SYSDATE FROM DUAL
##用来配置测试空闲连接的间隔时间,单位秒。测试方式还是上面的两种之一,因为它保证连接池会每隔一定时间对空闲连接进行一次测试,从而保证有效的空闲连接能每隔一定时间访问一次数据库,为0则不测试。Default:0
spring.datasource.c3p0.idleConnectionTestPeriod=120

##c3p0是异步操作的,缓慢的JDBC操作通过进程完成。扩展这些操作可以有效的提升性能通过多线程实现多个操作同时被执行。Default:3
spring.datasource.c3p0.numHelperThreads=3

Log printout to the console

The mybatis configuration mentioned above, there is a log configuration.

#日志
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

Of course you can also use the log that comes with springboot, but I'll use the familiar configuration.

Before that, pom.xml must be imported.

        <!--日志-->
        <!-- 忽略自带的日志框架. -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j</artifactId>
            <version>1.3.8.RELEASE</version>
        </dependency>

Also use log4j.properties configuration

#---- global logging configuration
#---- level: FATAL,ERROR,WARN,INFO,DEBUG
#---- appender: console, file, mail
### set log levels ###
log4j.rootLogger = INFO,console

### 输出到控制台 ###
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern =  %d{yyyy-MM-dd HH\:mm\:ss} %5p %c{1}:%L - %m%n

### 输出到日志文件 ###
log4j.appender.file = org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.File = ${webapp.root}/WEB-INF/logs/platform.log
log4j.appender.file.DatePattern=_yyyyMMdd'.log'
#log4j.appender.file.Append = true
#log4j.appender.file.Threshold = INFO
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern =%-d{yyyy-MM-dd HH\:mm\:ss}  [ %t\:%r ] - [ %p ]  %m%n

### 打印SQL ###
#log4j.logger.com.ibatis=DEBUG
#log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
#log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
#log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
#log4j.logger.java.sql.ResultSet=DEBUG

#配置logger扫描的包路径  这样才会打印sql
log4j.logger.com.yx.gw.mapper=DEBUG

@Autowired annotation cannot scan Mapper file problem

Regarding the inability of POJO to scan the corresponding Mapper file, the @Autowired annotation is useless. Although it does not affect the operation of the program, the unsightly exclamation mark is still uncomfortable.

Nearly Baidu found that their code also had this problem. After several days of inquiries and attempts, this problem was solved.

Configure with MybatisMapperScannerConfig.java

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

/**
 * @ClassName MyBatisMapperScannerConfig
 * @Description TODO
 * @Author lisonglin
 * @Date 2019/2/9 17:51
 * @Version 1.0
 */
@Configuration
@AutoConfigureAfter(DataSourceConfig.class)//init时指定先后顺序,这里是数据源在mybatis之前配置
public class MyBatisMapperScannerConfig {

    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        //指定xml配置文件的路径
        mapperScannerConfigurer.setBasePackage("com.example.mapper");
        return mapperScannerConfigurer;
    }

}

The most important point comes up. You also need to inject the @Component annotation into the POJO. Add @Component to the mapper interface class under the com.example.mapper package to solve the problem.

Simple implementation of Reids

ReidsConfig.java configuration

@Configuration
// 必须加,使配置生效
@EnableCaching
public class RedisConfiguration extends CachingConfigurerSupport {

    @Bean
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        //使用jackson2替换掉redietempalte本身的序列化
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);

        //利用Jackson 使用 defaultTyping 实现通用的序列化和反序列化
        ObjectMapper om = new ObjectMapper();
        //指定要序列化的域,field,get和set,以及修饰符范围,ANY包括public和private
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //指定序列化输入类型,必须是非final修饰
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        // 配置redisTemplate
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        //配置连接工厂
        template.setConnectionFactory(redisConnectionFactory);
        //指定序列化模式
        template.setKeySerializer(jackson2JsonRedisSerializer); // key序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);// value序列化
        template.setHashKeySerializer(jackson2JsonRedisSerializer);// Hash key序列化
        template.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化
        template.afterPropertiesSet();

        // 开启事务
        template.setEnableTransactionSupport(true);
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

Test class

package com.example.test;

import com.example.Application;
import com.example.model.Category;
import com.example.util.SerializeUtil;
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.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class DemoApplicationTests {

    //字符串存储
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    //对象存储
    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void contextLoads() {
        Category category=new Category();
        category.setId(10);
        category.setName("gfs");
        String serial = SerializeUtil.serial(category);
        redisTemplate.opsForHash().put("id:","name:",serial);
        System.out.println(redisTemplate.getKeySerializer());
        System.out.println(redisTemplate.getValueSerializer());

        String obj = (String)redisTemplate.opsForHash().get("id:", "name:");
        System.out.println(obj);
        Category category1= (Category)SerializeUtil.deserial(obj);
        System.out.println(category1);
        System.out.println(redisTemplate.opsForHash().hasKey("id:", "name:"));



    }

}

Redis properties configuration

#redis
#集群模式
#spring.redis.cluster.nodes=115.xxx.xx.xxx:7000,115.xxx.xx.xxx:7001,...,111.xxx.xxx.xx:7008
#spring.redis.cluster.max-redirects=3
#单机模式
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
spring.redis.timeout=10000

# redis连接池配置
#连接超时时间(毫秒)
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=20
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=3000ms
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=5
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0

The above codes are uploaded to Baidu Cloud, Baidu Cloud connection: link: https://pan.baidu.com/s/16IfdY-KmxBSJGbsSEO-yCg 
Extraction code: 2uq0 is 
recorded!

Welcome everyone to support me! Those with stable income can support it, thank you, Alipay QR code!

Guess you like

Origin blog.csdn.net/qq_41520636/article/details/87192263