Spring Data JPA 入门篇
Spring Data JPA是什么
它是Spring基于ORM框架(如hibernate,Mybatis等)、JPA规范(Java Persistence API)封装的一套 JPA应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。他提供了包括增删改查在内的常用功能,且易于扩展!学习并使用Spring Data JPA可以极大提高开发效率。
Spring Data JPA有什么
主要看看SpringDataJPA提供的编程接口
- Repository:最顶层的接口,是一个空接口,目的是为了统一所有的Repository的类型,且能让组件扫描的时候自动识别。
- CrudRepository:Repository的子接口,提供CRUD的功能
- PagingAndSortingRepository:CrudRepository的子接口,添加分页排序的功能
- JpaRepository:PagingAndSortingRepository的子接口,增加批量操作等功能
- JPASpecificationExecutor:用来做复杂查询的接口
建立项目:用户管理
配置文件persistent.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="userPU" transaction-type="RESOURCE_LOCAL">
<!--jpa的提供者-->
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<!--声明数据库连接的驱动-->
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<!--jdbc数据库的连接地址-->
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/test"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value="123456"/>
<!--配置方言-->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
<!--激活查询日志功能-->
<property name="hibernate.show_sql" value="true"/>
<!--优雅地输出Sql-->
<property name="hibernate.format_sql" value="true"/>
<!--添加一条解释型标注-->
<property name="hibernate.use_sql_comments" value="false"/>
<!--配置如何根据java模型生成数据库表结构,常用update,validate-->
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"
default-lazy-init="true"> <!--第一步-->
<!--定义服务层代码存放的包扫描路径-->
<context:component-scan base-package="com.jike.usermanage.service" /> <!--第二步-->
<!--定义实体的工厂bean-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="userPU" />
<property name="persistenceXmlLocation" value="classpath:persistence.xml"></property>
</bean> <!--第三步-->
<!--定义事务管理器-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!--第四步-->
<!--定义repository接口的存放目录-->
<!--定义接口实现的后缀,通常用Impl--,如果我们不想使用JPA提供的方法,我们可以自己实现,文件后缀为Impl>
<!--定义实体工厂的引用-->
<!--定义事务管理器的引用-->
<jpa:repositories base-package="com.jike.usermanage.repository"
repository-impl-postfix="Impl"
entity-manager-factory-ref="entityManagerFactory"
transaction-manager-ref="transactionManager"/>
<!--第五步-->
<!--声明采用注解的方式申明事务-->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
实体类User.java
package com.jike.usermanage.model; import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table; @Entity
@Table(name="user")
public class User { @Id
@GeneratedValue
private Integer id;
private String name;
private String address;
private String phone; public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
Dao层UserRepository.java:这个类需要继承JpaRepository<User,Integer>,Integer表示User表中的主键类型
package com.jike.usermanage.repository; import java.util.List; import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository; import com.jike.usermanage.model.User; public interface UserRepository extends JpaRepository<User, Integer> { // 查询需求: 从数据库中查询电话号码(phone)以指定字符串开始(例如:136)的,并且地址(address)中包含指定字符串(例如:路)的记录
// select * from user where phone like '136%' and address like '%路%' order
// by phone desc limit 0,2
List<User> findTop2ByPhoneStartingWithAndAddressContainingOrderByPhoneDesc(
String phone, String address); List<User> findTop2ByPhoneStartingWithAndAddressContaining(String phone,
String address, Sort sort); Page<User> findByPhoneStartingWithAndAddressContaining(String phone,
String address, Pageable pageable);
}
Service层:
package com.jike.usermanage.service; import java.util.List; import org.springframework.data.domain.Page; import com.jike.usermanage.exception.UserNotFound;
import com.jike.usermanage.model.User; public interface UserService {
// 添加用户
public void addUser(User user); // 修改用户
public User updateUser(User user) throws UserNotFound; // 删除用户,根据用户编号删除
public User deleteUser(int id) throws UserNotFound; // 查询单个用户
public User getUser(int id); // 查询所有用户
public List<User> getUsers(); // 不分页带条件查询
public List<User> getUsersByConditionNoPage(String phone, String address); // 带分页条件查询(需要得到用户列表并且得到分页信息)
public Page<User> getUsersByConditionWithPage(String phone, String address,
Integer page, Integer pageSize);
// 带分页条件查询(得到用户列表)
// public List<User> getUsersByCondition(String phone,String address,Integer
// page,Integer pageSize);
}
ServiceImpl
package com.jike.usermanage.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service; import com.jike.usermanage.exception.UserNotFound;
import com.jike.usermanage.model.User;
import com.jike.usermanage.repository.UserRepository; @Service("userService")
public class UserServiceImpl implements UserService { @Autowired
private UserRepository userRepository; @Override
public void addUser(User user) {
userRepository.save(user); } @Override
public User updateUser(User user) throws UserNotFound {
User userUpdate = userRepository.findOne(user.getId());
if (userUpdate == null)
throw new UserNotFound();
if (user.getName() != null)
userUpdate.setName(user.getName());
if (user.getAddress() != null)
userUpdate.setAddress(user.getAddress());
if (user.getPhone() != null)
userUpdate.setPhone(user.getPhone());
userRepository.save(userUpdate);
return userUpdate;
} @Override
public User deleteUser(int id) throws UserNotFound {
User userDelete = userRepository.findOne(id);
if (userDelete == null)
throw new UserNotFound();
userRepository.delete(userDelete);
return userDelete;
} @Override
public User getUser(int id) { return userRepository.findOne(id);
} @Override
public List<User> getUsers() { return userRepository.findAll();
} @Override
public Page<User> getUsersByConditionWithPage(String phone, String address,
Integer page, Integer pageSize) { // 不排序
Page<User> userPage = userRepository
.findByPhoneStartingWithAndAddressContaining(phone, address,
new PageRequest(page, pageSize)); // 排序 // 第一种排序方式
// Page<User> userPage =
// userRepository.findByPhoneStartingWithAndAddressContaining(phone,address,new
// PageRequest(page, pageSize,new Sort(Direction.ASC,"name","phone"))); // 第二种排序方式
// Order order = new Order(Direction.ASC,"phone");
// Page<User> userPage =
// userRepository.findByPhoneStartingWithAndAddressContaining(phone,address,new
// PageRequest(page, pageSize,new Sort(order)); // 第三种排序方式
// List<Order> orders = new ArrayList<Order>();
// orders.add(new Order(Direction.DESC,"name"));
// orders.add(new Order(Direction.ASC,"phone"));
// Page<User> userPage =
// userRepository.findByPhoneStartingWithAndAddressContaining(phone,address,new
// PageRequest(page, pageSize,new Sort(orders)); return userPage; } @Override
public List<User> getUsersByConditionNoPage(String phone, String address) { return userRepository
.findTop2ByPhoneStartingWithAndAddressContainingOrderByPhoneDesc(
phone, address); // return
// userRepository.findTop2ByPhoneStartingWithAndAddressContaining(phone,
// address, new Sort(Direction.ASC,"phone")); // Order order = new Order(Direction.ASC,"phone");
// return
// userRepository.findTop2ByPhoneStartingWithAndAddressContaining(phone,
// address, new Sort(order)); // List<Order> orders = new ArrayList<Order>();
// orders.add(new Order(Direction.DESC,"name"));
// orders.add(new Order(Direction.ASC,"phone"));
// return
// userRepository.findTop2ByPhoneStartingWithAndAddressContaining(phone,
// address, new Sort(orders); } }
异常类:
package com.jike.usermanage.exception; public class UserNotFound extends Exception { }
JpaRepository接口方法:
delete删除或批量删除
findAll查找所有
findOne查找单个
save保存单个或批量保存
saveAndFlush保存并刷新到数据库
查询操作的基本实现----基于方法名解析
JpaRepository支持接口规范方法名查询。意思是如果在接口中定义的查询方法符合他的命名规则,就可以不用写实现。
例如:findByName这个方法表示从数据库中查询Name这个属性等于XXX的所有记录,类似于SQL语句:select * from xxTable where name=xxx这种形式
1. 方法名需要在接口中设定
2.必须符合一定的命名规范
find+全局修饰+By+实体的属性名称+限定词+连接词+...(其他属性实体)+OrderBy+排序属性+排序方向
例如:findDistinctByFirstNameIgnoreCaseAndLastNameOrderByAgeDesc(String firstName,String lastName){....}
其中:Distinct是全局修饰(非必须),FirstName和LastName是实体的属性名,And是连接词,IgnoreCase是限定词,Age是排序属性,Dest是排序方向,限定词和连接词统称为"关键词"
常用词如下:
全局修饰:Distinct,Top,First
关键词:IsNull,InNotNull,Like,NotLike,Containing,In,NotIn,IgnoreCase,Betwwen,Equals,LessThan,GreaterThan,After,Before
排序方向:Asc,Desc
连接词:And,Or
Spring Data JPA 入门篇的更多相关文章
- Spring Data JPA入门及深入
一:Spring Data JPA简介 Spring Data JPA 是 Spring 基于 ORM 框架.JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据库的访问 ...
- spring data jpa入门学习
本文主要介绍下spring data jpa,主要聊聊为何要使用它进行开发以及它的基本使用.本文主要是入门介绍,并在最后会留下完整的demo供读者进行下载,从而了解并且开始使用spring data ...
- Spring Data JPA 入门Demo
什么是JPA呢? 其实JPA可以说是一种规范,是java5.0之后提出来的用于持久化的一套规范:它不是任何一种ORM框架,在我看来,是现有ORM框架在这个规范下去实现持久层. 它的出现是为了简化现有的 ...
- Spring Data Jpa 入门学习
本文主要讲解 springData Jpa 入门相关知识, 了解JPA规范与Jpa的实现,搭建springboot+dpringdata jpa环境实现基础增删改操作,适合新手学习,老鸟绕道~ 1. ...
- Spring Data JPA入门
1. Spring Data JPA是什么 它是Spring基于ORM框架.JPA规范封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据的访问和操作.它提供了包括增删改查等在内的常用功能, ...
- Spring Data Jpa --- 入门
一.概述 Spring Data是Spring下的一个子项目,用于简化数据库访问,并支持云服务的开源框架.Spring Data支持NoSQL和 关系数据存储,其主要目标是使得数据库的访问变得方便快捷 ...
- 【ORM框架】Spring Data JPA(一)-- 入门
本文参考:spring Data JPA入门 [原创]纯干货,Spring-data-jpa详解,全方位介绍 Spring Data JPA系列教程--入门 一.Spring Data JPA介 ...
- 深入浅出学Spring Data JPA
第一章:Spring Data JPA入门 Spring Data是什么 Spring Data是一个用于简化数据库访问,并支持云服务的开源框架.其主要目标是使得对数据的访问变得方便快捷,并支持map ...
- Spring Data JPA 教程(翻译)
写那些数据挖掘之类的博文 写的比较累了,现在翻译一下关于spring data jpa的文章,觉得轻松多了. 翻译正文: 你有木有注意到,使用Java持久化的API的数据访问代码包含了很多不必要的模式 ...
随机推荐
- 洛谷 P1021 邮票面值设计
题目描述 给定一个信封,最多只允许粘贴N张邮票,计算在给定K(N+K≤15)种邮票的情况下(假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大值MAX,使在1-MAX之间的每一个邮资值都能得到 ...
- 洛谷 P1454 圣诞夜的极光 == codevs 1293 送给圣诞夜的极光
题目背景 圣诞夜系列~~ 题目描述 圣诞老人回到了北极圣诞区,已经快到12点了.也就是说极光表演要开始了.这里的极光不是极地特有的自然极光景象.而是圣诞老人主持的人造极光. 轰隆隆……烟花响起(来自中 ...
- C ++ _基础之共用体
由以下代码来进一步学习共用体 #include <stdio.h> #include<iostream> void main() { union un { int a; cha ...
- 二分 || UOJ 148 跳石头
L距离中有n块石头,位置在d[i], 移走m块,使从起点0跳到终点l时,每次跳跃的最小距离最大,求这个最小距离 *解法:想到二分(想不到),对要求的结果进行二分,于是对最小距离二分== #includ ...
- dns config
.: { forward . { force_tcp expire 50s health_check 50s } cache debug errors whoami log } Corefile .: ...
- IFE春季班第一阶段任务(请仔细阅读)
第一阶段的主要目标是帮助大家 了解.认识.学习.掌握HTML及CSS.第一阶段任务从 3月14日 开始,持续到 4月3日.当然,您也可以在这个时间以后继续自行实践练习. 第一阶段任务一共有 12 个题 ...
- p1036 选数(不详细勿看,递归)
题目:传送门 这题,不会做,而且看了好久才看懂题解的,然后在题解的基础上补了一个 if(start>end) return 0 感觉这样对于我更直观 转载自:大神博客的传送门,点击进入 先声明, ...
- 常用字符串匹配算法(brute force, kmp, sunday)
1. 暴力解法 // 暴力求解 int Idx(string S, string T){ // 返回第一个匹配元素的位置,若没有匹配的子串,则返回-1 int S_size = S.length(); ...
- WCF未找到终结点
配置都配了,仍然找不到,config文件没有重新加载,原因不详,只能重新编译一下,就好了....后续找找原因看看
- Delete 语句带有子查询的sql优化
背景: 接到开发通知,应用页面打不开,让我协助... (开发跟我说,表GV_BOOKS一直有锁,锁了有1个多小时了,问我能不能把锁释放掉,我回答他们说,这肯定是sql性能问题,表上有锁是正常现象,不是 ...