这里就不引用冠冕堂皇的介绍了。用我概括的话说。他就是一个类似hibernate,mybatis数据访问层的框架。官网有详细的介绍,
戳这里
Jpa是什么?他是一套规范,类似restful风格一样,都是一套规范。使用Jpa必须按照它的规范来操作数据访问。
SpringDataJpa==Jpa规范+Hibernate底层
笔者其实很喜欢用mybatis写sql来操作数据。但mybatis的局限性就是使用比较麻烦。在工作中,其实大多数业务都是简单的增删改查排序分页。使用mybatis时,每个表基本都要写一遍mapping配置。其实这些工作都是重复性的。写多了谁都会烦而且没必要,只是改了表名和实体类。针对这个问题也有解决方案,就是使用生成工具,直接生成。或者封装一个通用基类,但是mybatis封装很麻烦。所以笔者开始用jpa来做这件事。当然mybatis使用配置文件有一点好处,就是修改sql无需重新编译就可以生效。就是说当我们在服务器上部署了一个项目,通过修改配置文件不用重启服务器。
Jpa适合什么样的项目呢?我觉得适合非互联网项目,或者说中小型项目,或者说对sql优化不高的项目,或者说需求变更不是太频繁的项目。我们可以一个项目中mybatis+jpa混合使用,对于不需要sql优化的表,jpa使用更加方便。
综合来说,jpa在开发效率上讲绝对是比mybatis方便的。我们可以根据自己的需求,来界定是否使用jpa。
Jpa用起来有多简单呢?只需要写一个接口,然后继承JpaRepository,就可以使用了。
比如我要操作User表,新增一个接口IUserDao继承JpaRepository。
public interface IUserDao extends JpaRepository,JpaSpecificationExecutor {}
在调用的地方初始化IUserDao
@Autowired
private IUserDao userDao;
最后就是调用的地方写代码即可,增删改查如下,根本不用自己定义一边。
userDao.save(user);增
userDao.delete(1);删
userDao.save(user);改
userDao.findById(1);查
相比mybatis,每个方法都要声明一边,然后写对应的sql,是不是简单了许多?
可能有人会说上边这几个方法使用起来太单一,不能满足我的需求,比如根据用户名查找,根据用户名修改等操作。
别急,我上边只是介绍最基本的操作,你想的这些,Jpa作者都想到了。
比如说根据用户名查找,我们只需要在IUserDao接口中,声明如下方法即可:
public User findByUserName(String userName);
然后在调用的地方,加上如下代码即可。
userDao.findByUserName("zhangsan");
我们也可以这样写:
@Query("from User where userName=?1")
public User findBySql(String userName);
也可以通过条件修改:
@Transactional
@Modifying
@Query("update User set userName=?1 where id=?2")
public int updateBySql(String userName,Integer id);
还有很多简便用法,这里就不做展示了。写到这不知道你对Jpa是否有点心动。
使用SpringBoot继承Jpa是最简单的。
操作步骤如下:
初始化后pom.xml文件如下,也可以新建空的maven工程,倒入下边的依赖。
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.7.RELEASE
com.ming
springbootjpatest
0.0.1-SNAPSHOT
springbootjpatest
Demo project for Spring Boot
1.8
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-jdbc
mysql
mysql-connector-java
runtime
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
工程初始化完毕后,首先新增实体类User。具体注意点,参见代码注释。一定要注意细节,哪个位置没注意,工程就会报错。代码如下:
package com.ming.springbootjpatest.entity;
import javax.annotation.Generated;
import javax.persistence.*;
@Entity
@Table(name = "t_userinfo")//数据库表明
public class User {
@Id//声明id为主键
@GeneratedValue(strategy = GenerationType.IDENTITY)//声明自动增长
@Column(name = "id")//声明数据库对应的字段
private Integer id;
@Column(name = "user_name")//声明数据库对应的字段
//定义字段也是有讲究的,比如首字母小写,后边的驼峰,对应的数据库字段,遇到驼峰用下划线断开
//比如实体类定义的userName,则数据库字段为user_name,
//比如实体类定义的username,则数据库字段也为username
private String userName;
@Column(name = "password")
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", userName='" + userName + '\'' +
", password='" + password + '\'' +
'}';
}
}
然后新增dao层接口IUserDao,代码如下:
public interface IUserDao extends JpaRepository,JpaSpecificationExecutor {}
然后定义配置文件,在resources目录下新增application.yml,将之前的application.properties文件删掉。配置如下:
server:
port: 8080
servlet:
context-path: /
spring:
datasource:
url: jdbc:mysql://localhost:3306/jpatest?serverTimezone=UTC
username: root
password: 123456
jpa:
database: MySQL
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect #mysql数据库固定配置
show-sql: true #控制台打印sql
hibernate:
ddl-auto: update #update代表数据库没有表的话,会先创建表,有表的话就不创建了。
以上就基本完成了,我们可以在测试类中做各种数据操作了。
有人说数据库表还没有呢啊!这里要告诉大家,程序运行后,Jpa会去数据库查看,如没有表的话,会先创建表,有表的话就不创建了。所以我们不用创建表,jpa帮我们做了。具体配置参见上边ddl-auto字段。
下边就可以在测试类中写一些测试了啦,代码如下:
package com.ming.springbootjpatest;
import com.ming.springbootjpatest.dao.IUserDao;
import com.ming.springbootjpatest.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.context.junit4.SpringRunner;
import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootjpatestApplicationTests {
@Autowired
private IUserDao userDao;
/**
* 增加方法
*/
@Test
public void testAdd(){
User user=new User();
user.setUserName("zhangsan1");
user.setPassword("12345");
userDao.save(user);
}
/**
* 批量增加
*/
@Test
public void testAddList(){
List userList=new ArrayList<>();
for(int i=0;i<10;i++){
User user=new User();
user.setUserName("zhangsan_"+i);
user.setPassword("12345_"+i);
userList.add(user);
}
userDao.saveAll(userList);
}
/**
* 通过主键查找
*/
@Test
public void testFindById(){
Optional optionalUser = userDao.findById(1);
User user = optionalUser.get();
System.out.println(user);
}
/**
* 通用查找方法,基本上按照哪个字段查都可以,写起来稍微麻烦一点点。
* 下边是按照userName="zhangsan"去查,如果不用=换作like,就将下边的criteriaBuilder.equal
* 换成criteriaBuilder.like。
*/
@Test
public void testCommonFind(){
Specification specification=new Specification() {
@Override
public Predicate toPredicate(Root root, CriteriaQuery> criteriaQuery, CriteriaBuilder criteriaBuilder) {
Path
以上基本覆盖了常用的方法。还有很多的复杂方法这里不再介绍。仅当入门演示。
spring配置起来比SpringBoot麻烦,主要是需要导入很多依赖,版本号控制繁琐,配置也比Springboot麻烦。但难于很多项目都是Spring,在这里增加Jpa在spring中的配置。
可以去maven仓库查询常见依赖版本,maven仓库地址:https://mvnrepository.com/
新建一个空的maven工程,导入pom文件如下:
4.0.0
com.ming
spring-jpa-test
1.0-SNAPSHOT
1.8
5.1.5.RELEASE
5.4.2.Final
1.8.0-beta4
1.2.17
0.9.1.2
5.1.6
junit
junit
4.13-beta-3
test
org.aspectj
aspectjweaver
1.9.4
org.springframework
spring-aop
${spring.version}
org.springframework
spring-context
${spring.version}
org.springframework
spring-context-support
${spring.version}
org.springframework
spring-orm
${spring.version}
org.springframework
spring-beans
${spring.version}
org.springframework
spring-core
${spring.version}
org.hibernate
hibernate-core
${hibernate.version}
org.hibernate
hibernate-entitymanager
${hibernate.version}
org.hibernate
hibernate-validator
6.0.16.Final
c3p0
c3p0
${c3p0.version}
log4j
log4j
${log4j.version}
org.slf4j
slf4j-api
${slf4j.version}
org.slf4j
slf4j-log4j12
${slf4j.version}
mysql
mysql-connector-java
${mysql.version}
org.springframework.data
spring-data-jpa
2.1.10.RELEASE
org.springframework
spring-test
5.1.9.RELEASE
javax.el
javax.el-api
3.0.0
org.glassfish
javax.el
3.0.1-b10
接下来就是resources中applicationContext.xml的配置。
主要就是这两个配置文件,具体实现代码同SpringBoot中的代码。
注意pom文件中mysql-connection-java的版本跟你使用的mysql版本有关,如果用5点几的mysql,mysql-connection-java的版本也要用5点几的否则会报错噢,具体版本可以用maven仓库搜索,仓库地址上边有写。
因为配置spring版本等问题,很容易出错,如遇到错误,可先去我的另外一篇文章中查找,戳这里
在多module工程中,如果把model放在单独的工程,记得在jpa工程启动类中,使用@EntityScan注解,扫描实体类噢。
以上就是对SpringDataJpa的介绍,相信通过文章的介绍大家都能入门使用了,有些细节的使用,还需熟悉jpa规范。
我们也可以封装一个公用基类,便于更好的维护管理。
公用基类声明如下:
@NoRepositoryBean
public interface IBaseDao extends JpaRepository, JpaSpecificationExecutor {
}
像IUserDao等接口都直接继承IBaseDao即可。注意上边的注解,否则会报错。
https://github.com/OptimusMX/springdatajpa