1 简单介绍下JPA
JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
Sun引入新的JPA ORM规范出于两个原因:其一,简化现有Java EE和Java SE应用开发工作;其二,Sun希望整合ORM技术,实现天下归一。
JPA由EJB 3.0软件专家组开发,作为JSR-220实现的一部分。但它又不限于EJB 3.0,你可以在Web应用、甚至桌面应用中使用。JPA的宗旨是为POJO提供持久化标准规范,由此可见,经过这几年的实践探索,能够脱离容器独立运行,方便开发和测试的理念已经深入人心了。Hibernate3.2+、TopLink 10.1.3以及OpenJPA都提供了JPA的实现。
JPA的总体思想和现有Hibernate、TopLink、JDO等ORM框架大体一致。总的来说,JPA包括以下3方面的技术:
- ORM映射元数据
JPA支持XML和JDK5.0注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中;
- API
用来操作实体对象,执行CRUD操作,框架在后台替代我们完成所有的事情,开发者从繁琐的JDBC和SQL代码中解脱出来。
- 查询语言
这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。
2 新建Spring Boot工程和POM依赖以及配置文件
pom.xml
<dependencies> <!-- JPA --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- MySql driver --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- 单元测试 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> 复制代码
application.properties
#classname spring.datasource.driver-class-name=com.mysql.jdbc.Driver #url spring.datasource.url=jdbc:mysql://localhost:3306/sp_jpa #username spring.datasource.username=root #password spring.datasource.password=12345 #数据库类型 spring.jpa.database=MySQL #是否自动生成 spring.jpa.generate-ddl=true #每次运行程序,没有表格会新建表格,表内有数据不会清空,只会更新 spring.jpa.hibernate.ddl-auto=update 复制代码
工程结构:
3 实体类和DAO层
Student.java
/** * @author 17122 */ @Entity @Data @Setter @Getter @Accessors(chain = true) public class Student { @Id @GeneratedValue//ID自动递增 private Long sId; private String sName; private Integer sAge; } 复制代码
StudentDao.java
/** * @author 17122 */ @Repository //JpaRepository < 实体类,主键类型 > public interface StudentDAO extends JpaRepository<Student,Long> { //模糊查询 //nativeQuery = true 表示为原生SQL @Query(value = "select s_id,s_name,s_age from student s where s.s_name like ?1 ", nativeQuery = true) List<Student> findByFirstName(@Param("firstName") String firstName); } 复制代码
4 Service层接口和实现类
StudentService.java
/** * @author 17122 */ public interface StudentService { //添加一个 int saveStudent(Student student); //根据Sid查找 Student findStudentBySid(Long sId); //查看全部 List<Student> findAllStudent(); //根据id修改 int updateStudentById(Student student); //根据id删除 void deleteStudentById(Long sId); //根据姓模糊查询 List<Student> findStudentByFirstName(String firstName); } 复制代码
StudentServiceImpl.java
/** * @author 17122 */ @Service public class StudentServiceImpl implements StudentService { @Autowired private StudentDAO studentDAO; @Override public int saveStudent(Student student) { Student save = studentDAO.save(student); return ObjectUtils.isEmpty(save) ? 0 : 1; } @Override public Student findStudentBySid(Long sId) { return studentDAO.findById(sId).get(); } @Override public List<Student> findAllStudent() { return studentDAO.findAll(); } @Override public int updateStudentById(Student student) { Student student1 = studentDAO.saveAndFlush(student); return ObjectUtils.isEmpty(student1) ? 0 : 1; } @Override public void deleteStudentById(Long sId) { studentDAO.deleteById(sId); } @Override public List<Student> findStudentByFirstName(String firstName) { return studentDAO.findByFirstName(firstName+"%"); } } 复制代码
5 测试
@SpringBootTest class SpJpaApplicationTests { @Autowired private StudentService studentService; @Test void saveStudent() { Student student = new Student(); student.setSName("张三") .setSAge(100); studentService.saveStudent(student); } @Test void findStudentById() { Student student = studentService.findStudentBySid(1L); System.out.println(student); } @Test void findAllStudent() { List<Student> students = studentService.findAllStudent(); System.out.println(students); } @Test void updateStudent() { Student student = new Student(); student.setSId(3L) .setSName("张四") .setSAge(10); studentService.updateStudentById(student); } @Test void deleteStudent() { studentService.deleteStudentById(3L); } @Test void findBySome(){ System.out.println(studentService.findStudentByFirstName("张")); } } 复制代码
可以发现,根据配置文件的spring.jpa.hibernate.ddl-auto=update
我们不需要新建数据表,只需要新建数据库就可以了,我们测试下添加操作,然后刷新下数据库:
点开student
看下
发现那段配置命令可以帮助我们新建数据表,规则是
- 数据表名称与实体类名称相同
- 数据表字段将Java中的驼峰命名转化为了下换线命名
可是为什么又多了一张hibernate_sequence
表呢?
我们可以点开看下
显然,它是用来表示将要插入下一条数据的ID的
接下来我们可以把每个方法都测试一遍,发现都是可以通过的
6 总结
用了一遍JPA,想说的只有一句话,持久层框架中还是我们中国人开源的Mybatis Plus最好用!