首先创建一个springboot项目,默认加入web依赖,之后使用Spring Date JPA和MySql依赖
使用spring date jpa 需要添加以下依赖:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
接下来将默认的application.properties文件后缀改为.yml或者是.yaml文件,使用更方便,进行配置数据源连接
spring:
datasource:
url: jdbc:mysql://localhost:3306/test
username: root
password: ****
jpa:
show-sql: true
创建数据表"students",并且插入一条记录
CREATE TABLE `students` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`address` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
编写实体类Students类,这里IDEA或者eclipse要装lomback插件,否则要写setter-getter方法,因为lomback会在实体类进行编译的时候根据属性字段加上setter-getter方法
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.io.Serializable;
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Students implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
@Column
private Integer age;
@Column
private String address;
}
编写dao层。JpaRepository是springdata提供的的数据库访问层的工具类,可以大大简化代码的编写。JpaRepository提供了以下方法,可以满足大部分的需求:
import com.example.pojo.Students;
import org.springframework.data.jpa.repository.JpaRepository;
public interface StuRepository extends JpaRepository<Students, Long> {
}
使用JpaRepository默认方法
service层在这里简化了,直接写Controller层代码
import com.example.dao.StuRepository;
import com.example.pojo.Students;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.List;
@RestController
@Slf4j
public class StuController {
@Autowired
private StuRepository stuRepository;
@GetMapping("/findAll")
public List<Stu> findAll() {
List<Stu> stus = stuRepository.findAll();
return stus;
}
/**
* 创建
*
* @return
*/
@GetMapping("/createOne")
public List<Stu> createOne() {
Stu stu = Stu.builder().name("李四").age(12).address("西湖").build();
Stu save = stuRepository.save(stu);
log.info(save.toString());
List<Stu> stus = Arrays.asList(Students.builder().name("李四").age(12).address("西湖").build(),
Studengts.builder().name("王五").age(12).address("南京路").build());
List<Stu> stus1 = stuRepository.saveAll(stus);
return stus1;
}
@GetMapping("/deleteById")
public void deleteById() {
stuRepository.existsById(1L);//判断是否存在
stuRepository.deleteById(1L);//删除
}
/**
* 根据条件查询
*
* @return
*/
@GetMapping("/findByExample")
public List<Stu> findByExample() {
Students stu = Students.builder().age(12).build();
Example<Stu> example = Example.of(stu);
List<Stu> all = stuRepository.findAll(example);
return all;
}
/**
* 实现分页查询
*
* @return
*/
@GetMapping("/findWithPage")
public Page<Stu> findWithPage() {
Students stu = Students.builder().age(12).build();
Example<Stu> example = Example.of(stu);
Page<Stu> all = stuRepository.findAll(example, PageRequest.of(1, 5, Sort.by("name")));
return all;
}
}
启动服务,这里默认是采用Hibernate框架,进行持久化
至于JpaRepository更加详细的教程也可以在网上进行查询,这里我总结的几种方式
使用自定义的方法
自定义的简单查询就是根据方法名来自动生成SQL,主要的语法是findXXBy,readAXXBy,queryXXBy,countXXBy, getXXBy后面跟属性名称。
按照Spring Data的规范,查询方法以find | read | get 开头,涉及查询条件时,条件的属性用条件关键字连接,
要注意的是:条件属性以首字母大写。
例如:StuRepository中添加一个方法
public interface StuRepository extends JpaRepository<Students, Long> {
/**
* 根据名字自定义方法
* @param name
* @param age
* @return
*/
List<Stu> findByNameAndAge(String name, int age);
}
编写一个Controller方法:
/**
* 使用自定义的查询方法
* @return
*/
@GetMapping("/findByNameAndAge")
public List<Students> findByNameAndAge() {
List<Students> stus = stuRepository.findByNameAndAge("李四", 12);
return stus;
}
使用@Query来指定本地查询
有时候可能需要自己编写SQL,那么可以使用@Query来编写自己的SQL语句
public interface StuRepository extends JpaRepository<Students, Long> {
@Query(value="select * from students where name like %?%" ,nativeQuery=true)
List<Stu> findLikeName(String name);
}
事物
spring提供了声明式的事务管理@Transactional
。使用起来非常方便。这里只展示如何使用,具体原理后续再讲。
由于spring的事务管理是通过AOP动态代理实现的,所以调用方与事务方法不得在同一个方法内。
编写一个StuService
@Component
@Slf4j
public class StuService {
@Autowired
private StuRepository stuRepository;
@Transactional(rollbackFor = Exception.class)
public void createStu() {
Students stu = Stu.builder().age(100).address("1111").name("周星星").build();
Students save = stuRepository.save(stu);
log.info(save.toString());
int a = 1/0;
Students = Stu.builder().age(200).address("2222").name("周星星2").build();
Stu save1 = stuRepository.save(stu);
log.info(save1.toString());
}
}
在controller中测试
/**
*事务测试
* @return
*/
@GetMapping("/testTransactional")
public void testTransactional() {
stuService.createStu();
}
注意:这里rollbackFor最好写上,否则可能会存在一些运行时异常不活不到哦。遇到的异常
在这里可能会遇到 time zone时区异常
解决办法:
使用root用户登录mysql,执行命令show variables like '%time_zone%';
发现时区是系统默认的,而默认是美国时区,而我们中国要比他们迟8小时。所以需要对其进行修改:set global time_zone='+8:00';
执行完成之后,再次查询
如果没有变为+8:00,退出客户端,重新登录查询即可。