接下来我们可以实现第一个读取数据的服务了。
定义实体类 - POJO
以 Category
这个接口为例,要读取CATEGORY
表的数据,那么首先要有一个实体类与该表做映射。实际上就是Java POJO类,每一个该类的对象,就代表数据库表里的一行。
Category.java
@Entity
@Table(name = "CATEGORY")
public class Category implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "CATEGORY_ID")
private Integer categoryId;
@Column(name = "CATEGORY_NM")
private String categoryNm;
@Column(name = "CREATE_ID")
private String createId;
@Column(name = "UPDATE_ID")
private String updateId;
@Column(name = "CREATE_TS")
private Timestamp createTs;
@Column(name = "UPDATE_TS")
private Timestamp updateTs;
// No-Arg Constructor
// Getter and Setter
}
其中用到的一些Annotation:
@Entity
- 标注在类名上,且该类需要有一个无参构造器和一个主键(实体类不可以是final
的)参考:JPA规范-Entities
@Table
- 指定该类对应的数据库表名,以及所在schema(若有的话)
@Id
- 标识该字段为主键
@Column
- 标识该字段对应在数据库表中某一个列的信息,如对应的名称name = "CATEGORY_ID"
还有很多Annotation这里没有用到,可以参考 Defining JPA Entities 有更详细的说明。
获取数据 - Repository
在Spring Data中,Repository<T, ID>
是一个空的"标记"接口,它的子接口如CrudRepository<T, ID>
和JpaRepository<T, ID>
都提供了一些基本的CRUD操作方法,我们只需要新建一个接口进行继承,并提供实体类
和ID类型
,就可以使用那些方法。
这里我新建了一个CategoryRepository
并继承JpaRepository<T, ID>
接口,类型参数分别是<Category, Integer>
:
CategoryRepository.java
public interface CategoryRepository extends JpaRepository<Category, Integer> {
}
这样便可以使用诸如List<T> findAll();
,这样的基本方法。
业务逻辑 (实际干活层) - Service
在定义好对应的Repository后,就可以在Service层注入CategoryRepository
。调用时可以看到,有很多基本方法都可以调用,它们都来自于接口CrudRepository
或JpaRepository
:
CategoryService.java
@Service
public class CategoryService {
@Autowired
private CategoryRepository categoryRepository;
public List<Category> getAll() {
return categoryRepository.findAll();
}
}
控制器 (对外接口层) - Controller
这层很简单,写好要对外开放的接口即可,这里参考了RESTful接口的设计。
CategoryController.java
@RestController
@RequestMapping("/category")
public class CategoryController {
@Autowired
private CategoryService categoryService;
@GetMapping
public List<Category> getAll() {
return categoryService.getAll();
}
}
关于RESTful的设计,可以参考 RESTful API 设计指南。简而言之的理解,我认为就是使用HTTP动词,URL作为资源。比如
GET /category
,即获取所有的category数据