温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

SpringBoot与数据访问的用法

发布时间:2021-06-25 11:13:31 来源:亿速云 阅读:107 作者:chen 栏目:大数据

这篇文章主要讲解了“SpringBoot与数据访问的用法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SpringBoot与数据访问的用法”吧!

1. JDBC

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

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
spring:
  datasource:
    username: root
    password: zhangjiahui
    url: jdbc:mysql://192.168.199.172:3306/jdbc
    driver-class-name: com.mysql.cj.jdbc.Driver

效果:

默认是用com.zaxxer.hikari.HikariDataSource作为数据源

数据源相关配置都在DataSourceProperties里面

自动配置原理:

org.springframework.boot.autoconfigure.jdbc
  1. 参考DataSourceConfiguration, 根据配置创建数据源,默认使用HikariDataSource;可以使用spring.datasource.type指定自定义的数据源类型

  2. SpringBoot默认可以支持以下几种数据源

    org.apache.commons.dbcp2.BasicDataSource
    com.zaxxer.hikari.HikariDataSource
    org.apache.tomcat.jdbc.pool.DataSource


  3. 自定义数据源

    @ConditionalOnMissingBean({DataSource.class})
    @ConditionalOnProperty(
        name = {"spring.datasource.type"}
    )
    static class Generic {
        Generic() {
        }
    
        @Bean
        public DataSource dataSource(DataSourceProperties properties) {
            //使用DataSourceBuilder创建数据源,利用反射创建响应type数据源,并且绑定相关属性
            return properties.initializeDataSourceBuilder().build();
        }
    }


  4. DataSourceInitializerInvoker

DataSourceAutoConfiguration

@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class,
      DataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {

DataSourceInitializationConfiguration

@Configuration
@Import({ DataSourceInitializerInvoker.class,
      DataSourceInitializationConfiguration.Registrar.class })
class DataSourceInitializationConfiguration {

DataSourceInitializerInvoker

/**
 * Bean to handle {@link DataSource} initialization by running {@literal schema-*.sql} on
 * {@link InitializingBean#afterPropertiesSet()} and {@literal data-*.sql} SQL scripts on
 * a {@link DataSourceSchemaCreatedEvent}.
 *
 * @author Stephane Nicoll
 * @see DataSourceAutoConfiguration
 */
class DataSourceInitializerInvoker
      implements ApplicationListener<DataSourceSchemaCreatedEvent>, InitializingBean {
    
    @Override
	public void onApplicationEvent(DataSourceSchemaCreatedEvent event) {
		// NOTE the event can happen more than once and
		// the event datasource is not used here
		DataSourceInitializer initializer = getDataSourceInitializer();
		if (!this.initialized && initializer != null) {
			initializer.initSchema();
			this.initialized = true;
		}
	}
  1. DataSourceInitializerInvoker将为我们自动创建表并初始化数据,只需要我们将脚本以特定的命名方法,放置在指定的目录即可:

    默认放在classpath路径下,命名规则如下:

    1. 建表脚本:schema-*.sql

    2. 初始化数据脚本:data-*.sql

自定义路径:

spring:
  datasource:
    schema:
      - classpath:db/department.sql
      - classpath:db/init_department.sql

SpringBoot2.X重要设置项:spring.datasource.initialization-mode 初始化模式(springboot2.0),其中有三个值,always为始终执行初始化,embedded只初始化内存数据库(默认值),如h3等,never为不执行初始化。

注:mysql数据库对大小写敏感

  1. JdbcTemplate自动注入

@Configuration
@ConditionalOnClass({ DataSource.class, JdbcTemplate.class })
@ConditionalOnSingleCandidate(DataSource.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(JdbcProperties.class)
public class JdbcTemplateAutoConfiguration {

2. 整合基本Druid数据源

Druid数据源配置:

  1. 引入数据源

    <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.12</version>
    </dependency>


  2. 数据源属性绑定

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


  3. 属性配置

    spring:
      datasource:
        initialSize: 5
        minIdle: 5
        maxActive: 20
        maxWait: 60000
        timeBetweenEvictionRunMillis: 60000
        minEvictableIdleTimeMillis: 300000
        validationQuery: SELECT 1 FROM DUAL
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        poolPreparedStatements: true
        #配置监控统计拦截的filters,去掉后监控界面sql无法统计,‘wall’用于防火墙
        filters: stat,wall,log4j2
        maxPoolPreparedStatementPerConnectionSize: 20
        useGlobalDataSourceStat: true
        connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500


  4. 配置Servlet和Filter

@Configuration
public class DruidConfig {

    @Bean
    public ServletRegistrationBean statViewServlet() {

        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");

        Map<String, String> initParams = new HashMap<>();
        initParams.put("loginUsername", "admin");
        initParams.put("loginPassword", "admin");
        initParams.put("allow", "");
        initParams.put("deny", "");

        bean.setInitParameters(initParams);

        return bean;
    }

    @Bean
    public FilterRegistrationBean webStatFilter() {
        FilterRegistrationBean bean = new FilterRegistrationBean();

        Map<String, String> initParams = new HashMap<>();
        initParams.put("exclusions", "*.js,*.png,*.io,/druid/*");

        bean.setFilter(new WebStatFilter());
        bean.setUrlPatterns(Arrays.asList("/*"));
        bean.setInitParameters(initParams);

        return bean;
    }
}

3. 整合Mybatis

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

依赖关系:

SpringBoot与数据访问的用法

步骤:

1. 引入依赖、配置属性(见上一节)

2. 建数据库表

3. 创建JavaBean:Department/Employee

4. 实现增删改查

1. 注解版
  1. Mapper

//指定这是一个操作数据库的mapper
@Mapper
public interface DepartmentMapper {

    @Select("SELECT * FROM department WHERE id=#{id}")
    public Department getDeptById(Integer id);

    @Delete("DELETE FROM department WHERE id=#{id}")
    public int deleteDeptById(Integer id);

    @Options(useGeneratedKeys = true, keyProperty = "id")
    @Insert("INSERT INTO department(departmentName) VALUES(#{departmentName})")
    public int insertDept(Department dept);

    @Update("UPDATE department SET departmentName=${departmentName} WHERE id=${id}")
    public int updateDept(Department dept);
}
  1. Controller

@RestController
public class DeptController {

    @Autowired
    DepartmentMapper departmentMapper;

    @GetMapping("/dept/{id}")
    public Department getDept(@PathVariable("id") Integer id) {

        return departmentMapper.getDeptById(id);
    }

    @GetMapping("/dept")
    public Department insertDept(Department department) {
        departmentMapper.insertDept(department);
        return department;
    }
}
  1. 自定义Mybatis配置方法

@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. 配置文件版
  1. Mapper

//@Mapper或者@MapperScan将接口扫描装配到容器中
public interface EmployeeMapper {

    public Employee getEmpById(Integer id);

    public void insertEmp(Employee employee);
}
  1. Controller

@Controller
public class EmpController {

    @Autowired
    EmployeeMapper employeeMapper;

    @ResponseBody
    @GetMapping("/emp/{id}")
    public Employee getEmp(@PathVariable(value = "id") Integer id) {
        Employee employee = employeeMapper.getEmpById(id);

        return employee;
    }
}
  1. 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>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
</configuration>
  1. mapper配置文件EmployeeMapper.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.qiang.springboot.mapper.EmployeeMapper">
    <!--
    public Employee getEmpById(Integer id);

    public void insertEmp(Employee employee);-->
    <select id="getEmpById" resultType="com.qiang.springboot.bean.Employee">
        SELECT * FROM employee WHERE id=#{id}
    </select>

    <insert id="insertEmp">
        INSERT INTO employee(last_name, email, gender, department_id, birth) VALUES(#{lastName}, #{email}, #{gender}, #{departmentId}, CURRENT_DATE);
    </insert>
</mapper>
  1. 主配置文件及mapper文件路径指定

#mybatis相关配置,都以mybatis开头
mybatis:
  #指定主配置文件路径
  config-location: classpath:mybatis/mybatis-config.xml
  #指定mapper配置文件路径(数组,可使用通配符进行匹配)
  mapper-locations: classpath:mybatis/mapper/*.xml

5. 指定Mapper的两种方法

  1. 使用@Mapper注解

    //直接将@Mapper注解加在接口类上,指定这是一个操作数据库的mapper
    @Mapper
    public interface DepartmentMapper {
    
        @Select("SELECT * FROM department WHERE id=#{id}")
        public Department getDeptById(Integer id);
    
        @Delete("DELETE FROM department WHERE id=#{id}")
        public int deleteDeptById(Integer id);
    
        @Options(useGeneratedKeys = true, keyProperty = "id")
        @Insert("INSERT INTO department(departmentName) VALUES(#{departmentName})")
        public int insertDept(Department dept);
    
        @Update("UPDATE department SET departmentName=${departmentName} WHERE id=${id}")
        public int updateDept(Department dept);
    }


  2. 使用@MapperScan(value="mapper-package")注解

    //在SpringBoot主程序上添加注解@MapperScan(value="mapper-package")
    //则mapper-package包下所有类都会被标识为mapper
    @MapperScan(value = "com.qiang.springboot.mapper")
    @SpringBootApplication
    public class SpringBoot06DataMybatisApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringBoot06DataMybatisApplication.class, args);
        }
    
    }


4. 整合JPA

1. Spring Data简介

SpringBoot与数据访问的用法

2. 整合Spring Data JPA

JPA是基于ORM(Object Relational Mapping)思想的

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

@Entity //告诉JPA这是一个实体类(和数据表映射的类)
@Table(name = "tbl_user") //指定和哪个数据表相对应,如果省略此注解,则默认使用小写类名作为映射表名
public class User {

    /**
     * @Id : 告诉JPA这是一个主键字段
     * @GeneratedValue : 设置自增
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) //设置自增
    private Integer id;

    /**
     * @Column : 和数据表中某列对应的属性,默认属性名就是列名
     */
    @Column
    private String lastName;

    /**
     * @Column : 可使用name指定列名,使用length指定列长度
     */
    @Column(name = "user_email", length = 50)
    private String email;
    
    //getter & setter
    //...
}
  1. 编写一个dao接口来操作实体类对应的数据表(Repository)

//Repository必须是一个接口
//继承JpaRepository来完成对数据库的操作
public interface UserRepository extends JpaRepository<User, Integer> {
}
  1. 基本的配置JpaProperties

spring:
  datasource:
    url: jdbc:mysql://192.168.199.172:3306/jpa
    username: root
    password: zhangjiahui
    driver-class-name: com.mysql.cj.jdbc.Driver

  jpa:
    hibernate:
      #更新或者创建数据表结构
      ddl-auto: update
    #在控制台显示SQL
    show-sql: true

JPA 2.x版本后 findOne() 的变化

感谢各位的阅读,以上就是“SpringBoot与数据访问的用法”的内容了,经过本文的学习后,相信大家对SpringBoot与数据访问的用法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI