Springboot操作数据库
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
使用maven添加了两个依赖,一个是jpa,一个是mysql。
-
jpa(Java Persistence API)
这个是一套用于Java的数据持久化的规范,只是规范
实现这个的有Hibernate和Toplink,这个依赖添加的就是Hibernate。 -
mysql这个依赖是用来进行数据库连接的
数据库和jpa配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/databasename?serverTimezone=GMT
username: root
password: 123456
jpa:
hibernate:
ddl-auto: update
show-sql: true
进行数据库的连接需要进行一些配置:
- 驱动
- 数据库的地址
- 后面的参数是为了解决数据库的时区和本地时区不一样的错误设置的
- 用户名和密码
对hibernate的配置
- ddl-auto
- update:每次对数据库的操作是更新,前提是要有表
- create:第一次对数据库的操作是要创建一个表,如果已经有了,会把之前的删除在重新创建。
- show-sql:是否打印出sql语句,开发的时候一般选择
true
,这样便于查找错误。
创建表对应的类
如果ddl-auto设置的是true,就会在运行程序的时候再数据库中创建表。那要创建什么样的表呢?这就要创建一个类,在类里面设置的属性就对应着将要创建的表的每一列。
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.math.BigDecimal;
@Entity
public class Luckymoney {
@Id
@GeneratedValue
private Integer id;
private BigDecimal money;
private String producer;
private String consumer;
public Luckymoney() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public BigDecimal getMoney() {
return money;
}
public void setMoney(BigDecimal money) {
this.money = money;
}
public String getProducer() {
return producer;
}
public void setProducer(String producer) {
this.producer = producer;
}
public String getConsumer() {
return consumer;
}
public void setConsumer(String consumer) {
this.consumer = consumer;
}
}
这个类需要
- 属性
- 空构造器
- 每个属性的
getter
和setter
这个类名就会变成自动创建的表的表名
光有这些还不够,还需要有3个注解
- javax.persistence.Entity
这个用来修饰类的,这样编译器就知道这个类需要创建对应的表 - javax.persistence.Id
每个表最好都有一个或多个主键,这个注解就是用来修饰主键的,一般就是id。 - javax.persistence.GeneratedValue
表示对应的属性的值是自增的,每次表添加一个新的元组时,对应的字段的值会自增1
RESTful API 实践
- 对数据库的操作需要用到
Jpa
public interface LuckymoneyRepository
extends JpaRepository<Luckymoney,Integer> {
}
创建一个接口继承JpaRepository
这里需要传入两个泛型,第一个是数据库实体类,即你需要操作的表对应的类。第二个是ID的类型。
- 创建
Controller
在这个Controller中定义了一系列API请求和相应的对于数据库的操作。- 需要一个注解
@RestController
来修饰类 - 创建一个JpaRepository的实例
@Autowired private LuckymoneyRepository repository;
- 需要一个注解
@RestController
public class LuckymoneyController {
@Autowired
private LuckymoneyRepository repository;
/**
* 获取红包列表
*/
@GetMapping("/luckymoneys")
public List<Luckymoney> getList(){
return repository.findAll();
}
/**
* 发红包
*/
@PostMapping("/luckymoney")
public Luckymoney sendMoney(@RequestParam BigDecimal money,
@RequestParam String producer){
Luckymoney luckymoney =new Luckymoney();
luckymoney.setMoney(money);
luckymoney.setProducer(producer);
return repository.save(luckymoney);
}
/**
* 通过id查询红包
*/
@GetMapping("/luckymoneys/{id}")
public Luckymoney findById(@PathVariable Integer id){
return repository.findById(id).orElse(null);
}
/**
* 收红包
*/
@PostMapping("/luckymoneys/{id}")
public Luckymoney update(@RequestParam String consumer,
@PathVariable Integer id){
Optional<Luckymoney> optional = repository.findById(id);
if (optional.isPresent()){
Luckymoney luckymoney=optional.get();
luckymoney.setConsumer(consumer);
return repository.save(luckymoney);
}
return null;
}
}
在方法体里主要就是使用Jpa的方法来进行对于数据库的操作。
//如果这个对象的id是新的,就会往数据库里保存一条新的数据,
//已经存在,则会覆盖,
//所以如果想要更新数据,则需要在获取原来的对象,在原来的对象上进行更改,再调用save
repository.save(luckymoney);
//通过id在数据库里查找,findById的返回值是Optional,
//可以使用get方法来获取Optional里面的对象,但是如果是null就会报错,
//所以这里使用orElse,当null的时候,返回null。
Optional<Luckymoney> optional = repository.findById(id);
repository.findById(id).orElse(null);
事务
在数据库中有一个概念就是事务,事务是由多个操作组合在一起的,要么都执行,要么都不执行。就像银行里中的转账操作,可以看作两个基本操作,从转出方扣钱,向转入的账户加钱,这两个操作肯定是要么都执行,要么都不执行,这体现了原子性
。
那要如何用实现事务呢?
直接上代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
@Service
public class LuckymoneyService {
@Autowired
private LuckymoneyRepository repository;//对数据库进行操作需要用到
@Transactional
public void createTwo(){
Luckymoney luckymoney1=new Luckymoney();
luckymoney1.setMoney(new BigDecimal("520"));
luckymoney1.setProducer("producer");
repository.save(luckymoney1);
Luckymoney luckymoney2=new Luckymoney();
luckymoney2.setMoney(new BigDecimal("1314"));
luckymoney2.setProducer("producer");
repository.save(luckymoney2);
}
}
新建一个Service类,使用@Service
注解
创建事务方法,这里是将两个操作合成一个事务。方法使用@Transactional
注解。
在Controller
里调用
@Autowired
private LuckymoneyService service;
@PostMapping("/luckymoneys/two")
public void creteTwo(){
service.createTwo();
}
这样就好了,但是这里数据库有一个坑,就是我们使用的数据库所用的引擎很可能不支持事务,所以这些代码很有可能没用。所以我们需要在数据库中更改引擎。
我使用的是Navicat对Mysql进行可视化操作,选择对应的表,点击设计表,可以看见这个表的引擎是MyISAM
,而这个引擎恰好不支持事务,这里我把它改成InnoDB
这样就可以实现事务操作了,要么都执行,要么都不执行。
本文参考慕课网的课程:https://www.imooc.com/learn/1192