SpringBoot与数据访问

SpringBoot与数据访问

一、引言

大部分系统都离不开数据访问,数据库包括SQL和NOSQL,SQL是指关系型数据库,常见的有SQL Server,Oracle,MySQL(开源),NOSQL是泛指非关系型数据库,常见的有MongoDB,Redis。

用spring开发时我们常用的ORM框架有JDBC、Mybatis,Hibernate,现在最常用的应该是Mybatis。

在Springboot中对于数据访问层,无论是SQL还是NOSQL,都默认采用整合Spring Data的方式进行统一处理,Springboot会帮我们添加大量自动配置,屏蔽了很多设置。并引入各种xxxTemplate,xxxRepository来简化我们对数据访问层的操作。对我们来说只需要进行简单的设置即可。这篇就来学习springboot整合JDBC,mybatis、JPA。

二、JDBC

jdbc是我们最先学习的一个数据库框架,SpringBoot也进行了相应整合。

2.1、 引入依赖导入jbdc包的坐标

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

2.2、数据源配置

这里我们就要在SpringBoot的配置文件application.yml中导入一些配置例如:驱动之类的。

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
    driver-class-name: com.mysql.cj.jdbc.Driver

我们可以做个测试:

@Autowired
private DataSource dataSource;
@Test
public void test() throws SQLException {
    System.out.println(dataSource.getClass());
    Connection connection = dataSource.getConnection();
    System.out.println(connection);
    connection.close();
}

输出为:com.zaxxer.hikari.HikariDataSource

说明默认数据源是com.zaxxer.hikari.HikariDataSource,而在springboot 2.0之前为org.apache.tomcat.jdbc.pool.DataSource。我们也可以通过改变spring.datasource.type 属性来更改我们想自定义的数据源。数据源的相关配置都在DataSourceProperties,我们可以参考这个类进行配置。

2.3、DataSourceInitializer

DataSourceInitializer里面有两个方法runSchemaScripts()可以运行建表语句,runDataScripts()可以运行插入数据的sql语句。

默认使用schema-.sql创建建表语句,用data-.sql插入数据语句,当然我们也可以自己配置:

而且在最近的SpringBoot的版本中要加上initialization-mode: always数据库才会有反应:

spring:
  datasource:
  	initialization-mode: always
    schema:
     - classpath:department.sql

2.4、操作数据库

查询数据库数据

@Autowired
JdbcTemplate jdbcTemplate;
@Test
public void jdbcTest(){
    List<Map<String, Object>> mapList = jdbcTemplate.queryForList("select * from user ");
    System.out.println(mapList.get(0));
}

返回的值就是数据库中的第一条数据。

三、整合Druid数据源

上面讲到我们有默认的数据源,但一般情况我们还是会使用阿里提供的Druid数据源,因为Druid提供的功能更多,并且能够监控统计,这个时候我们需要先引入pom依赖,然后将spring.datasource.type 修改

3.1使用配置SpootBoot2.0配置yml/properties的方式配置

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

Druid的常用配置如下:其中包含Druid的基本配置以及监控配置

注意:而且这里要注意SpringBoot默认使用的好像是slf4j的方式,所以我们要查看清楚并把它编写成slf4j的日志否则会报错

   # 数据源
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/library?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
    druid:
      # 连接池的配置信息
      # 初始化大小,最小,最大
      initial-size: 5
      min-idle: 5
      maxActive: 20
      # 配置获取连接等待超时的时间
      maxWait: 60000
      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # 配置一个连接在池中最小生存的时间,单位是毫秒
      minEvictableIdleTimeMillis: 300000
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      # 打开PSCache,并且指定每个连接上PSCache的大小
      poolPreparedStatements: true
      maxPoolPreparedStatementPerConnectionSize: 20
      # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
      # DruidFilterConfiguration
      filter:
        slf4j:
          enabled: true
        wall:
          enabled: true
        stat:
          enabled: true
      # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
      connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
      # 配置DruidStatFilter
      web-stat-filter:
        enabled: true
        url-pattern: "/*"
        exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
      # 配置DruidStatViewServlet
      stat-view-servlet:
        url-pattern: "/druid/*"
        # IP白名单(没有配置或者为空,则允许所有访问)
        # allow: 127.0.0.1,192.168.46.120
        # IP黑名单 (存在共同时,deny优先于allow)
        # deny: 192.168.46.121
        #  禁用HTML页面上的“Reset All”功能
        reset-enable: false
        # 登录名
        login-username: admin
        # 登录密码
        login-password: 123456

配置问运行之后可以根据链接http://localhost:8080/druid/login.html,用户名admin,密码123456

3.2SSringBoot1.0加载配置类的方式配置Druid

首先引入与上面所使用的的不同的资源文件

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

Druid的常用配置如下:

注意:这里也要注意我们使用的是slf4j的日志格式所以要改成slf4j

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
    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,slf4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
    initialization-mode: always

但是配置之后不会立即生效,我们还需要编写配置类:

@Configuration
public class DruidConfig {
	@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","");//默认就是允许所有访问
		initParams.put("deny","192.168.15.21");
		bean.setInitParameters(initParams);
		return bean;
	}
	//2、配置一个web监控的filter
	@Bean
	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;
	}
}

四、Mybatis

第一步也是引入依赖:

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

也导入Druid数据源,并加入之前学习Mybatis时用到的实体,而后就可以进行测试,Mybatis的使用也有两种方法,注解版和配置文件版,注解版用的很少,一般都是配置文件。

4.1、注解版

@Mapper
public interface DepartmentMapper {
    @Select("select * from department where id=#{id}")
        Department getDeptById(Integer id);
    @Delete("delete from department where id=#{id}")
        int deleteDeptById(Integer id);
    @Options(useGeneratedKeys = true,keyProperty = "id")
        @Insert("insert into department(departmentName) values(#{departmentName})")
        int insertDept(Department department);
    @Update("update department set departmentName=#{departmentName} where id=#{id}")
        int updateDept(Department department);
}

测试:

@Autowired
UserMapper userMapper;

@Autowired
DepartmentMapper departmentMapper;

@Test
public void mybatisTest(){
    Department deptById = departmentMapper.getDeptById(1);
    System.out.println(deptById);

}

4.2、配置文件版

使用配置文件版方式也很简单,也是先新增一个接口:

@Mapper
public interface UserMapper {
    User queryUserById(Integer id);
}

然后新增一个全局配置文件: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>

然后再引入相应的XXXMapper.xml文件:例如在这里我们就引人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.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>

    <insert id="insertEmp">
        INSERT INTO employee(lastName,email,gender,d_id) VALUES (#{lastName},#{email},#{gender},#{dId})
    </insert>

</mapper>

最后在配置文件中加上扫描文件配置即可:路径在类路径下的mybatis下的xml文件

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

最后点击测试:

    @GetMapping("/emp/{id}")
    public Employee getEmp(@PathVariable("id") Integer id){
        return employeeMapper.getEmpById(id);
    }

Mybatis基本不需要额外配置。

五、JPA

JDBC和Mybatis我们之前都学习过,SpringBoot只不过是帮我们整合配置,而JPA我们之前没有接触过,所以还是要先解释下,了解JPA之前我们先了解Spring Data:

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

Spring Data 主要特点是

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

我们要使用JPA,就是继承JpaRepository,我们只要按照它的命名规范去对命名接口,便可以实现数据库操作功能。

第一步:引入依赖

<!-- springdata jpa依赖 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

第二步:编写表对应实体:

//防止出现空值的情况所以要加上否则就会无法运行处结果
@JsonIgnoreProperties({"hibernateLazyInitializer","handler"})
//使用JPA注解配置映射关系
@Entity//告诉jpa这是一个实体类(和数据表映射类)
@Table(name = "tbl_user")//来指定和哪个数据表对应;如果省略默认就是表名就是类名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;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

第三步:编写仓库接口:

@Repository
public interface OrderRepository extends JpaRepository<Order, Integer> {
}

测试:

@JsonIgnoreProperties(value = {"hibernateLazyInitializer","handler"})
@RestController
public class UserController {

    @Autowired
    UserRepository userRepository;

    @GetMapping("/user/{id}")
    public User getUser(@PathVariable("id") Integer id){
        System.out.println(id);
        User user = userRepository.getOne(1);
        return user;
    }

    @GetMapping("/user")
    public User insertUser(User user){
        User save = userRepository.save(user);
        return save;
    }

}

一个简单的JPA实现完成,当然JPA的内容很多,这里只是一个非常简单的例子,要进一步的学习的话还是要去看官方文档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值