1.JPA
JPA (Java Persistence API) 是 Sun 官方提出的 Java 持久化规范。它为 Java 开发人员提供了一种对象 / 关联映射工具来管理 Java 应用中的关系数据。他的出现主要是为了简化现有的持久化开发工作和整合 ORM 技术,结束现在 Hibernate,TopLink,JDO 等 ORM 框架各自为营的局面。值得注意的是,JPA 是在充分吸收了现有 Hibernate,TopLink,JDO 等 ORM 框架的基础上发展而来的,具有易于使用,伸缩性强等优点。JPA 是一套规范,不是一套产品,那么像 Hibernate,TopLink,JDO 他们是一套产品,如果说这些产品实现了这个 JPA 规范,那么我们就可以叫他们为 JPA 的实现产品。
2. 项目搭建
本文采用 IDEA 搭建 Spring Boot 的 JPA 应用,Demo 结构图如下:

3. 具体实现
3.1 配置文件
- pom.xml 里加入 spring-boot-starter-data-jpa 以及 mysql-connector-java 的依赖,如下所示。
1 2 3 4 5 6 7 8 9 10
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.6</version> </dependency>
|
- application.yml 里加入 hibernate、jpa 的配置,以及返回 json 对日期字段的特殊处理配置,注意 time-zone 的设置,须与 mysql 的 url 配置一致,否则会引起时间相差 8 小时的问题。jpa 里的 show-sql 作用,如果设置为 true,执行程序后可以看在控制台里看到 sql 语句,如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| spring: profiles: active: product datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/saascrm?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC username: root password: snail123 jpa: hibernate: ddl-auto: update show-sql: true jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: UTC
|
3.2 分层
为了区别各个模块,为项目建立几个包:controller、Entity、respository、service,这是典型的 MVC 架构,各个层次的代表意义在此不再赘述。
3.3 Respository 层
spring data jpa 让我们解脱了 DAO 层的操作,基本上所有 CRUD 都可以依赖于它来实现,需要实现 JpaRepository 接口
1 2
| public interface UserRepository extends JpaRepository<UserInfo,Long> { }
|
3.4 Entity 层
定义了用户信息表实体 UserInfo,通过 Hibernate 与数据库形成映射关系,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| @Entity @Component public class UserInfo { public UserInfo() { }
@Id @GeneratedValue public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getJobNumber() { return jobNumber; }
public void setJobNumber(String jobNumber) { this.jobNumber = jobNumber; }
public Date getCreateTime() { return createTime; }
public void setCreateTime(Date createTime) { this.createTime = createTime; }
private Long id; private String name; private String jobNumber; private Date createTime;
}
|
3.5 service 层
定义了服务层接口以及服务层接口实现类,如下:
1 2 3 4 5 6 7 8 9
| public interface UserService { List<UserInfo> getUserList(); UserInfo getUserByName(String name); UserInfo addUserInfo(UserInfo userInfo); UserInfo updateUserInfoById(UserInfo userInfo); void deleteUserInfoById(Long Id); List<UserInfo>getCurrentUserList(); Page<UserInfo> getPageUserList(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| @Service public class UserServiceImpl implements UserService{ @Autowired private UserRepository userRepository;
public List<UserInfo> getUserList(){ List<UserInfo> userList=new ArrayList<UserInfo>(); userList=userRepository.findAll(); return userList; }
public UserInfo getUserByName(String name) { return userRepository.findByName(name); }
public UserInfo addUserInfo(UserInfo userInfo) { return userRepository.save(userInfo); }
public UserInfo updateUserInfoById(UserInfo userInfo) { return userRepository.save(userInfo); }
public void deleteUserInfoById(Long id) { userRepository.delete(id); }
public List<UserInfo> getCurrentUserList() { Sort sort=new Sort(Sort.Direction.DESC,"createTime"); return userRepository.findAll(sort);
}
public Page<UserInfo> getPageUserList() { Sort sort=new Sort(Sort.Direction.DESC,"createTime"); Pageable pageable=new PageRequest(0,5,sort); return userRepository.findAll(pageable); }
}
|
3.6 Controller 层
其中,日期格式需要做转换,在需要日期转换的 Controller 中使用 SpringMVC 的注解 @initbinder 和 Spring 自带的 WebDateBinder 类来操作。WebDataBinder 是用来绑定请求参数到指定的属性编辑器。由于前台传到 controller 里的值是 String 类型的,当往 Model 里 Set 这个值的时候,如果 set 的这个属性是个对象,Spring 就会去找到对应的 editor 进行转换,然后再 SET 进去。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| @RestController @RequestMapping(value = "/test") public class TestController {
@Autowired private UserInfo userInfo;
@Resource private UserService userService;
@GetMapping(value = "/getUserList") public List<UserInfo> getUserList() { return userService.getUserList(); }
@GetMapping(value = "/getUserInfo") public UserInfo getUserInfoByName(@RequestParam("name") String name) { return userService.getUserByName(name); }
@GetMapping(value = "/getCurrentUserList") public List<UserInfo> getCurrentUserList(){ return userService.getCurrentUserList(); }
@GetMapping(value="/getPageUserList") public Page<UserInfo> getPageUserList(){ return userService.getPageUserList(); }
@PutMapping(value = "/addUserInfo") public UserInfo addUserInfo(UserInfo userInfo) { return userService.addUserInfo(userInfo); }
@PostMapping(value ="/updateUserInfo") public UserInfo updateUserInfo(UserInfo userInfo){ return userService.updateUserInfoById(userInfo); }
@PostMapping(value="/deleteUserInfo") public void deleteUserInfo(@RequestParam("id") Long id){ userService.deleteUserInfoById(id); }
@InitBinder protected void init(HttpServletRequest request, ServletRequestDataBinder binder) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false)); }
|
4. 测试
Http 定义了与服务器交互的不同方法,最基本的方法有 4 种,分别是 GET,POST,PUT,DELETE。URL 全称是资源描述符,我们可以这样认为:一个 URL 地址,它用于描述一个网络上的资源,而 HTTP 中的 GET,POST,PUT,DELETE 就对应着对这个资源的查,改,增,删 4 个操作。
本文借助 PostMan 工具进行测试,如下图所示。(注意事项,如果选择 PUT 请求,那么只能选 x-www-form-urlencoded)

v1.5.2