Spring Data:其实SpringData就是Spring提供了一个操作数据的框架。而SpringData JPA只是SpringData框架下的一个基于JPA标准操作数据的模块。
Spring Data JPA:基于JPA的标准数据进行操作。简化操作持久层的代码。只需要编写接口就可以。
具体可见spring官方网站。
1)在pom中添加依赖
org.springframework.boot
spring-boot-starter-data-jpa
2)修改application.properties / application.yml文件中添加配置
server:
port: 8081
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:9006/sm_db?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
jpa:
hibernate:
# jpa的正向工程
ddl-auto: update
# 显示sql
show-sql: true
说明:
spring.jpa.hibernate.ddl-auto=update jpa的正向工程
srpng.jpa.show-sql=true 显示sql
3)添加实体类
/**
* @Data:让其类下的所有属性都有getset方法
* @ToString:生成一个tostring的方法
* 这两个lombok下的工具类
* 使用lombok需要在idea安装插件,在File -> Settings 菜单 , 或Ctrl + Alt + S 快捷键,
* 打开设置面板 . 并切换到Plugins插件视图,在搜索框输入lombok进行搜索。
* 使用需要在pom里面添加依赖
*
* org.projectlombok
* lombok
* true
*
*/
@Data
@ToString
// @Entity 定义这个类是实体类
@Entity
// @Table 数据库中对应的表,name 对应的表名
@Table(name = "t_user")
public class User {
// @Id 标志这个属性是个id
@Id
// @GeneratedValue 标志是个自增主键
@GeneratedValue(strategy = GenerationType.IDENTITY)
// @Column 数据库中对应的字段
@Column(name = "lid")
private Long lid;
@Column(name = "username")
private String username;
@Column(name = "mobilephone")
private String mobilephone;
@Column(name = "email")
private String email;
}
4)编写Dao接口
/**
* 参数一 T :当前需要映射的实体
* 参数二 ID :当前映射的实体中的OID的类型
*/
public interface UserRepository extends JpaRepository {
}
5)在pom文件中添加测试启动器的坐标
org.springframework.boot
spring-boot-starter-test
test
6)测试
@RunWith(SpringRunner.class)
@SpringBootTest(classes = { ProjectFrame2Application.class })
class ProjectFrame2ApplicationTests {
@Autowired
private UserService userService;
@Test
public void testSave() {
User user = new User();
user.setUsername("测试");
user.setMobilephone("12345678910");
user.setEmail("[email protected]");
this.userRepository.save(user);
}
}
1、Repository接口
2、CrudRepository接口
3、PagingAndSortingRepository接口
4、JpaRepository接口
5、JPASpecificationExecutor接口
1)Repository接口的使用
提供了方法名称命名查询方式
提供了基于@Query注解查询与更新
1、dao层接口(方法名称命名查询方式)
/**
* Repository接口方法名称命名查询
*
*/
public interface UsersRepositoryByName extends Repository {
//方法名称必须要遵循驼峰式命名规则,findBy(关键字)+属性名称(首字母大写)+查询条件(首字母大写)
// 根据name和年龄进行查询
List findByName(String name);
// 根据name和age进行查询
List findByNameAndAge(String name,Integer age);
// findByNameLike 根据name条件进行模糊查询
List findByNameLike(String name);
}
2、dao层接口编写(基于@Query注解查询与更新)
/**
* 〈一句话功能简述〉
* Repository @Query
*
* @author admin
* @create 2019/5/22
* @since 1.0.0
*/
public interface UsersRepositoryQueryAnnotation extends JpaRepository {
@Query("from Users where name = ?")
List queryByNameUseHQL(String name);
@Query(value = "select * from t_user where name=?",nativeQuery = true)
List queryByNameUseSQL(String name);
@Query("update Users set name=? where id=?")
@Modifying //需要执行一个更新操作
void updateUserNameById(String name,Long id);
}
2)、CrudRepository接口的使用
CrudRepository接口,主要是完成一些增删改查的操作。注意:CrudRepository接口继承了Repository接口
1、编写dao层接口
public interface UsersRepositoryCrudRepository extends CrudRepository {
}
2、测试
@Test
public void testCrudRepositorySave() {
User user = new User();
user.setUsername("测试1");
user.setMobilephone("12345678911");
user.setEmail("[email protected]");
this.userRepositoryCrudRepository.save(users);
}
@Test
public void testCrudRepositoryUpdate() {
User user = new User();
user.setLid(1L);
user.setUsername("测试2");
user.setMobilephone("12345678912");
user.setEmail("[email protected]");
this.userRepositoryCrudRepository.save(users);
}
@Test
public void testCrudRepositoryFindOne() {
User user=this.userRepositoryCrudRepository.findOne(4);
System.out.println(user);
}
@Test
public void testCrudRepositoryFindAll() {
List list= (List) this.userRepositoryCrudRepository.findAll();
for (User user : list){
System.out.println(user);
}
}
@Test
public void testCrudRepositoryDeleteById() {
this.usersRepositoryCrudRepository.delete(2);
}
3)PagingAndSortingRepository接口的使用
该接口提供了分页与排序的操作,注意:该接口继承了CrudRepository接口
1、编写dao层
public interface UsersRepositoryPagingAndSorting extends PagingAndSortingRepository {
}
2、测试
@Test
public void testPagingAndSortingRepositorySort() {
//Order 定义了排序规则
Sort.Order order=new Sort.Order(Sort.Direction.DESC,"id");
//Sort对象封装了排序规则
Sort sort=new Sort(order);
List list = (List) this.usersRepositoryPagingAndSorting.findAll(sort);
for (User user:list){
System.out.println(user);
}
}
@Test
public void testPagingAndSortingRepositoryPaging() {
//Pageable:封装了分页的参数,当前页,煤业显示的条数。注意:它的当前页是从0开始
//PageRequest(page, size):page表示当前页,size表示每页显示多少条
Pageable pageable=new PageRequest(1,2);
Page page=this.usersRepositoryPagingAndSorting.findAll(pageable);
System.out.println("数据的总条数:"+page.getTotalElements());
System.out.println("总页数:"+page.getTotalPages());
List list = page.getContent();
for (User user : list){
System.out.println(user);
}
}
@Test
public void testPagingAndSortingRepositorySortAndPaging() {
Sort sort=new Sort(new Sort.Order(Sort.Direction.DESC,"id"));
Pageable pageable=new PageRequest(0, 2, sort);
Page page=this.usersRepositoryPagingAndSorting.findAll(pageable);
System.out.println("数据的总条数:"+page.getTotalElements());
System.out.println("总页数:"+page.getTotalPages());
List list=page.getContent();
for (User user : list){
System.out.println(user);
}
}
4)JpaRepository接口
该接口继承了PagingAndSortingRepository。对继承的父接口中方法的返回值进行适配。
1、dao层接口编写
/**
* 参数一 T :当前需要映射的实体
* 参数二 ID :当前映射的实体中的OID的类型
*
*/
public interface UsersRepository extends JpaRepository {
}
2、测试
/**
* JpaRepository 排序测试
*/
@Test
public void testJpaRepositorySort() {
//Order 定义了排序规则
Sort.Order order=new Sort.Order(Sort.Direction.DESC,"id");
//Sort对象封装了排序规则
Sort sort=new Sort(order);
List list= this.usersRepository.findAll(sort);
for (User user : list){
System.out.println(user);
}
}
5)JPASpecificationExecutor接口
该接口主要是提供了多条件查询的支持,并且可以在查询中添加排序与分页。注意JPASpecificationExecutor是单独存在的。完全独立
1、dao层接口编写
public interface UserRepositorySpecification extends JpaRepository,JpaSpecificationExecutor {
}
2、测试
/**
* JpaSpecificationExecutor 单条件查询
*/
@Test
public void testJpaSpecificationExecutor1() {
/**
* Specification:用于封装查查询条件
*/
Specification spec=new Specification() {
//Predicate:封装了单个查询条件
/**
* @param root 对查询对象属性的封装
* @param criteriaQuery 封装了我们要执行的查询中的各个部分的信息,select from order
* @param criteriaBuilder 查询条件的构造器
* @return
*/
@Override
public Predicate toPredicate(Root root, CriteriaQuery> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//where name="张三"
/**
* 参数一:查询的属性
* 参数二:条件的值
*/
Predicate predicate=criteriaBuilder.equal(root.get("username"),"张三");
return predicate;
}
};
List list=this.userRepositorySpecification.findAll(spec);
for (Users user:list){
System.out.println(user);
}
}
/**
* JpaSpecificationExecutor 多条件查询方式一
*/
@Test
public void testJpaSpecificationExecutor2() {
/**
* Specification:用于封装查查询条件
*/
Specification spec=new Specification() {
//Predicate:封装了单个查询条件
/**
* @param root 对查询对象属性的封装
* @param criteriaQuery 封装了我们要执行的查询中的各个部分的信息,select from order
* @param criteriaBuilder 查询条件的构造器
* @return
*/
@Override
public Predicate toPredicate(Root root, CriteriaQuery> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//where name="张三" and age=20
/**
* 参数一:查询的属性
* 参数二:条件的值
*/
List list=new ArrayList<>();
list.add(criteriaBuilder.equal(root.get("username"),"张三"));
list.add(criteriaBuilder.equal(root.get("mail"),"[email protected]"));
Predicate[] arr=new Predicate[list.size()];
return criteriaBuilder.and(list.toArray(arr));
}
};
List list=this.userRepositorySpecification.findAll(spec);
for (User user:list){
System.out.println(user);
}
}
/**
* JpaSpecificationExecutor 多条件查询方式二
*/
@Test
public void testJpaSpecificationExecutor3() {
/**
* Specification:用于封装查查询条件
*/
Specification spec=new Specification() {
//Predicate:封装了单个查询条件
/**
* @param root 对查询对象属性的封装
* @param criteriaQuery 封装了我们要执行的查询中的各个部分的信息,select from order
* @param criteriaBuilder 查询条件的构造器
* @return
*/
@Override
public Predicate toPredicate(Root root, CriteriaQuery> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//where username="张三" and mail="[email protected]"
/**
* 参数一:查询的属性
* 参数二:条件的值
*/
/*List list=new ArrayList<>();
list.add(criteriaBuilder.equal(root.get("username"),"张三"));
list.add(criteriaBuilder.equal(root.get("mail"), "[email protected]"));
Predicate[] arr=new Predicate[list.size()];*/
//(username='张三' and mail="[email protected]") or lid=2L
return criteriaBuilder.or(criteriaBuilder.and(criteriaBuilder.equal(root.get("username"),"张三"),criteriaBuilder.equal(root.get("mail"),"[email protected]")),criteriaBuilder.equal(root.get("lid"),2L));
}
};
Sort sort=new Sort(new Sort.Order(Sort.Direction.DESC,"lid"));
List list=this.userRepositorySpecification.findAll(spec,sort);
for (User user:list){
System.out.println(user);
}
}
1、一对多的关联关系
需求:角色与用户的一对多的关联关系
角色:一方
用户:多方
1)实体类
/**
*
*/
@Data
@Entity
@Table(name = "t_roles")
public class Roles {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "role_id")
private Integer roleId;
@Column(name = "role_name")
private String roleName;
@OneToMany(mappedBy = "roles")
private Set user=new HashSet<>();
}
@Data
@ToString(exclude = {"roles"})
@Entity
@Table(name="t_users")
public class Users {
@Id //主键id
@GeneratedValue(strategy=GenerationType.IDENTITY)//主键生成策略
@Column(name="id")
private Integer id;
@Column(name="name")
private String name;
@Column(name="age")
private Integer age;
@Column(name="address")
private String address;
@ManyToOne(cascade = CascadeType.PERSIST) //表示多方
@JoinColumn(name ="role_id") //维护一个外键,外键在Users一侧
private Roles roles;
}
2)dao层接口编写
/**
* 参数一 T :当前需要映射的实体
* 参数二 ID :当前映射的实体中的OID的类型
*
*/
public interface UsersRepository extends JpaRepository {
}
3)测试
/**
* 〈一句话功能简述〉
* 多对多的关联关系的测试
*
* @author admin
* @create 2019/5/23
* @since 1.0.0
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {ProjectFrame2Application.class})
public class ManyToManyTest {
@Autowired
private RolesRepository rolesRepository;
/**
* 添加测试
*/
@Test
public void testSave(){
//创建角色对象
Roles roles=new Roles();
roles.setRoleName("项目经理");
//创建菜单对象
Menus menus=new Menus();
menus.setMenusName("xxxx管理系统");
menus.setFatherId(0);
Menus menus2=new Menus();
menus2.setFatherId(1);
menus2.setMenusName("项目管理");
//关联
roles.getMenus().add(menus);
roles.getMenus().add(menus2);
menus.getRoles().add(roles);
menus2.getRoles().add(roles);
//保存
this.rolesRepository.save(roles);
}
/**
* 查询操作
*/
@Test
public void testFind(){
Roles roles=this.rolesRepository.findOne(2);
System.out.println(roles.getRoleName());
Set menus=roles.getMenus();
for (Menus menu:menus){
System.out.println(menu);
}
}
}
2、多对多的关联关系
角色与菜单多对多关联关系
菜单:多方
角色:多方
1)实体类
@Data
@ToString(exclude = {"roles"})
@Entity
@Table(name = "t_menus")
public class Menus {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "menus_id")
private Integer menusId;
@Column(name = "menus_name")
private String menusName;
@Column(name = "menus_url")
private String menusUrl;
@Column(name = "father_id")
private Integer fatherId;
@ManyToMany(mappedBy = "menus")
private Set roles=new HashSet<>();
}
@Data
@Entity
@Table(name = "t_roles")
public class Roles {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "role_id")
private Integer roleId;
@Column(name = "role_name")
private String roleName;
@OneToMany(mappedBy = "roles")
private Set users=new HashSet<>();
@ManyToMany(cascade = CascadeType.PERSIST,fetch = FetchType.EAGER)
//映射中间表 joinColumns:当前表中的主键关联中间表的外键
@JoinTable(name = "t_roles_menus",joinColumns =@JoinColumn(name = "role_id"),inverseJoinColumns = @JoinColumn(name = "menu_id"))
private Set menus=new HashSet<>();
2)dao层接口
public interface RolesRepository extends JpaRepository {
}
3)测试
/**
* 多对多的关联关系的测试
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {ProjectFrame2Application.class})
public class ManyToManyTest {
@Autowired
private RolesRepository rolesRepository;
/**
* 添加测试
*/
@Test
public void testSave(){
//创建角色对象
Roles roles=new Roles();
roles.setRoleName("项目经理");
//创建菜单对象
Menus menus=new Menus();
menus.setMenusName("xxxx管理系统");
menus.setFatherId(0);
Menus menus2=new Menus();
menus2.setFatherId(1);
menus2.setMenusName("项目管理");
//关联
roles.getMenus().add(menus);
roles.getMenus().add(menus2);
menus.getRoles().add(roles);
menus2.getRoles().add(roles);
//保存
this.rolesRepository.save(roles);
}
/**
* 查询操作
*/
@Test
public void testFind(){
Roles roles=this.rolesRepository.findOne(2);
System.out.println(roles.getRoleName());
Set menus=roles.getMenus();
for (Menus menu:menus){
System.out.println(menu);
}
}
}
本文章是我在学习中所记录,如有错误请及时告知,谢谢!!!