一、大致了解下JPA和Spring-data-JPA
JPA诞生的缘由是为了整合第三方ORM框架,实现持久化领域的统一,简化现有Java EE和Java SE应用的对象持久化的开发工作。JPA是一套规范,而不是具体的ORM框架,JPA的标准的定制是hibernate作者参与定制的,所以可以理解JPA是Hibernate的一个功能子集。简而言之:JPA是标准接口或持久化规范,Hibernate是它的一种实现。
Spring Data是Spring提供的对数据库的访问方式而Spring Data JPA是Spring Data的一部分,是JPA的Spring 实现方案。通过Spring Data JPA可以很方便的利用spring-framew构建基于数据库的应用程序。
在使用持久化工具的时候,一般都有一个对象来操作数据库,在原生的Hibernate中叫做Session,在JPA中叫做EntityManager,在MyBatis中叫做SqlSession,通过这个对象来操作数据库。我们一般按照三层结构来看的话,Service层做业务逻辑处理,Dao层和数据库打交道,在Dao中,就存在着上面的对象。那么ORM框架本身提供的功能有什么呢?答案是基本的CRUD,所有的基础CRUD框架都提供,我们使用起来感觉很方便,业务逻辑层面的处理ORM是没有提供的,如果使用原生的框架,业务逻辑代码我们一般会自定义,会自己去写SQL语句,然后执行。在这个时候,Spring-data-jpa的威力就体现出来了,ORM提供的能力他都提供,ORM框架没有提供的业务逻辑功能Spring-data-jpa也提供,全方位的解决用户的需求。使用Spring-data-jpa进行开发的过程中,常用的功能,我们几乎不需要写一条sql语句,当然spring-data-jpa也提供自己写sql的方式,这个就看个人怎么选择了。
二、整合Spring-data-JPA
org.springframework.boot
spring-boot-starter-data-jpa
com.zaxxer
HikariCP
com.alibaba
druid
1.1.0
mysql
mysql-connector-java
runtime
#修改默认端口号和访问的上下文路径
server:
port: 8090
servlet:
context-path: /dev
# 配置MySQL数据源
spring:
datasource:
url: jdbc:mysql://localhost:3306/weather_forecast?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
username: root
password: 123123
driver-class-name: com.mysql.jdbc.Driver
# 使用druid连接池
type: com.alibaba.druid.pool.DruidDataSource
# 配置druid连接池
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 30000
filters: stat
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxOpenPreparedStatements: 20
sql-script-encoding: utf-8
---
# jpa相关配置
spring:
jpa:
# 更新数据表结构
hibernate:
ddl-auto: update
# 在日志中打印出执行sql语句的信息
show-sql: true
// 使用JPA注解配置实体类与数据库字典表之间的映射关系
// 配置表名,若省略则默认表名是实体类TDictionary
@Table(name = "t_dictionary")
@Entity
public class TDictionary {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) // 主键自增
private String id;
private String code;
private String name;
private String status;
private String extendfield;
private String type;
private String description;
private String crtTime;
private String modTime;
private long sort;
// get、set方法省略....
}
spring data jpa采用接口的方式声明相应的数据库操作方法并且提供了部分基础的数据库操作方法包括save、findOne、findAll、update、delete等方法,通过查询方法还提供了分页查询的功能,也结合自己的业务需求自定义Repository并集成框架本身提供的接口就能拥有框架本身提供的数据库访问功能,针对具体的应用情况声明了特定的查询方法,针对各种简单查询,复杂查询的描述请参见spring data jpa官方手册:https://docs.spring.io/spring-data/jpa/docs/1.11.4.RELEASE/reference/html/。
public interface JPATestDao extends JpaRepository {
}
@Service
public class JPATestServiceImpl implements JPATestService {
@Autowired
private JPATestDao jpaTestDao;
@Override
public Optional getCityById(String id) {
return jpaTestDao.findById(id);
}
@Override
@Transactional
public void deleteCityById(String id) {
jpaTestDao.deleteById(id);
}
}
spring-data-jpa会根据方法的名字来自动生成sql语句,我们只需要按照方法定义的规则即可,上面的方法findById,spring-data-jpa规定,方法都以findBy开头,sql的where部分就是Id,被spring-data-jpa翻译之后就变成了:SELECT * FROM t_dictionary WHERE id = ?
下表会很直接说明:
三、测试一下
@RestController
@RequestMapping("/jpaTest")
public class JPATestController {
private Logger logger = LoggerFactory.getLogger(JdbcTestController.class);
@Autowired
private JPATestService jpaTestService;
/**
* 根据ID查询字典表的城市
*
* @return
*/
@RequestMapping("/getCityById")
@ResponseBody
public String getCityById() {
Optional vo = jpaTestService.getCityById("1");
logger.info("根据ID查询字典表的城市成功!");
return vo.get().getCrtTime()+vo.get().getName();
}
@ResponseBody
@RequestMapping("/deleteCityById")
public String deleteCityById() {
try {
jpaTestService.deleteCityById("4");
logger.info("删除成功!");
return "根据ID删除字典表测记录成功!";
} catch (Exception e) {
logger.error("删除异常", e);
return "删除异常,请检查日志信息!";
}
}
}
getCityById接口测试:
deleteCityById接口测试:
四、总结一下
spring-data-JPA实现不太复杂的CRUD操作基本不用写sql语句,通过构建Repository接口方法实现对数据库的操作,这个过程需要注意实体类和数据库表的映射关系配置,需要熟悉相关CRUD的api方法,可以去spring data jpa官方手册学习下。