数据库操作,SpringDataJpa的使用
本节需求:上一节中,我们实现了通过url与服务端进行数据交互,但是这些数据都是写死的,在开发中这些数据是没有什么意义的,一般数据都是存储在数据库中,所以需要对数据库中的数据进行增删改查等操作。本节课就来通过JPA实现对数据库的操作,通过url 来访问数据。
先看下本节的代码结构
本节demo在项目中的demo03下
SpringDataJpa 简介
JPA是一套标准接口,而Hibernate是JPA的实现,SpringData JPA 底层默认实现是使用Hibernate,它提供了一些接口和语法,按照JPA语法规则去实现即可。JPA 入门简单,想要学精难,特别是在一些要求很复杂的数据的时候。
Talk is cheap. Show me the code.
1.导入依赖
在 pop.xml 添加相关依赖,添加后刷新maven
...
<!-- JPA 包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- MYSQL 包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--数据连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
...
2.数据库连接参数配置
配置文件我们使用 .yml 类型,这种方式更简洁,在项目中找到application.properties,改后缀properties为yml即可,至于两者的用法的区别自行百度。
在配置之前请安装好MySQL数据库和创建sduty数据库,以便在项目中使用。
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/study?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
username: root
password: 123456
jpa:
show-sql: true
hibernate:
ddl-auto: update
database: mysql
需要注意的一个参数是 ddl-auto,
- create:每次运行程序时,都会重新创建表,数据会丢失
- create-drop:每次运行程序时会先创建表结构,然后待程序结束时清空表
- upadte:每次运行程序,没有表时会创建表,如果对象发生改变会更新表结构,原有数据不会清空,只会更新(推荐使用)
- validate:运行程序会校验数据与数据库的字段类型是否相同,字段不同会报错
3.创建实体类
JPA规范注解在javax.persistence包下,注意不要引错包,否则报错。
新建一个包 demo03/domain,在这个包下写一个Student 实体类,
@Entity//表示是一个实体类,这个实体类与数据表相互映射,表名默认为类名(小写)
public class Student implements Serializable {
private static final long serialVersionUID = 1546546324464618465L;
@Id//主键
@GeneratedValue(strategy = GenerationType.IDENTITY)//自增
private Long id;
private String name;
private Integer age;
//省略setter/getter
}
建好后重启应用,此时即可创建 student 数据表,可以通过 MySQL 可视化界面工具查看,IDEA本身有MySQL可视化插件,配置一下即可。可参考
4.数据访问层 Repository
/**
* 继承JpaRepository<T,K>,第一个泛型参数是实体对象的名称,第二个是主键类型
* JpaRepository 默认实现了部分CRUD,所以可以直接使用这些简单的功能了,不需要自己实现了。
* 没有默认实现的功能,我们可以根据JPA语法规范写好接口即可,
*
*/
@Repository
public interface StudentRepository extends JpaRepository<Student,Long> {
/**
* 通过 name 查询学生信息
* @param name
* @return
*/
Student findByName(String name);
}
5.增删改查测试
在StudentRepository 类中右键选择goto–>Test–>Create new …,会创建一个测试类,在这个类中我们实现增删改查的测试。
自动创建的这个测试类需要在类上添加注解
@RunWith(SpringRunner.class)
@SpringBootTest
整个测试代码如下:
@RunWith(SpringRunner.class)
@SpringBootTest
public class StudentRepositoryTest {
private static final Logger log = LoggerFactory.getLogger(StudentRepositoryTest.class);
@Autowired
private StudentRepository studentRepository;
/**
* 添加一条数据
*/
@Test
public void save() {
//场景 student 示例并添加数据
Student student = new Student();
student.setName("jack");
student.setAge(16);
// 通过 StudentRepository 接口实现数据存储到数据表中
Student result = studentRepository.save(student);
//打印下结果
log.info("添加数据 name={},age={}", result.getName(), result.getAge());
//打印结果
//Hibernate: insert into student (age, name) values (?, ?)
//INFO 8460 --- [ main] c.e.d.d.r.StudentRepositoryTest : 添加数据 name=jack,age=16
}
/**
* 通过id来删除数据,删除数据没有返回值,可以通过可视化工具查看数据库表中是否存在该数据,或者重新id为1的数据是否存在来验证是否已经成功删除
*/
@Test
public void delete() {
studentRepository.deleteById(1L);
}
/**
* 更新数据,把name为jack 改为 role
*/
@Test
public void update() {
//1.通过某个id来找数据
Student result = studentRepository.findById(1L).orElse(null);
//
if (result != null) {
log.info("更新前的数据 name={},age={}", result.getName(), result.getAge());
result.setName("role");
//保存和更新都用save(),但要保证 自增id不变即可
Student findPO = studentRepository.save(result);
log.info("更新后的数据 name={},age={}", findPO.getName(), findPO.getAge());
} else {
log.info("数据不存在,不能更新");
}
//打印日志,结果是hi更新成功
//2019-06-11 19:12:50.008 INFO 2432 --- [ main] c.e.d.d.r.StudentRepositoryTest : 更新前的数据 name=jack,age=16
//Hibernate: select student0_.id as id1_0_0_, student0_.age as age2_0_0_, student0_.name as name3_0_0_ from student student0_ where student0_.id=?
//Hibernate: update student set age=?, name=? where id=?
//2019-06-11 19:12:50.069 INFO 2432 --- [ main] c.e.d.d.r.StudentRepositoryTest : 更新后的数据 name=role,age=16
}
/**
* 通过名称查找数据
*/
@Test
public void findByName() {
Student result = studentRepository.findByName("role");
if (result != null) {
log.info("查找的数据 name={},age={}", result.getName(), result.getAge());
} else {
log.info("没有名称为 role 学生");
}
//打印结果
//c.e.d.d.r.StudentRepositoryTest : 查找的数据 name=role,age=16
}
}
6.通过接口访问数据库数据
这小节我们通过url来实现新增一个Student和通过name 来查询一个Student。
在demo03包下新建一个包 service,然后创建 StudentService 类,并实现两个接口,如下:
public interface StudentService {
/**
* 新增一个Student对象
* @param student
* @return
*/
Student save(Student student);
/**
* 通过用户名来查找 Student 对象
* @param name
* @return
*/
Student findByName(String name);
}
接着在service 包下新建一个包 impl,再创建StudentService 的实现类 StudentServiceImpl
@Service
public class StudentServiceImpl implements StudentService {
private static final Logger log = LoggerFactory.getLogger(StudentServiceImpl.class);
@Autowired
private StudentRepository studentRepository;
/**
* 新增一个Student对象
*
* @param student
* @return
*/
@Override
public Student save(Student student) {
//在这里处理业务逻辑,这里要看具体情况处理
Student result = studentRepository.save(student);
//打印下结果
log.info("添加数据 name={},age={}", result.getName(), result.getAge());
return result;
}
/**
* 通过用户名来查找 Student 对象
*
* @param name
* @return
*/
@Override
public Student findByName(String name) {
//在这里处理业务逻辑,这里要看具体情况处理
Student result = studentRepository.findByName(name);
log.info("添加数据 name={},age={}", result.getName(), result.getAge());
return result;
}
}
最后在Controller 中进行访问即可,关于Controller 的使用可以参考 上一节,具体代码如下
@RestController
@RequestMapping("/student")
public class StudentController {
@Autowired
private StudentService studentService;
@PostMapping
public Object save(StudentForm studentForm) {
Student student = new Student();
student.setName(studentForm.getName());
student.setAge(studentForm.getAge());
Student result = studentService.save(student);
return result;
}
@GetMapping
public Object findByName(String name) {
Student result = studentService.findByName(name);
return result;
}
}
可以通过Postman 等工具进行测试访问,
添加一个Student
通过name 获取一个Student
总结:
这一节我们实现了 JPA 在Springboot 中的基本使用方式和步骤,并实现了通过 URL 来访问数据库。
- 通过Maven导入依赖
- 数据库连接参数配置
- 创建实体类
- 数据访问层 Repository
- 增删改查测试
- 写业务逻辑层
- 通过url 访问数据