SpringBoot series (7)-SpringBoot and data access

SpringBoot and data access

Regarding the data access layer, whether it is SQL or NOSQL, SpringBoot adopts the method of integrating Spring Data for unified processing by default, adding a large number of automatic configurations, and shielding many settings. In this one, SpringBoot introduce various xxxTemplate, xxxRepositoryto simplify our operations on the data access layer. For us, only simple settings are required.

SpringBoot uses the following three data access methods

  • JDBC
  • MyBatis
  • JPA

Using JDBC in SpringBoot

  • Create a new project test: springboot_data_jdbc; introduce the corresponding module! Basic module
    Insert picture description here
  • After the project was built, it was discovered that the following launchers were automatically imported for us:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
  • Write a yaml configuration file to connect to the database;
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver
  • After configuring these things, we can go directly to use, because SpringBoot has automatically configured for us by default; go to the test class to test
@SpringBootTest
class SrpingBootDataJdbc1ApplicationTests {
    
    

    //DI注入数据源
    @Autowired
    DataSource dataSource;

    @Test
    void contextLoads() throws SQLException {
    
    
        //看一下默认数据源
        System.out.println(dataSource.getClass());
        //获得连接
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        //关闭连接
        connection.close();
    }
}

Insert picture description here
Here we can see the console output log, we can know that SpringBoot uses class com.zaxxer.hikari.HikariDataSourceas a data source by default , and the relevant configuration of the data source is in DataSourcePropertiesit.

Principle of automatic configuration

Let's search globally and find all the automatic configuration of the data source is in: DataSourceConfiguration file:
Insert picture description here
The imported classes are all under the DataSourceConfigurationconfiguration class. It can be seen that Spring Boot 2.x uses the HikariDataSourcedata source by default , while the previous version, such as Spring Boot 1 .x is used org.apache.tomcat.jdbc.pool.DataSourceby default as the data source;

HikariDataSource 号称 Java WEB 当前速度最快的数据源,相比于传统的 C3P0 、DBCP、Tomcat jdbc 等连接池更加优秀;

  • First of all, according to convention, find the automatic configuration class of jdbc, and then analyze it by consulting the automatic configuration class, and the automatic configuration class of jdbc isorg.springframework.boot.autoconfigure.jdbc
  • For reference DataSourceConfiguration, create a data source according to the configuration, and use the Tomcat connection pool by default; you can use the spring.datasource.typespecified custom data source type;
  • The data sources that SpringBoot can support by default are as follows;
    • org.apache.tomcat.jdbc.pool.DataSource
    • HikariDataSource
    • BasicDataSource

Since there is a default data source, we can of course customize the data source type

/**
 * Generic DataSource configuration.
 */
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type")
static class Generic {
    
    

   @Bean
   public DataSource dataSource(DataSourceProperties properties) {
    
    
       //使用DataSourceBuilder创建数据源,利用反射创建响应type的数据源,并且绑定相关属性
      return properties.initializeDataSourceBuilder().build();
   }

}
  • DataSourceInitializer:ApplicationListener
    • effect:
      • runSchemaScripts(); Run the table creation statement;
      • runDataScripts(); Run the sql statement that inserts the data;

By default, you only need to name the file:

schema-*.sql、data-*.sql
默认规则:schema.sql,schema-all.sql;
可以使用   
	schema:
      - classpath:department.sql
      指定位置

Operation database: JdbcTemplate operation database is automatically configured

  • Write JdbcController:
@Controller
@RequestMapping("/jdbc")
public class JdbcController {
    
    

    @Autowired
    JdbcTemplate jdbcTemplate;

    @ResponseBody
    @GetMapping("/list")
    public List<Map<String, Object>> userList(){
    
    
        String sql = "select * from account";
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
        return maps;
    }
}
//其他的方法大家有兴趣可以自己添加

Insert picture description here

Integrate Druid data sources

A large part of the Java program has to operate the database, in order to improve performance when operating the database, you have to use the database connection pool.

Druid is a database connection pool implementation on the Alibaba open source platform, combining the advantages of C3P0, DBCP and other DB pools, and adding log monitoring.

Druid can well monitor the DB pool connection and the execution of SQL, and it is born to be a DB connection pool for monitoring.

Spring Boot 2.0 and above use Hikari data source by default. It can be said that Hikari and Driud are the best data sources on the current Java Web. Let's focus on how Spring Boot integrates Druid data sources and how to implement database monitoring.

Configure data source

  • Import dependencies
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.21</version>
</dependency>
  • Switch the data source; specify the data source through spring.datasource.type.
    Insert picture description here

  • After the data source is switched, inject the DataSource into the test class, then get it, and the output will tell you whether the switch is successful or not;
    Insert picture description here

  • Switched successfully! Now that the switch is successful, you can set the data source connection initialization size, maximum number of connections, waiting time, minimum number of connections and other settings;

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    #自定义数据源
    type: com.alibaba.druid.pool.DruidDataSource
    
    #   数据源其他配置
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    #   配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

server:
  port: 8081
  • Now you need to bind the parameters in the global configuration file to the DruidDataSource by yourself, and then add it to the container, instead of using the automatic generation of Spring Boot; we need to add the DruidDataSource component to the container by ourselves, and bind the properties;
@Configuration
public class DruidConfig {
    
    

    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druid(){
    
    
        return new DruidDataSource();
    }
}
  • Test it in the test class
@SpringBootTest
class SrpingBootDataJdbc1ApplicationTests {
    
    

    //DI注入数据源
    @Autowired
    DataSource dataSource;

    @Test
    void contextLoads() throws SQLException {
    
    
        //获得连接
        Connection connection = dataSource.getConnection();
        DruidDataSource druidDataSource = (DruidDataSource) dataSource;
        System.out.println("druidDataSource 数据源最大连接数:" + druidDataSource.getMaxActive());
        System.out.println("druidDataSource 数据源初始化连接数:" + druidDataSource.getInitialSize());
        //关闭连接
        connection.close();
    }
}
  • operation result:
    Insert picture description here

Configure Druid data source monitoring

  • Druid data source has the monitoring function, and provides a web interface for users to view, similar to when the router is installed, others also provide a default web page.

So the first step is to set up Druid's back-end management page, such as login account, password, etc.; configure back-end management;

@Configuration
public class DruidConfig {
    
    

    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druid(){
    
    
        return new DruidDataSource();
    }

    //配置Druid的监控
    //1、配置一个管理后台的Servlet
    //配置 Druid 监控管理后台的Servlet;
    //内置 Servlet 容器时没有web.xml文件,所以使用 Spring Boot 的注册 Servlet 方式
    @Bean
    public ServletRegistrationBean statViewServlet(){
    
    
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        Map<String, String> initParam = new HashMap<>();
        initParam.put("loginUsername","admin");//后台管理界面的登录账号
        initParam.put("loginPassword","123456");//后台管理界面的登录密码
        initParam.put("allow","");//默认就是允许所有访问
        //deny:Druid 后台拒绝谁访问
        //initParams.put("xiaozhang", "192.168.1.20");表示禁止此ip访问
        bean.setInitParameters(initParam);
        return bean;
    }

    //2、配置一个web监控的filter
    public FilterRegistrationBean webStatFilter(){
    
    
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());
        Map<String, String> initParams = new HashMap<>();
        initParams.put("exclusions","*.js,*.css,/druid/*");
        bean.setInitParameters(initParams);
        bean.setUrlPatterns(Arrays.asList("/*"));
        return bean;
    }
}

Insert picture description here
Insert picture description here
We can find after running the previous query:
Insert picture description here

SpringBoot integrates MyBatis

  • Import the dependencies required by MyBatis
<dependency>
   <groupId>org.mybatis.spring.boot</groupId>
   <artifactId>mybatis-spring-boot-starter</artifactId>
   <version>2.1.4</version>
</dependency>
  • Configure database connection information

Same as the integration of Druid above

  • Create a table for the database
  • To create a JavaBean is to create it based on the attributes of the data table. The attribute name is best to match the attribute name of the database.

Annotated version

  • Create the mapper directory and the corresponding Mapper interface
@Mapper//指定这是一个操作数据库的mapper
public interface UserMapper {
    
    

    @Select("select * from user where id=#{id}")
    public User getUserById(Integer id);

    @Delete("delete from user where id=#{id}")
    public int deleteUserById(Integer id);

    @Options(useGeneratedKeys = true,keyProperty = "id")
    @Insert("insert into user(username) values(#{username})")
    public int insertUser(User user);

    @Update("update user set username=#{username} where id=#{id}")
    public int updateUser(User user);
}
  • Write control class
@RestController
public class UserController {
    
    

    @Autowired
    UserMapper userMapper ;

    @GetMapping("/user/{id}")
    public User getUser(@PathVariable("id") Integer id){
    
    
        return userMapper .getUserById(id);
    }

    @GetMapping("/user")
    public User insertUser(User user){
    
    
        userMapper .insertUser(user);
        return user;
    }
}
  • Then enter localhost:8080/user/id in the browser
    Insert picture description here

  • When the attribute name of our entity class is inconsistent with that of the database, data etc. cannot be found. In the past, aliases could be set in xml. What should we do now?

  • We can customize the configuration rules of MyBatis; add one to the container ConfigurationCustomizer;

@org.springframework.context.annotation.Configuration
public class MyBatisConfig {
    
    

    @Bean
    public ConfigurationCustomizer configurationCustomizer(){
    
    
        return new ConfigurationCustomizer(){
    
    

            @Override
            public void customize(Configuration configuration) {
    
    
                configuration.setMapUnderscoreToCamelCase(true);
            }
        };
    }
}
  • When we have many Mappers, each Mapper has to get an @Mapper annotation. We can add in the main file:
    Insert picture description here

Configuration file version

mybatis:
  config-location: classpath:mybatis/mybatis-config.xml 指定全局配置文件的位置
  mapper-locations: classpath:mybatis/mapper/*.xml  指定sql映射文件的位置

Integrate SpringData JPA

SpringData provides us with a unified API to operate the data access layer; this is mainly implemented by the Spring Data Commons project. Spring Data Commons allows us to use relational or non-relational data access technologies based on the unified standards provided by Spring. The standards include CRUD (create, get, update, delete), query, sort, and paging related operations.
Insert picture description here
And SpringDataJPA has a unified Repository interface such as

  • Repository<T, ID extends Serializable>Unified interface
  • RevisionRepository<T, ID extends Serializable, N extends Number & Comparable>Based on optimistic locking mechanism
  • CrudRepository<T, ID extends Serializable>Basic CRUD operations
  • PagingAndSortingRepository<T, ID extends Serializable>: Basic CRUD and paging

Integrate SpringData JPA

  • First introduce our dependencies. After introducing the dependencies, unlike the original data access method, we can write an entity class (bean) to map the data table, and configure the mapping relationship;
//使用JPA注解配置映射关系
@Entity //告诉JPA这是一个实体类(和数据表映射的类)
@Table(name = "tbl_user") //@Table来指定和哪个数据表对应;如果省略默认表名就是user;
public class User {
    
    

    @Id //这是一个主键
    @GeneratedValue(strategy = GenerationType.IDENTITY)//自增主键
    private Integer id;

    @Column(name = "last_name",length = 50) //这是和数据表对应的一个列
    private String lastName;
    @Column //省略默认列名就是属性名
    private String email;

  • After creating the entity class and configuring the mapping relationship, we then write a Dao interface to manipulate the data table (Repository) corresponding to the entity class
//继承JpaRepository来完成对数据库的操作
public interface UserRepository extends JpaRepository<User,Integer> {
    
    
}
  • Our jpa uses hibernate by default, so we can perform the following basic configuration in the configuration file
spring:  
 jpa:
    hibernate:
#     更新或者创建数据表结构
      ddl-auto: update
#    控制台显示SQL
    show-sql: true

Guess you like

Origin blog.csdn.net/weixin_43844418/article/details/114315646