对于数据访问层,无论是SQL还是NOSQL, Spring Boot默认采用整合Spring Data的方式进行统一处理,添加大量自动配置,屏蔽了很多设置。引入各种xxxTemplate, xxxRepository来简化我们对数据访问层的操作。对我们来说只需要进行简单的设置即可。我们将在数据访问章节测试使用SQL相关、NOSQL在缓存、消息、检索等章节测试。
– JDBC
– MyBatis
1. 什么是JDBC
JDBC(JavaDataBase Connectivity)就是Java数据库连接,说白了就是用Java语言来操作数据库。原来我们操作数据库是在控制台使用SQL语句来操作数据库,JDBC是用Java语言向数据库发送SQL语句。
2. JDBC原理
早期SUN公司的天才们想编写一套可以连接天下所有数据库的API,但是当他们刚刚开始时就发现这是不可完成的任务,因为各个厂商的数据库服务器差异太大了。后来SUN开始与数据库厂商们讨论,最终得出的结论是,由SUN提供一套访问数据库的规范(就是一组接口),并提供连接数据库的协议标准,然后各个数据库厂商会遵循SUN的规范提供一套访问自己公司的数据库服务器的API出现。SUN提供的规范命名为JDBC,而各个厂商提供的,遵循了JDBC规范的,可以访问自己数据库的API被称之为驱动!
JDBC是接口,而JDBC驱动才是接口的实现,没有驱动无法完成数据库连接!每个数据库厂商都有自己的驱动,用来连接自己公司的数据库。
JDBC的使用参考:JDBC快速入门教程
3. Springboot整合JDBC和数据源
导入依赖
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.22version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jdbcartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
application.yml
spring:
datasource:
username: root
password: 123
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
测试
可以看到springboot的默认数据源是Hikari(号称javaweb最快的数据源)。
要是想换一个数据源,在application.yml中配置数据源,这里我用druid(阿里开源数据源,有监控),配置druid加的配置(使用前需要引入druid的jar包)
问题1 在SpringBoot1.x中, 运行schema.sql不需要配置便可之间运行,但是在SpringBoot2.x中,我们需要在配置文件中配置一下:
问题2 如果这个时候,我们用druid数据源,黄色部分的配置是不起作用的,因为在springboot的DataSourceProperties中,没有属性与yml中的字段匹配。如果要使druid的附加配置生效,要自己写一个配置类。
druid效果
步骤
建立mapper接口。
@Mapper 是 Mybatis 的注解,和 Spring 没有关系,@Repository 是 Spring 的注解,用于声明一个 Bean。(重要)
在 Spring 程序中,Mybatis 需要找到对应的 mapper,在编译的时候动态生成代理类,实现数据库查询功能,所以我们需要在接口上添加 @Mapper 注解。
但是,仅仅使用@Mapper注解,我们会发现,在其他变量中依赖注入,IDEA 会提示错误,但是不影响运行(亲测~)。因为我们没有显式标注这是一个 Bean,IDEA 认为运行的时候会找不到实例注入,所以提示我们错误。
尽管这个错误提示并不影响运行,但是看起来很不舒服,所以我们可以在对应的接口上添加 bean 的声明。
@Repository
//指定这是一个操作数据库的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 department);
@Update("update department set department_name=#{departmentName} where id=#{id}")
public int updateDept(Department department);
}
编写Controller测试
@RestController
public class DeptController {
@Autowired
DepartmentMapper departmentMapper;
@GetMapping("/dept/{id}")
public Department getDepartment(@PathVariable("id") Integer id){
return departmentMapper.getDeptById(id);
}
@GetMapping("/dept")
public Department insertDept(Department department){
departmentMapper.insertDept(department);
return department;
}
}
附加:
如果数据库和bean的字段名对不上,比如数据库用驼峰命名法department_name,而bean用departmentName。需要定义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);
}
};
}
}
基于注解的开发也有其他手段帮助 Mybatis 找到 mapper,那就是 @MapperScan 注解,可以在启动类上添加该注解,自动扫描包路径下的所有接口。
@MapperScan(value = "com.atguigu.springboot.mapper")
@SpringBootApplication
public class SpringbootMybatisApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootMybatisApplication.class, args);
}
}
XML配置文件模式
编写EmployeeMapper接口
@Repository
public interface EmployeeMapper {
public Employee getEmpById(Integer id);
public void insertEmp(Employee employee);
}
编写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="org.mao.springboot_mybatis.mapper.EmployeeMapper">
<select id="getEmpById" resultType="org.mao.springboot_mybatis.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-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>
完成以上,在application.yml中配置:
mybatis:
# 指定全局配置文件位置
config-location: classpath:mybatis/mybatis-config.xml
# 指定sql映射文件位置
mapper-locations: classpath:mybatis/mapper/*.xml
参考:
JDBC的概述
SpringBoot_权威教程_spring boot_springboot核心篇+springboot整合篇-_雷丰阳_尚硅谷