Spring Boot 与 数据访问

JDBC

  • 简介:
    • 对于数据访问层,无论是SQL还是NOSQL,Spring Boot默认采用整合Spring Data的方式进行统一处理,添加大量自动配置,屏蔽了很多设置。引入各种xxxTemplate,xxxRepository来简化我们对数据访问层的操作。对我们来说只需要进行简单的设置即可
  • 整合基本JDBC与数据源
    • 引入依赖:
      • <!--JDBC-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <!--MySQL驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
    • yml文件的简单配置:
      • spring:
          datasource:
            username: root
            password: 123456
            # useUnicode=true&characterEncoding=UTF-8: 解决中文乱码问题
            # serverTimezone=UTC: 其中UTC是统一标准世界时间
            url: jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
            # com.mysql.jdbc.Driver: 老的版本的这个,被替换掉了
            # SpringBoot2.0之后默认的数据源是: com.zaxxer.hikari.HikariDataSource
            driver-class-name: com.mysql.cj.jdbc.Driver
            # 在SpringBoot2.0以上版本需要添加这条命令,表示:Always initialize the datasource
            initialization-mode: always
    • 效果:
      • 默认使用的是:com.zaxxer.hikari.HikariDataSource 作为数据源
      • 数据源的相关配置都在:DataSourceProperties 类中
    • 有关数据源的自动配置原理:
      • org.springframework.boot.autoconfigure.jdbc
      • 1、参考DataSourceConfiguration,根据配置创建数据源,SpringBoot2.0之后默认使用的是HikariDataSource数据源,可以使用spring.datasource.type指定自定义的数据源类型
      • 2、SpringBoot默认可以支持
      • 1、org.apache.tomcat.jdbc.pool.DataSource
        2、com.zaxxer.hikari.HikariDataSource
        3、org.apache.commons.dbcp2.BasicDataSource
        4、也可以指定自己设定的数据源
      • 3、自定义数据源类型:
      • /**
         * Generic DataSource configuration.
         */
        @Configuration(proxyBeanMethods = false)
        @ConditionalOnMissingBean(DataSource.class)
        @ConditionalOnProperty(name = "spring.datasource.type")
        static class Generic {
            @Bean
            DataSource dataSource(DataSourceProperties properties) {
                //initializeDataSourceBuilder方法中返回的是,使用DataSourceBuilder创建数据源,利用反射创建响应type的数据源,并且绑定相关属性
                return properties.initializeDataSourceBuilder().build();
            }
        }
      • 4、DataSourceInitializerInvoker implements ApplicationListener
        • 作用:这个类负责,运行建表语句,并且运行插入数据的SQL语句
        • 默认只需要将文件命名为:
        • schema-*.sql、data-*.sql
          1、默认规则【将sql文件命名为】: schema.sql、schema-all.sql
          
          2、如果不想改名,那么可以使用如下的方式,在yml文件中配置sql文件的路径
              spring:
                datasource:
                  schema:
                    # 如果还有那么重启一行接着写【- classpath:xxxx.sql】
                    - classpath:department.sql
      • 5、操作数据库:自动配置了JdbcTemplate操作数据库
  • 整合Druid数据源

    • //前提是将Druid的数据源进行导入
      /**
      spring:
        datasource:
          username: root
          password: 123456
          # useUnicode=true&characterEncoding=UTF-8: 解决中文乱码问题
          # serverTimezone=UTC: 其中UTC是统一标准世界时间
          url: jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
          # com.mysql.jdbc.Driver: 老的版本的这个,被替换掉了
          # SpringBoot2.0之后默认的数据源是: com.zaxxer.hikari.HikariDataSource
          driver-class-name: com.mysql.cj.jdbc.Driver
          # 在SpringBoot2.0以上版本需要添加这条命令,表示:Always initialize the datasource
          initialization-mode: always
          # 使用type更换数据源DruidDataSource
          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
      */
      
      
      
      @Configuration
      public class DruidConfig {
      
          // @ConfigurationProperties:用于参数绑定,需要指定文件
          @ConfigurationProperties(prefix = "spring.datasource")
          // 将我们创建的数据源加在容器中
          @Bean
          public DataSource druid(){
              return new DruidDataSource();
          }
      
          //配置Druid的监控
          //1、配置一个管理后台的Servlet
          @Bean
          public ServletRegistrationBean statViewServlet(){
              ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
              Map<String,String> initParams = new HashMap<>();
              initParams.put("loginUsername","admin");
              initParams.put("loginPassword","123456");
              initParams.put("allow",""); //不写value的时候是默认所有
              initParams.put("deny","192.168.15.21");
              bean.setInitParameters(initParams);
              return bean;
          }
      
          //2、配置Web一个监控的Filter
          @Bean
          public FilterRegistrationBean webStatFilter(){
              FilterRegistrationBean bean = new FilterRegistrationBean();
              //设置Filter
              bean.setFilter(new WebStatFilter());
      
              Map<String,String> initParams = new HashMap<>();
              //使用初始化的方式告诉Filter那些不拦截
              initParams.put("exclusions","*.js,*.css,/druid/*");
              //添加一些初始化参数
              bean.setInitParameters(initParams);
              //设置Filter拦截那些请求
              bean.setUrlPatterns(Arrays.asList("/*"));
              return bean;
          }
      }
      
  • 整合MyBatis

    • 引入MyBatis依赖

    • <!--MyBatis-->
      <dependency>
          <groupId>org.mybatis.spring.boot</groupId>
          <artifactId>mybatis-spring-boot-starter</artifactId>
          <version>2.1.1</version>
      </dependency>
    • 步骤:

      • 配置数据源相关属性【DruidConfig.class、properties.yml】

      • 给数据库建表【运行建表的sql文件】

      • 创建JavaBean【Employee.java、Department.java】

    • 注解版:

      • //指定这是一个操作数据库的mapper
        @Mapper
        public interface DepertmentMapper {
        
            //查找部门Id
            @Select("SELECT * FROM department WHERE id=#{id}")
            public Department getDeptById(Integer id);
        
            //删除
            @Delete("DELETE FROM department WHERE id=#{id}")
            public int deletDeptById(Integer id);
        
            //插入,因为id是自增的所以不需要插入
            //useGeneratedKeys:是不是使用自动生成的主键; keyProperty:表示那个属性用来封装主键
            @Options(useGeneratedKeys = true,keyProperty = "id")
            @Insert("INSERT INTO department(departmentName) values(#{departmentName})")
            public int insertDept(Department department);
        
            //更新
            @Update("UPDATE department SET departmentName=#{departmentName} WHERE id=#{id}")
            public int updateDept(Department department);
        }
      • 问题:

        • 1、如果在数据库中我们的属性有,例如:department_name的形式【驼峰命名法】,这种情况下,是没办法进行封装的,添加一个如下的Config进行解决

          • 自定义MyBatis的配置规则,给容器中添加一个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);
                        }
                    };
                }
            }
            
        • 2、当mapper文件过多的时候,需要给每个mapper文件的类名上添加一个@Mapper注解,现在觉得太麻烦了,换一种方式,只需要在SpringBoot的主配置类上添加一个注解@MapperScan

          • 作用:使用@MapperScan批量扫描所有的Mapper接口

          • @MapperScan(value = "com.atguigu.springboot.mapper")
            @SpringBootApplication
            public class SpringBoot06DataMybatisApplication {
            
                public static void main(String[] args) {
                    SpringApplication.run(SpringBoot06DataMybatisApplication.class, args);
                }
            
            }
    • 配置文件版:

      • 数据库SQL映射文件

      • <?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.atguigu.springboot.mapper.EmployeeMapper">
            <!--
                public Employee getEmpById(Integer id);
        
                public void insertEmp(Employee employee);
            -->
            <select id="getEmpById" resultType="com.atguigu.springboot.bean.Employee">
                SELECT * FROM employee WHERE id=#{id}
            </select>
        
            <select id="insertEmp">
                INSERT INTO employee(lastName,email,gender,d_id) VALUES (#{lastName},#{email},#{gender},#{dId})
            </select>
        </mapper>
      • 全局配置文件

      • <?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="mapUnderscoreToCamelCase" value="true"/>
            </settings>
        </configuration>
      • 在application.yml中进行配置

      • mybatis:
          # 全局配置文件的位置
          config-location: classpath:mybatis/mybatis-config.xml
          # SQL映射文件,Mapper文件
          mapper-locations: classpath:mybatis/mapper/*.xml
      • 调用Controller进行实现,以及方法实现

      • @GetMapping("/emp/{id}")
        public Employee getEmp(@PathVariable("id") Integer id){
            return employeeMapper.getEmpById(id);
        }
        
        //@Mapper:将接口装配到容器中,但是我们在主配置类中添加了@MapperScan注解,所以这里不需要添加@Mapper注解了
        //@Mapper
        public interface EmployeeMapper {
        
            public Employee getEmpById(Integer id);
        
            public void insertEmp(Employee employee);
        
        }
        
      • 说明:

        • 先完成Controller,从浏览器中得到参数,并调用对应的方法,而对应的方法,需要在xml文件中配置相应的数据库调用,完成后还把相应的xml文件在properties.yml文件中进行配置,整个操作才能生效

    • 总结:

      • 注解版配置文件版 可以共存

  • 整合SpringData JPA

    • 简介:

      • Spring Data 项目的目的是为了简化构建基于 Spring 框架应用的数据访问技术,包括非关系数据库、 Map-Reduce 框架、云数据服务等等;另外也包含对关系数据库的访问支持。

      • 特点

        • ​​​​​​​SpringData为我们提供使用统一的API来对数据访问层进行操作,这主要是Spring Data Commons项目来实现的。Spring Data Commons让我们在使用关系型或者非关系型数据访问技术时都基于Spring提供的统一标准,标准包含了CRUD(创建、获取、更新、删除)、查询、排序和分页的相关操作。

      • ​​​​​​​统一的Repository接口​​​​​​​

        • //统一接口
          @Indexed
          public interface Repository<T, ID> {
          
          //基于乐观锁机制
          @NoRepositoryBean
          public interface RevisionRepository<T, ID, N extends Number & Comparable<N>> extends Repository<T, ID> {
          
          //基本CRUD操作
          @NoRepositoryBean
          public interface CrudRepository<T, ID> extends Repository<T, ID> {
          
          //基本CRUD及分页
          @NoRepositoryBean
          public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
      • 提供数据访问模板类 xxxTemplate

        • 如:MongoTemplate、RedisTemplate等

      • JPA与Spring Data

        • JpaRepository基本功能

          • 编写接口继承JpaRepository既有crud及分页等基本功能

        • 定义符合规范的方法命名

          • 在接口中只需要声明符合规范的方法,即拥有对应的功能

        • @Query自定义查询,定制查询SQL

        • Specifications查询(Spring Data JPA支持JPA2.0的Criteria查询)

    • ​​​​​​​​​​​​​​​​​​​​​整合SpringData API​​​​​​​:

      • ​​​​​​​JPA:基于ORM(Object Relational Mapping)思想

      • 步骤:

        • ​​​​​​​编写一个实体类(bean)和数据表进行映射,并且配置好映射关系

        • //使用JPA注解配置映射关系
          //@Entity:告诉JPA这是一个实体类(和数据表映射的类)
          @Entity
          //@Table:来指定和那个数据表对应,如果省略默认表名就是类名小写user
          @Table(name = "tb1_user")
          //如果实体类中没有以下这个注解会报错:主要原因是jackson把懒加载也作为pojo进行序列化了
          //解决方法就是添加:@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
          @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
          public class User {
          
              //这是一个主键
              @Id
              //自增主键
              @GeneratedValue(strategy = GenerationType.IDENTITY)
              private Integer id;
              //这是和数据表对应的一个列
              @Column(name = "last_name",length = 50)
              private String lastName;
              //省略默认列名就是属性名
              @Column
              private String email;
        • 编写一个Dao接口来操作实体类对应的数据表(Repository

        • //继承JpaRepository来完成对数据库的操作
          /**
           * JpaRepository<User,Integer>
           *     User:表示我们要操作的那个实体类
           *     Integer:传的是User中主键的类型
           */
          public interface UserRepository extends JpaRepository<User,Integer> {
          
          }
        • 基本的配置(JpaProperties

        • 测试类(Controller

        • @RestController
          public class UserController {
          
              @Autowired
              UserRepository userRepository;
          
              @GetMapping("/user/{id}")
              public User getUser(@PathVariable("id") Integer id){
                  User user = userRepository.getOne(id);
                  return user;
              }
          
              @GetMapping("/user")
              public User insertUser(User user){
                  User save = userRepository.save(user);
                  return save;
              }
          }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值