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