什么是JPA
JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中,且支持分页查询。
几种常见的注解
注解 | 解释 |
---|---|
@Entity | 声明类为实体或表 |
@Table | 指定表名 |
@Id | 用于指定的类的属性,指定其为表中的主键)。 |
@GeneratedValue | 指定如何标识属性可以被初始化,例如自动、手动、或从序列表中获得的值。 |
@Column | 指定列的属性。 |
NamedQuery查询
SpringData JPA支持用JPA的NamedQuery来定义查询方法,即一个名称映射一个查询语句
@Entity(name = "tb_account")
@NamedQuery(name = "Account.findByName",query = "select a from tb_account a where a.name=?1")
public interface AccountDao extends JpaRepository<Account,Long> {
/**
*使用的是NamedQuery里定义的查询语句,而不是根据方法名称查询
* @param name
* @return
*/
Account findByName(String name);
Query查询
@Query("select a from tb_account a where a.price=?1")
List<Account> findByPrice(Double price);
SpringBoot中使用JPA
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>compile</scope>
</dependency>
这里说件题外话,在使用IDEA自动添加的依赖,mysql的依赖是这样的
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
这样在配置文件的时候会出现
找不到MySQL包,这是因为scope 范围指定为runtime,runtime 依赖在运行和测试系统的时候需要,但在编译的时候不需要。所以运行时才需要,因为还没运行,所以idea不能找到包的路径。这样只需要把scope这个标签删掉或者改为默认的complie即可
数据库以及JPA配置
spring:
datasource:
username: root
password: 1001101
url: jdbc:mysql://localhost:3306/loginweb?serverTimezone=GMT%2B8
initialization-mode: always
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update//启动时会根据实体类生成表,当实体类属性变动的时候,表结构也会更新
show-sql: true//在控制台显示sql语句
这里使用的是yml配置文件,springBoot中JPA属性用spring.jpa前缀来配置
定义映射实体类
@Entity(name = "tb_account")//没有指定表名,则默认为表名默认为类名
@NamedQuery(name = "Account.findByName",query = "select a from tb_account a where a.name=?1")
public class Account {
@Id//指明这个属性映射为数据库的主键
@GeneratedValue//默认使用主键生成方式为自增
private Long id;
//默认列名为属性名
private String name;
private String password;
private Double price;
//get,set方法省略
继承JpaRepository
public interface AccountDao extends JpaRepository<Account,Long> {
/**
*使用的是NamedQuery里定义的查询语句,而不是根据方法名称查询
* @param name
* @return
*/
Account findByName(String name);
@Query("select a from tb_account a where a.price=?1")
List<Account> findByPrice(Double price);
}
Controller层
@RestController
public class AccountController {
@Autowired
AccountDao accountDao;
@RequestMapping("/save")
public Account saveAccount(Account account){
Account account1 = accountDao.save(account);
return account1;
}
@RequestMapping("/findById/{id}")
public Account findById(@PathVariable("id") Long id){
Optional<Account> account = accountDao.findById(id);
return account.get();
}
@RequestMapping("/update")
public Account updateAccount(Account account){
Account account1 = accountDao.save(account);
return account1;
}
@RequestMapping("/find")
public Account findByName(String name){
Account account = accountDao.findByName(name);
return account;
}
@RequestMapping("/findByPrice")
public List<Account> findByPrice(Double price){
List<Account> accountList = accountDao.findByPrice(price);
return accountList;
}
@RequestMapping("/sort")
public List<Account> sort(){
List<Account> accountList = accountDao.findAll(new Sort(Sort.Direction.ASC, "price"));
return accountList;
}
@RequestMapping("/page")
public Page<Account> page(){
Page<Account> accountPage = accountDao.findAll(PageRequest.of(0, 2));
return accountPage;
}
}
测试
Page(http://localhost:8080/page)
Sort(http://localhost:8080/sort)
findByPrice(http://localhost:8080/findByPrice?price=50)