在 SpringBoot 项目中使用 JPA
新建项目,增加依赖
在 Intellij IDEA 里面新建一个空的 SpringBoot 项目。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
准备数据库环境
新建数据库test 表User
项目配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT
username: root
password: root
jpa:
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect #使用InnoDB引擎
show-sql: true #控制台打印sql
hibernate:
ddl-auto: create #根据实体自动建表
- spring.jpa.show-sql=true 配置在日志中打印出执行的 SQL 语句信息。
- spring.jpa.hibernate.ddl-auto=create 配置指明在程序启动的时候要删除并且创建实体类对应的表。这个参数很危险,因为他会把对应的表删除掉然后重建。所以千万不要在生成环境中使用。只有在测试环境中,一开始初始化数据库结构的时候才能使用一次。
- spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect 。在 SrpingBoot 2.0 版本中,Hibernate 创建数据表的时候,默认的数据库存储引擎选择的是 MyISAM 。这个参数是在建表的时候,将默认的存储引擎切换为 InnoDB 用的。
建立第一个数据实体类
import lombok.Data;
import javax.persistence.*;
@Entity
@Table(name = "user")
@Data
public class User {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
Integer id;
@Column(length = 50, nullable = false)
String name;
@Column(length = 150, nullable = false)
String password;
}
其中:
- @Entity 是一个必选的注解,声明这个类对应了一个数据库表。
- @Table(name = "AUTH_USER") 是一个可选的注解。声明了数据库实体对应的表信息。包括表名称、索引信息等。这里声明这个实体类对应的表名是 AUTH_USER。如果没有指定,则表名和实体的名称保持一致。
- @Id 注解声明了实体唯一标识对应的属性。
- @Data省略get set方法
- @Column(length = 32) 用来声明实体属性的表字段的定义。默认的实体每个属性都对应了表的一个字段。字段的名称默认和属性名称保持一致(并不一定相等)。字段的类型根据实体属性类型自动推断。这里主要是声明了字符字段的长度。如果不这么声明,则系统会采用 255 作为该字段的长度
以上配置全部正确,则这个时候运行这个项目,我们就可以看到日志中如下的内容:
Hibernate: drop table if exists user
Hibernate: create table user (id int not null, account name(50), password varchar(150), primary key (id)) engine=InnoDB
实现一个持久层服务
在 Spring Data JPA 的世界里,实现一个持久层的服务是一个非常简单的事情。以上面的 UserDO 实体对象为例,我们要实现一个增加、删除、修改、查询功能的持久层服务,那么我只需要声明一个接口,这个接口继承
org.springframework.data.repository.Repository<T, ID> 接口或者他的子接口就行。
import com.zh.program.Entrty.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserDao extends JpaRepository<User, Integer> {
}
此时便可以编写测试方法了:
@Controller
public class TestController {
@Autowired
private UserDao userDao;
@ResponseBody
@RequestMapping("str")
public String test(String str){
User user = new User();
user.setName("aaa");
user.setPassword("123");
userDao.save(user);
return "true" + str;
}
@ResponseBody
@RequestMapping("get")
public String get(){
List<User> list = userDao.findAll();
return JSONObject.toJSONString(list);
}
}
扩展查询
从上面的截图 “UserDao 查询实体删除功能” 中,我们可以看到,查询功能是不尽人意的,很多我们想要的查询功能还没有。不过放心。JPA 有非常方便和优雅的方式来解决
根据属性来查询
@Repository
public interface UserDao extends JpaRepository<User, Integer> {
User findByName(String name);
}
然后增加一个测试用例:
@ResponseBody
@RequestMapping("findByName")
public String findByName(String name){
User user = userDao.findByName(name);
return JSONObject.toJSONString(user);
}
自定义查询
如果上述的情况还无法满足需要。那么我们就可以通过通过 import org.springframework.data.jpa.repository.Query 注解来解决这个问题。例如我们想查询名称等于某两个名字的所有用户列表,则声明如下的接口即可
@Query("select u from User u where u.name=:name1")
List<User> query(@Param("name1") String name);
当然也可以使用原生SQL来进行查询
@Query(nativeQuery = true, value = "select * from user u where u.name=:name1")
List<User> query1(@Param("name1") String name);
这里在 @Query 注解中增加一个 nativeQuery = true 的属性,就可以采用原生 SQL 语句的方式来编写查询。
后记
这个样例基本上讲述了 JPA 使用过程中的一些细节。我们可以看出。使用 JPA 来完成关于关系数据库增删改查的功能是非常的方便快捷的。所有代码已经上传到 github 的仓库program 上了