Spring Data官网:Spring Data官网
数据库相关的启动器: 可以参考官方文档:中文官方文档
整合JDBC
1.新建项目测试,引入相应的基础模块
引入相应的模块发现它帮我们自动导入了相应的的启动器。
<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.编写yml配置文件连接数据库
spring:
datasource:
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
配置完就可以直接去使用了,它给我们配置的默认数据源是HikariDataSource,我们全局搜索,找到数据源的所有自动配置都在:DataSourceAutoConfiguration文件:
可以看出这里导入的类都在DataSourceConfiguration配置类中,HikariDataSource 号称 Java WEB 当前速度最快的数据源,相比于传统的 C3P0 、DBCP、Tomcat jdbc 等连接池更加优秀;
JDBCTemplate
即使不使用第三方数据库操作框架,如Mybatis等,spring本身也对原生的JDBC做了轻量级封装,默认配置好了放在容器当中,即JDBCTemplate。数据库操作的CRUD方法都封装在JDBCTemplate中。JDBCTemplate是自动配置是依赖org.springframework.boot.autoconfigure.jdbc包下的JDBCTemplateConfiguration类。
JDBCTemplate主要提供以下几类方法
- .execute():可以用于执行任何SQL语句,一般用于执行DDL语句。
- update():updatef方法及batchUpdate方法:update方法用于执行新增,修改,删除等语句;batchUpdate方法用于执行批处理相关语句。
- query方法及queryForXXX方法:用于执行查询相关语句。
- call方法:用于执行存储过程,函数相关语句。
3.测试
先编写数据库,编写Controller,注入jdbcTemplate,编写测试方法进行访问测试
@RestController
public class SqlController {
@Autowired//自动注入
JdbcTemplate template;
@RequestMapping("/query")
public List<Map<String,Object>> query(){
List<Map<String, Object>> mapList = template.queryForList("select * from user");
return mapList;
}
@RequestMapping("/update/{id}")
public String update(@PathVariable("id") Integer id){
String sql="update user set name=?,password=? where id="+id;
Object[] objects=new Object[2];
objects[0]="王军";
objects[1]="357753";
template.update(sql,objects);
return "success";
}
@RequestMapping("/add")
public String add(){
String sql="insert into user (id,name,password)values(6,'陈意涵','159951')";
template.update(sql);
return "成功";
}
@RequestMapping("/delete/{id}")
public String delete(@PathVariable("id") Integer id){
String sql="delete from user where id=?";
template.update(sql,id);
return "yes";
}
@RequestMapping("/queryname/{id}")
public List<Map<String,Object>>queryBy(@PathVariable("id") Integer id){
String sql="select * from user where id=?";
List<Map<String, Object>> list = template.queryForList(sql,id);
return list;
}
}
至此为止JDBC整合完毕,但是我们一般都会结合其他数据源来使用,而不会单纯的使用JDBC,以下就是结合阿里巴巴的Druid数据源来为大家演示。
整合Druid数据源
Druid简介
Druid 是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0、DBCP 等 DB 池的优点,同时加入了日志监控。
Druid 可以很好的监控 DB 池连接和 SQL 的执行情况,天生就是针对监控而生的 DB 连接池。
Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。
Spring Boot 2.0 以上默认使用 Hikari 数据源,可以说 Hikari 与 Driud 都是当前 Java Web 上最优秀的数据源,我们来重点介绍 Spring Boot 如何集成 Druid 数据源,如何实现数据库监控。
Github地址:Druid数据源
1.添加Druid数据源依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
2.切换数据源
3.设置数据源连接初始化大小,最大连接数,等待时间,最小连接数等设置项,
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,stat:监控统计、log4j:日志记录、wall:防御sql注入
#如果允许报错,java.lang.ClassNotFoundException: org.apache.Log4j.Properity
#则导入log4j 依赖就行
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionoProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
5.导入Log4j的依赖
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
6.为DruidDataSource绑定全局配置文件中的参数,再添加到容器当中,而不再使用SpringBoot的自动生成了,我们需要自己添加DruidDataSource组件到容器中,并绑定属性
@Configuration
public class DruidConfig {
//将全局配置文件中的前缀为spring.datasource的属性值注入到druid.pool.DruidDataSource的同名参数中
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource getDataSource(){
return new DruidDataSource();
}
7.配置Druid数据源监控
Druid数据源自带监控的功能,提供了一个web界面方便用户查看,所以第一步需要设置 Druid的后台管理页面,配置账号密码等,配置后台管理,监控filter过滤器
@Bean
//相当于web.xml文件
public ServletRegistrationBean statViewServlet(){
ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(),"/druid/*");
HashMap<String,String> initParameters = new HashMap<>();
//增加登录配置参数,其中loginUserName loginPassword是固定的
initParameters.put("loginUsername","admin");
initParameters.put("loginPassword","123456");
//设置谁可以访问
//deny:Druid后台谁拒绝访问
initParameters.put("allow","localhost");
//设置初始参数
bean.setInitParameters(initParameters);
return bean;
}
public FilterRegistrationBean webStarterFilter(){
FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>();
bean.setFilter(new WebStatFilter());
Map<String,String> initParameters = new HashMap<>();
//设置哪些请求或者资源无需统计
// "/*"表示过滤所有请求
initParameters.put("exclusions","/druid/*,*.js,*.css");
bean.setInitParameters(initParameters);
return bean;
}
}
webStatFilter:用于配置web和Druid数据源之间的管理关联监控统计。
配置完毕后,我们可以访问:http://localhost:8080/druid/login.html
输入用户名和密码后,进入页面如下:
只需按需求配置即可,主要起到监控的作用,后台执行sql语句时,此页面会实时监控执行的状况和执行失败的原因。
整合Mybatis
整合测试
1.导入mybatis所需要的启动器,并添加Maven资源过滤器
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
2.配置数据库连接信息(与Druid上述相同,保持不变)
3.创建实体类(导入Lombok使用注解)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String password;
}
4.创建Mapper及对应的xml文件
@Mapper:表示本类是一个mybatis的mapper
@Repository:用在持久层的接口上,这个注解是将接口的一个实现类交给spring管理。
@Mapper
@Repository
public interface UserMapper {
List<User> queryAll();
User queryBy(int id);
int update(User user);
int add(User user);
int delete(int id);
}
xml文件中注意绑定mapper接口
<?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.wang.demo.mapper.UserMapper">
<select id="queryAll" resultType="User">
select * from user;
</select>
<select id="queryBy" resultType="User">
select * from user where id=#{id};
</select>
<update id="update" parameterType="User">
update user set name=#{name},password=#{password} where id=#{id}
</update>
<insert id="add" parameterType="User">
insert into user (id,name,password) values(#{id},#{name},#{password});
</insert>
<delete id="delete" parameterType="int">
delete from user where id=#{id};
</delete>
</mapper>
5.编写Controller层
@RestController//返回的是Json字符串
public class UserController {
@Autowired//注入userMapper
UserMapper userMapper;
@GetMapping("/queryAll")
public List<User> queryAll(){
List<User> userList = userMapper.queryAll();
return userList;
}
@GetMapping("/query/{id}")
public User queryBy(@PathVariable("id") int id){
User user = userMapper.queryBy(id);
return user;
}
@GetMapping("/add")
public String add(User user){
userMapper.add(new User(7,"刘六","852258"));
return "ok";
}
@GetMapping("/update")
public String update(User user){
userMapper.update(new User(1,"张安","658214"));
return "success";
}
@GetMapping("/delete/{id}")
public String delete(@PathVariable("id") int id){
userMapper.delete(id);
return "NoFail";
}
}
启动项目测试就行。
接下来就以Employee与Department为例来演示多表查询,Department与上述User相似省略,重点是Employee,或者参照Mybatis的多对一;
1.新建一个实体类 Employee
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
private Integer id;
private String lastName;
private String email;
//1 male, 0 female
private Integer gender;
private Integer department;
private Date birth;
private Department department; // 冗余设计
}
2.新建EmployeeMapper接口和对应的xml文件
@Mapper
@Repository
public interface EmployeeMapper {
// 获取所有员工信息
List<Employee> getEmployees();
// 新增一个员工
int save(Employee employee);
// 通过id获得员工信息
Employee get(Integer id);
// 通过id删除员工
int delete(Integer id);
}
标签resultMap>中表示两张表的映射属性,select>中的resultMap与resultMap的id值一致。单表操作则是resultType
<?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.kuang.mapper.EmployeeMapper">
<resultMap id="EmployeeMap" type="Employee">
<id property="id" column="eid"/>
<result property="lastName" column="last_name"/>
<result property="email" column="email"/>
<result property="gender" column="gender"/>
<result property="birth" column="birth"/>
<association property="eDepartment" javaType="Department">
<id property="id" column="did"/>
<result property="departmentName" column="dname"/>
</association>
</resultMap>
<select id="getEmployees" resultMap="EmployeeMap">
select e.id as eid,last_name,email,gender,birth,d.id as did,d.department_name as dname
from department d,employee e
where d.id = e.department
</select>
<insert id="save" parameterType="Employee">
insert into employee (last_name,email,gender,department,birth)
values (#{lastName},#{email},#{gender},#{department},#{birth});
</insert>
<select id="get" resultType="Employee">
select * from employee where id = #{id}
</select>
<delete id="delete" parameterType="int">
delete from employee where id = #{id}
</delete>
</mapper>
4.编写Controller层
@RestController
public class EmployeeController {
@Autowired
EmployeeMapper employeeMapper;
// 获取所有员工信息
@GetMapping("/getEmployees")
public List<Employee> getEmployees(){
return employeeMapper.getEmployees();
}
@GetMapping("/save")
public int save(){
Employee employee = new Employee();
employee.setLastName("王昌军");
employee.setEmail("wcj@qq.com");
employee.setGender(1);
employee.setDepartment(101);
employee.setBirth(new Date());
return employeeMapper.save(employee);
}
// 通过id获得员工信息
@GetMapping("/get/{id}")
public Employee get(@PathVariable("id") Integer id){
return employeeMapper.get(id);
}
// 通过id删除员工
@GetMapping("/delete/{id}")
public int delete(@PathVariable("id") Integer id){
return employeeMapper.delete(id);
}
}
跑主代码测试即可。