淘先锋技术网

首页 1 2 3 4 5 6 7

1.数据源的自动配置

1.1 导入 JDBC 场景

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>

  

导入了 JDBC 场景,官方没有导入数据库驱动。因为官方不知道我们接下来要操作什么数据库。所以我们要导入数据库驱动。

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

注意,SpringBoot 对 mysql 进行了版本仲裁,所以可以不输入版本号。但是要注意驱动版本要与本地数据库版本对应。

 修改数据库驱动版本方法

  • 直接引入具体版本(Maven 就近依赖原则)
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.26</version>
        </dependency>
  • 重新声明版本(Maven 属性的就近优先原则)
    <properties>
        <mysql.version>8.0.26</mysql.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>

1.2 分析自动配置

自动配置的类

1、DataSourceAutoConfiguration   数据源相关的配置

  • 修改数据源相关的配置只需要修改 【spring.datasource】相关的配置,它与 DataSourceProperties 类绑定。
  • 自己在容器中没有 DataSource 时,才会自动配置数据库连接池。
	@Configuration(proxyBeanMethods = false)
	@Conditional(PooledDataSourceCondition.class)
	@ConditionalOnMissingBean({ DataSource.class, XADataSource.class }) //表示容器中没有配置数据源时,才会生效
	@Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,
			DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.OracleUcp.class,
			DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class })
	protected static class PooledDataSourceConfiguration {

	}
  • 底层配置好的数据源是 HikariDataSource

2、DataSourceTransactionManagerAutoConfiguration   事务管理器的自动配置

3、JdbcTemplateAutoConfiguration   JdbcTemplate的自动配置,可以用来对数据库进行 CRUD

  • 可以修改【spring.jdbc】相关的配置项(与 JdbcProperties 类型绑定),来修改 JdbcTemplate。
  • 容器中有 JdbcTemplate,我们可以自动注入来使用它。

4、JndiDataSourceAutoConfiguration   Jndi的自动配置

5、XADataSourceAutoConfiguration    分布式事务相关的自动配置

1.3 修改数据源相关配置项

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

1.4 测试

@Slf4j
@SpringBootTest
class Boot05Web01ApplicationTests {
    @Autowired
    JdbcTemplate jdbcTemplate;

    @Test
    void contextLoads() {
        Long count = jdbcTemplate.queryForObject("select count(*) from tb_account", Long.class);
        log.info("记录总数:{}", count);
    }

}

2.使用 Druid 数据源

durid 官方地址

将第三方技术整合进 SpringBoot 的两种方式: 自定义、 找 starter

2.1 自定义方式

引入依赖

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.21</version>
        </dependency>

配置 Durid 数据源

@Configuration
public class MyDataSourceConfig {
    @ConfigurationProperties("spring.datasource") //将 DruidDataSource 的属性于配置文件绑定
    @Bean
    public DataSource dataSource() throws SQLException {
        DruidDataSource druidDataSource = new DruidDataSource();
//        不需要写死,采用 @ConfigurationProperties 与配置文件绑定
//        druidDataSource.setUrl();
//        druidDataSource.setUsername();
//        druidDataSource.setPassword();
        return druidDataSource;
    }
}

 跟多配置项参考官方文档

配置 Durid 数据源的监控页面:

@Configuration
public class MyDataSourceConfig {
    @ConfigurationProperties("spring.datasource") //将 DruidDataSource 的属性于配置文件绑定
    @Bean
    public DataSource dataSource() throws SQLException {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setFilters("stat,wall"); //stat:启动 SQL 监控功能 ;wall启动防火墙
        return druidDataSource;
    }

    /**
     * 配置 Druid 的监控页功能
     * @return
     */
    @Bean
    public ServletRegistrationBean statViewServlet() {
        StatViewServlet statViewServlet = new StatViewServlet();
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(statViewServlet, "/druid/*");
        servletRegistrationBean.addInitParameter("loginUsername","admin");
        servletRegistrationBean.addInitParameter("loginPassword","admin");
        return servletRegistrationBean;
    }

    /**
     * 配置druid:用于采集 web-jdbc 关联监控的数据
     * @return
     */
    @Bean
    public FilterRegistrationBean webStatFilter() {
        WebStatFilter webStatFilter = new WebStatFilter();
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(webStatFilter);
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/*"));
        filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }
}

2.2 starter 方式

<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>druid-spring-boot-starter</artifactId>
   <version>1.1.17</version>
</dependency>

分析自动配置

@Configuration
@ConditionalOnClass({DruidDataSource.class})
@AutoConfigureBefore({DataSourceAutoConfiguration.class})
@EnableConfigurationProperties({DruidStatProperties.class, DataSourceProperties.class})
@Import({DruidSpringAopConfiguration.class, DruidStatViewServletConfiguration.class, DruidWebStatFilterConfiguration.class, DruidFilterConfiguration.class})
public class DruidDataSourceAutoConfigure {
}
  • 扩展配置项 spring.datasource.druid ,它对应的类型是 DruidStatProperties
  • DruidSpringAopConfiguration :用来监控 SpringBean 的配置项
  • DruidStatViewServletConfiguration :监控页的配置,默认开启【spring.datasource.druid.stat-view-servlet】
  • DruidWebStatFilterConfiguration :Web 监控的配置,默认开启 【spring.datasource.druid.web-stat-filter】
  • DruidFilterConfiguration.class :配置所有 Druid 自己 filter 的配置项。
// 所有的 filters    
    private static final String FILTER_STAT_PREFIX = "spring.datasource.druid.filter.stat";
    private static final String FILTER_CONFIG_PREFIX = "spring.datasource.druid.filter.config";
    private static final String FILTER_ENCODING_PREFIX = "spring.datasource.druid.filter.encoding";
    private static final String FILTER_SLF4J_PREFIX = "spring.datasource.druid.filter.slf4j";
    private static final String FILTER_LOG4J_PREFIX = "spring.datasource.druid.filter.log4j";
    private static final String FILTER_LOG4J2_PREFIX = "spring.datasource.druid.filter.log4j2";
    private static final String FILTER_COMMONS_LOG_PREFIX = "spring.datasource.druid.filter.commons-log";
    private static final String FILTER_WALL_PREFIX = "spring.datasource.druid.filter.wall";
    private static final String FILTER_WALL_CONFIG_PREFIX = "spring.datasource.druid.filter.wall.config";

配置示例

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

    druid:
      filters: stat,wall #开启哪些功能组件
      aop-patterns: com.cj.web.* #Spring 监控包
      stat-view-servlet:  #druid监控页相关配置
        enabled: true
        login-username: admin
        login-password: password
        reset-enable: false
      web-stat-filter: #druid Web监控相关配置
        enabled: true
        url-pattern: /*
        exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'
      filter: #对 filters 的每个组件进行详细配置
        stat:
          enabled: true
          slow-sql-millis: 1000
          log-slow-sql: true
        wall:
          enabled: true
          config:
            drop-table-allow: false #不允许进行删除

3.整合 Mybatis 操作

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.4</version>
</dependency>

3.1 配置模式 

分析

自动配置类如下:

@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties({MybatisProperties.class}) //Mybatis 配置类
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class})
public class MybatisAutoConfiguration implements InitializingBean {
}

@ConfigurationProperties(
    prefix = "mybatis"
)
public class MybatisProperties {
}

由上可知, 可以修改以 mybatis 开始的配置。

之前我们使用的时候是需要编写全局配置文件的,使用 SpringBoot 的 mybatis 场景会自动配置好以下组件:

  • SqlSessionFactory :自动配置好
  • SqlSession :自动配置了 SqlSessionTemplate,SqlSessionTemplate 内部组合了 SqlSession。
  • 只要我们编写的操作 Mybatis 的接口标注了 @Mapper ,就会被自动扫码进来。【@Import({MybatisAutoConfiguration.AutoConfiguredMapperScannerRegistrar.class})】实现了此功能。
    @Configuration
    @Import({MybatisAutoConfiguration.AutoConfiguredMapperScannerRegistrar.class})
    @ConditionalOnMissingBean({MapperFactoryBean.class, MapperScannerConfigurer.class})
    public static class MapperScannerRegistrarNotFoundConfiguration implements InitializingBean {
    }

实践 

yml 配置文件

mybatis:
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml

Mybatis 全局配置文件 mybatis-config.xml

<?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>

</configuration>

 Bean

@Data
public class Account {
    private Long  id;
    private String name;
    private Date createTime;
}

mapper 相关

@Mapper
public interface AccountMapper {
    Account selectById(Long id);
}
<!--AccountMapper.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.cj.web.mapper.AccountMapper">
    <select id="selectById" resultType="com.cj.web.bean.Account">
        select * from tb_account where id = #{id}
    </select>
</mapper>

Service 层

@Service
public class AccountService {
    @Autowired
    AccountMapper accountMapper;

    public Account getById(Long id){
        return accountMapper.selectById(id);
    }
}

controller 层

    @Autowired
    AccountService accountService;

    @ResponseBody
    @GetMapping(value = {"/acct"})
    public Account acct(Long id) {
        return accountService.getById(id);
    }

注意: yml 中的 配置项 【mybatis.configuration】与 【mybatis.config-location】不能同时出现。 因为 他们都表示了全局的配置, 只不过 【mybatis.configuration】 是放在 yml 配置文件配置,而【mybatis.config-location】是在另外的全局配置文件中配置。

我们推荐使用 【mybatis.configuration】。

mybatis.configuration 的使用范例

mybatis:
#  config-location: classpath:mybatis/mybatis-config.xml #使用了 configuration 就不需要使用全局配置文件了
  mapper-locations: classpath:mybatis/mapper/*.xml
  configuration:
    map-underscore-to-camel-case: true #开启驼峰命名

3.2 注解模式+配置模式

我们修改 AccountMapper 如下,将简单的方法写在方法的注解上,负责的方法写在 mapper.xml 里。

@Mapper
public interface AccountMapper {
    @Select("select * from tb_account where id = #{id}") //简单方法可以使用注解,无须在mapper.xml中编写
    Account selectById(Long id);

    void insert(Account account); //复杂方法在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.cj.web.mapper.AccountMapper">

    <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        insert into tb_account (name,age) values (#{name},#{age})
    </insert>
</mapper>

如果觉得在每个 XxxMapper 接口都加上 @Mapper 注解觉得麻烦,可以使用 @MapperScan("packageName") 简化。 @MapperScan 增加在启动类上,Mapper接口就可以不用标注 @Mapper 注解。 但是我们推荐使用 @Mapper 注解

4.整合 Mybatis-Plus 完成 CRUD

Mybatis-Plus(检查 MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

mybatis-plus 官网

在开发 Mybatis-Plus 之前,推荐先安装 MybatisX 快速开发插件

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3.2</version>
        </dependency>

 Mybatis-Plus 自动引入了 Mybatis

 4.1分析自动配置

@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties({MybatisPlusProperties.class})
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisPlusLanguageDriverAutoConfiguration.class})
public class MybatisPlusAutoConfiguration implements InitializingBean {
  • MybatisPlusAutoConfiguration 是自动配置类,MybatisPlusProperties 配置项绑定。mybatis-plus:xxx 就是对 Mybatis-Plus 的定制。
  • SqlSessionFactory 自动配置。底层是容器中默认的数据源。
  • mapperLocations 自动配置了默认值。 建议 xml 映射文件都放在 mapper 文件夹下。

classpath*:/mapper*.xml  是 mapperLocations 的默认值,它的意思为 任意包的类路径下的所有 mapper 文件夹下的所有 xml(包含其子文件夹中的 xml)

  • 容器中也配置好了 SqlSessionTemplate。
  • @Mapper 标注的接口也会被自动扫描。

优点

  • 只要我们的 Mapper 接口继承 BaseMapper 方法,就可以拥有 CRUD 能力,减轻开发工作。
@Mapper
public interface AccountMapper extends BaseMapper<Account> {

}

4.2 实践

Mapper 

@Mapper
public interface AccountMapper extends BaseMapper<Account> {
}

Service

public interface AccountService extends IService<Account> {
}

@Service
public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> implements AccountService {
}

接下来就可以测试CRUD接口了。

@Slf4j
@SpringBootTest
class Boot05Web01ApplicationTests {
    @Autowired
    AccountService accountService;

    @Test
    void list() {
        log.info("列表:{}", accountService.list());
    }

    @Test
    void page() {
        Page<Account> page = new Page<>(1,3);
        Page<Account> accountPage = accountService.page(page);
        log.info("分页:{}, {}, {}", accountPage.getSize(), accountPage.getCurrent(), accountPage.getRecords());
    }

    @Test
    void delete() {
        log.info("列表:{}", accountService.removeById(1));
    }
}

5.Redis

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

5.1 Redis 自动配置

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
  • RedisAutoConfiguration 是自动配置类。RedisProperties 属性类 --> spring.redis 是对 redis 的配置。
  • 连接工厂是准备好的。LettuceConnectionConfiguration、JedisConnectionConfiguration 。
  • 自动注入了 RedisTemplate<Object, Object> (XxxTemplate)。
  • 自动注入了 StringRedisTemplate。key、value 都是 String 的。
  • 底层只要我们使用了 StringRedisTemplate、RedisTemplate 就可以操作 Redis。

5.2 Redis 环境搭建

自行百度安装方法。本人在本机以安装好Redis。

可在 安装目录下的 【redis.windows-service.conf】文件中查看 port 为多少,这就是redis 的端口。作者的本地端口是 6379

5.3 实践 (Lettuce 客户端)

yml 配置文件

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    username:  #未设置用户名
    password:  #未设置密码

测试代码:

@Slf4j
@SpringBootTest
class Boot05Web01ApplicationTests {
    @Autowired
    RedisTemplate redisTemplate;

    @Test
    void redis() {
        ValueOperations<String, String> operations = redisTemplate.opsForValue();
        operations.set("hello","world");
        log.info("设置 完成");
        log.info("hello 的值:{}", operations.get("hello"));
    }

}

5.4 切换到 Jedis 客户端

若要使用 Jedis 客户端,则还需要引入 Jedis 依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>

此时,我们的底层有 Jedis、 Lettuce 这两个客户端。

此时需要在底层指定客户端类型为 Jedis。

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    username:  #未设置用户名
    password:  #未设置密码
    client-type: jedis  #指定客户端类型为 jedis  

测试代码与 Lettuce 客户端的代码一致。