一、什么是JPA?
JPA(Java Persistence API) Java 持久层API,是JDK5.0注解或XML描述 对象-关系表的映射关系,并将运行期内的实体对象持久化到数据库中。
JPA的总体思想和现有Hibernate、TopLink、Jdo等ORM框架大体一致,总的来说,JPA 包括以下3方面的技术:
1、ORM映射元数据
JPA支持XML和JDK5.0注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中;
2、API
用来操作实体对象,执行CRUD操作,框架在后台替代我们完成所有的事情,开发者从繁琐的JDBC和SQL代码中解脱出来。
3、查询语言
这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。
二、环境搭建流程
1、创建工程的时候,添加JPA 的依赖;或者在pom.xml文件中添加
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jpa artifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>6.0.5version>
dependency>
<dependency>
<groupId>org.hibernate.javax.persistencegroupId>
<artifactId>hibernate-jpa-2.0-apiartifactId>
<version>1.0.1.Finalversion>
dependency>
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-coreartifactId>
<version>5.0.7.Finalversion>
dependency>
2、配置数据源,在application.yml 文件中 添加
server:
port: 1111
context-path: /Boot
spring:
profiles:
active: dev #可设置使用哪个配置文件
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/user_boot?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
username: root
password: root
jpa:
hibernate:
ddl-auto: update
show-sql: true
hibernate 自动减表方式有五个 (前提要把数据库建好):
update:表示自动根据model对象来更新表结构,启动 hibernate 时会自动检查数据库,如果缺少表则自动建表;缺少列则自动添加列;
create: 启动hibernate时,自动删除原来的表,新建所有的表,所以每次启动后的以前数据都会丢失。
create-drop:应用停下来的时候,自动会把表和数据删掉、
none: 什么也不做;
validate:会验证类里的属性和表字段是否一致,不一致,则会报错;
3、实体映射 entity类
@Entity //注解的包 都是引用的 javax.persistence 下的
public class User {
@Id
@GeneratedValue
private Integer id;
private String name;
@Min(value = 18, message = "禁止添加未成年人员!")
private String age;
@NotNull(message = "金额必传")
private Double money;
getter() setter() toString()
}
@Enitty 表明是一个映射的实体类
@Id 表名字段id
@GeneratedValue 字段自动生成
属性名字和表字段是一致的。
4、接口访问 dao 层
/**
* Created by Advancer on 2017/12/29 10:41.
* auth: lbh
*/
public interface UserRepository extends JpaRepository<User, Integer> {
//通过年龄来查询数据
public List findUserByAge(String age);
}
直接继承 JpaRepository 接口就可以了,里面内置了一些简单的CRUD操作,也可自定义,查看源码
@NoRepositoryBean
public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
List findAll();
List findAll(Sort var1);
List findAll(Iterable var1);
List save(Iterable var1);
void flush();
S saveAndFlush(S var1);
void deleteInBatch(Iterable var1);
void deleteAllInBatch();
T getOne(ID var1);
List findAll(Example var1);
List findAll(Example var1, Sort var2);
}
5、测试数据 controller层
package com.lbh.Controller;
import com.lbh.Dao.UserRepository;
import com.lbh.Service.UserService;
import com.lbh.entity.User;
import com.lbh.util.ResultUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
* Created by Advancer on 2017/12/29 10:36.
* auth: lbh
*/
@RestController
@RequestMapping("/user")
public class UserController {
private final static Logger logger = LoggerFactory.getLogger(UserController.class);
@Autowired
private UserRepository userRepository;
@Autowired
private UserService userService;
/**
* 查询用户的全部列表
* @return
*/
@GetMapping(value = "/getUsers")
public List getUserList(){
logger.info("getUserList()");
return userRepository.findAll();
}
/**
* 新增一条记录
* @param user
* @return
*/
@PostMapping(value = "/addUser")
public Object addUser(@Valid User user, BindingResult bindingResult){
if (bindingResult.hasErrors()){
return ResultUtils.error(1, bindingResult.getFieldError().getDefaultMessage());
}
user.setAge(user.getAge());
user.setMoney(user.getMoney());
return ResultUtils.success(userRepository.save(user));
}
/**
* 查询一个用户
* @param id
* @return
*/
@GetMapping(value = "/getUser/{id}")
public User findUserById(@PathVariable("id") Integer id){
return userRepository.findOne(id);
}
/**
* 更新一个用户
* @param id
* @param name
* @param age
* @return
*/
@PutMapping(value = "/updUser/{id}")
public User updUser(@PathVariable("id") Integer id,
@RequestParam("name") String name,
@RequestParam("age") String age){
User user = new User();
user.setId(id);
user.setName(name);
user.setAge(age);
return userRepository.save(user);
}
/**
* 删除用户
* @param id
*/
@DeleteMapping(value = "/delUser/{id}")
public void delUser(@PathVariable("id") Integer id){
userRepository.delete(id);
}
/**
* 通过年龄来查询用户
* @param age
* @return
*/
@GetMapping(value = "/findUserByAge/{age}")
public List findUserByAge(@PathVariable("age") String age){
return userRepository.findUserByAge(age);
}
/**
* 事务测试 写入两条数据
*/
@PostMapping("/insertUserTwo")
public void insertUserTwo(){
userService.insertUsers();
}
/**
* 根据id 查年龄
* @param id
*/
@GetMapping("/getAge/{id}")
public void getAge(@PathVariable("id") Integer id) throws Exception {
userService.getAge(id);
}
}
三、事务控制
springboot开启事务很简单,只需要一个注解@Transactional 就可以了。因为在springboot中已经默认对jpa、jdbc、mybatis开启了事事务,引入它们依赖的时候,事物就默认开启。当然,如果你需要用其他的orm,比如beatlsql,就需要自己配置相关的事物管理器。
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Transactional(rollbackFor = Exception.class)
public void insertUsers(){
User user = new User();
user.setAge("24");
user.setName("jkj");
userRepository.save(user);
User user1 = new User();
user1.setAge("24");
user1.setName("wyy");
userRepository.save(user1);
}
}