在springboot中使用JPA
最近,在学习jhipster过程中看到JPA,因为之前没结果或者说接触过了也不知道,所以专门记录一下。
定义
Java Persistence API :用于对象持久化的 API
Java EE 5.0 平台标准的 ORM规范,使得应用程序以统一的方式访问持久层
JPA 是 hibernate 的一个抽象(就像JDBC和JDBC驱动的关系)
JPA是规范,Hibernate 是实现
JPA 包括 3方面的技术
- ORM 映射元数据:JPA 支持 XML 和 JDK 5.0 注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中。
- JPA 的 API:用来操作实体对象,执行CRUD操作,框架在后台完成所有的事情,开发者从繁琐的 JDBC和 SQL代码中解脱出来。
- 查询语言(JPQL):这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序和具体的 SQL 紧密耦合。
JPA基本注解
JPA 基本注解:@Entity, @Table, @Id, @GeneratedValue, @Column, @Basic,@Transient, @Temporal, 用 table 来生成主键详解。具体使用时大家可以查询搜索引擎,也可以在使用的查看源代码了解。
springboot 中使用JPA
环境:windows7+idea+jdk8
步骤:
- 使用idea创建一个springboot项目,勾选JPA,thymeleaf等,最终项目生成的pom.xml中要包含:
<!--JPA-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--mysql数据库jdbc驱动(也可以选oracle数据库jdbc驱动)-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
-
配置数据库相关的属性
# 驱动 spring.datasource.driver-class-name=com.mysql.jdbc.Driver # 数据库地址 spring.datasource.url=jdbc:mysql://localhost:3306/jpatest # 数据库用户 spring.datasource.username=root # 数据密码 spring.datasource.password=123456 # 配置了实体类维护数据库表结构的具体行为: # update表示当实体类的属性发生变化时,表结构跟着更新, # create表示启动的时候删除上一次生成的表,并根据实体类重新生成表,这个时候之前表中的数据就会被清空; # create-drop表示启动时根据实体类生成表,但是当sessionFactory关闭的时候表会被删除; # validate表示启动时验证实体类和数据表是否一致; # none表示啥都不做。 spring.jpa.hibernate.ddl-auto=update # 表示hibernate在操作的时候在控制台打印真实的sql语句 spring.jpa.show-sql=true # 表示格式化输出的json字符串 spring.jackson.serialization.indent_output=true
-
定义映射实体
/** * 定义TabProject实体 * 所有的实体类似 */ @Entity @Table(name = "tab_project") public class TabProject implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "pro_name") private String proName; @Column(name = "pro_creater") private String proCreater; @Column(name = "createtime") private LocalDate createtime; @Column(name = "pro_update") private String proUpdate; @Column(name = "updatetime") private LocalDate updatetime; //set,get方法省略 }
-
定义数据访问接口
之前有用过springMVC,大概要分成domain,service,controller这几层,sprinBoot也是一样的,起初我还认为有了JPA之后,只需要中间的repository这一层,就代替了service。所以觉得就可以不需要service这一层,dan其实,在项目中,这一层还是不可少的,因为要写与业务相关的内容在这一层写是最合适的,后期维护也非常方便,repository这一层还是直接与底层数据库交互。
关于数据访问接口的几点
-
继承JpaRepository接口,就自动具备部分数据访问方法,具体可查源码。
-
自定义方法可以按照属性名来查询,但是方法的命名方式是固定的,比如第一个方法和第二个方法,第一个方法表示根据一个属性查询,第二个方法表示根据多个属性查询,findBy、And等可以算作是这里的查询关键字了,如果写作其他名称则系统不能识别,类似的关键字还有Like、Or、Is、Equals、Between等,而这里的findBy关键字又可以被find、read、readBy、query、queryBy、get、getBy等来代替。
-
在查询的过程中我们也可以限制查询结果,这里使用的关键字是top、first等
-
使用NamedQuery来查询,就是直接在实体类上使用@NamedQuery注解来定义查询方法和方法名,一个名称对应一个查询语句。
-
也可以向第三个方法那样添加@Query注解,当我调用这个方法的时候使用这个注解中的sql语句进行查询,方法的参数则是注解中的占位符的值。
-
注意HQL和SQL语句的区别(建议简单的可以学习使用HQL,如果是比较复杂的可以使用SQL)
@Repository public interface TabProjectRepository extends JpaRepository<TabProject, Long> { /** * 使用内部定义方法名称获取数据,不写sql语句 * @param proName * @return * */ TabProject findByProName(String proName); /** *自定义,使用HQL语句 * @param name * @return * */ @Query("select * from TabProject p where p.proName=:name ") TabProject withNameQuery(@Param("name") String name); /** *自定义,使用SQL语句 * @return * */ @Query("select proName,count(id) as total from TabProject p group by proName ",nativeQuery = true) List<Map<String,Object>> getProjectCount(); }
-
-
编写controller
@RestController @RequestMapping("/api") public class ProjectController { @Autowired TabProjectRepository tabProjectRepository; @GetMapping("/tab-projects/name/{proname}") public TabProject findByName(@PathVariable("proname") String proName ){ return tabProjectRepository.findByProName(proName); } @GetMapping("/tab-projects/proname/{proname}") public TabProject withNameQuery(@PathVariable("proname") String proName ){ return tabProjectRepository.withNameQuery(proName); } @GetMapping("/tab-projects/project/count") public TabProject getProjectCount(){ return tabProjectRepository.getProjectCount(); } }
-
后记
至于测试这些东西,就自己去弄了,写单元测试也行,或者直接在浏览器里输入要访问地址,比如http://localhost:8080/api/tab-projects/name/122, 看结果。
-
参考文档