环境搭建

源码地址:gitee:https://gitee.com/ytfs-dtx/JPA

导入依赖

<properties>
<spring.version>5.2.5.RELEASE</spring.version>
<hibernate.version>5.4.10.Final</hibernate.version>
<slf4j.version>1.7.30</slf4j.version>
<log4j.version>2.12.1</log4j.version>
<druid.version>1.1.21</druid.version>
<mysql.version>5.1.6</mysql.version> </properties> <dependencies>
<!-- spring beg -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency> <!-- spring对orm框架的支持包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency> <!-- hibernate beg -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.2.Final</version>
<exclusions>
<exclusion>
<artifactId>classmate</artifactId>
<groupId>com.fasterxml</groupId>
</exclusion>
</exclusions>
</dependency> <!-- hibernate end -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- spring data jpa 的坐标 -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.2.6.RELEASE</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency> <!-- el beg 使用spring data jpa 必须引入 -->
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency> </dependencies>

创建配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<!-- 配置实体类管理工厂 -->
<bean id="entityManagerFactoryBean" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/> <!-- 配置实体类的扫描 -->
<property name="packagesToScan" value="xyz.ytfs.entity"/> <!-- 配置jpa的提供方 -->
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider"/>
</property> <!-- 配置提供方的适配器 -->
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <!-- 数据库的类型 -->
<property name="database" value="MYSQL"/> <!-- 不自动创表 -->
<property name="generateDdl" value="false"/> <!-- 控制台打印sql语句 -->
<property name="showSql" value="true"/> <property name="databasePlatform" value="org.hibernate.dialect.MySQL55Dialect"/>
</bean>
</property> <!-- jpa的方言:高级特性 -->
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property> <property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property> </bean> <!-- 配置JPA的事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryBean"/>
</bean> <!-- JPA -->
<jpa:repositories base-package="xyz.ytfs.dao" transaction-manager-ref="transactionManager"
entity-manager-factory-ref="entityManagerFactoryBean"/> <!-- 配置数据源 -->
<context:property-placeholder location="classpath:jdbcConfig.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean> </beans>

创建实体类

注解说明

@ManyToMany
作用:用于映射多对多关系
属性:
cascade:配置级联操作。
fetch:配置是否采用延迟加载。
targetEntity:配置目标的实体类。映射多对多的时候不用写。 @JoinTable
作用:针对中间表的配置
属性:
nam:配置中间表的名称
joinColumns:中间表的外键字段关联当前实体类所对应表的主键字段
inverseJoinColumn:中间表的外键字段关联对方表的主键字段 @JoinColumn
作用:用于定义主键字段和外键字段的对应关系。
属性:
name:指定外键字段的名称
referencedColumnName:指定引用主表的主键字段名称
unique:是否唯一。默认值不唯一
nullable:是否允许为空。默认值允许。
insertable:是否允许插入。默认值允许。
updatable:是否允许更新。默认值允许。
columnDefinition:列的定义信息。

User

package xyz.ytfs.entity;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set; /**
* @author by ytfs
* @Classname User
* @Description TODO(用户类)
* @Date 2020/5/9 23:47
*/ @Entity
@Table(name = "sys_user") public class User { @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long userId; @Column(name = "user_name")
private String userName; /**
* 配置用户到角色的多对多关系
* 配置多对多的映射关系
* 1.声明表关系的配置
*
* @ManyToMany(targetEntity = Role.class) //多对多
* targetEntity:代表对方的实体类字节码
* 2.配置中间表(包含两个外键)
* @JoinTable name : 中间表的名称
* joinColumns:配置当前对象在中间表的外键
* @JoinColumn的数组 name:外键名
* referencedColumnName:参照的主表的主键名
* inverseJoinColumns:配置对方对象在中间表的外键
*/ @ManyToMany(targetEntity = Role.class, cascade = CascadeType.ALL)
@JoinTable(name = "sys_user_role",
//joinColumns,当前对象在中间表中的外键
joinColumns = {@JoinColumn(name = "sys_user_id", referencedColumnName = "user_id")},
//inverseJoinColumns,对方对象在中间表的外键
inverseJoinColumns = {@JoinColumn(name = "sys_role_id", referencedColumnName = "role_id")})
private Set<Role> roles = new HashSet<>(); public Long getUserId() {
return userId;
} public void setUserId(Long userId) {
this.userId = userId;
} public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} public Set<Role> getRoles() {
return roles;
} public void setRoles(Set<Role> roles) {
this.roles = roles;
} @Override
public String toString() {
return "User{" +
"userId=" + userId +
", userName='" + userName + '\'' +
", roles=" + roles +
'}';
}
}

Role

package xyz.ytfs.entity;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set; /**
* @author by ytfs
* @Classname Role
* @Description TODO(用户对应的类型)
* @Date 2020/5/9 23:47
*/ @Entity
@Table(name = "sys_role")
public class Role { @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "role_id")
private Long roleId; @Column(name = "role_name")
private String roleName; /**
* 配置用户到角色的多对多关系
* 配置多对多的映射关系
* 1.声明表关系的配置
* @ManyToMany(targetEntity = User.class) //多对多
* targetEntity:代表对方的实体类字节码
* 2.配置中间表(包含两个外键)
* @JoinTable
* name : 中间表的名称
* joinColumns:配置当前对象在中间表的外键
* @JoinColumn的数组
* name:外键名
* referencedColumnName:参照的主表的主键名
* inverseJoinColumns:配置对方对象在中间表的外键
*/
/* @ManyToMany(targetEntity = User.class)
@JoinTable(name = "sys_user_role",
//joinColumns,当前对象在中间表中的外键
joinColumns = {@JoinColumn(name = "sys_role_id", referencedColumnName = "role_id")},
//inverseJoinColumns,对方对象在中间表的外键
inverseJoinColumns = {@JoinColumn(name = "sys_user_id", referencedColumnName = "user_id")})*/
@ManyToMany(mappedBy = "roles")
private Set<User> users = new HashSet<>(); public Set<User> getUsers() {
return users;
} public void setUsers(Set<User> users) {
this.users = users;
} public Long getRoleId() {
return roleId;
} public void setRoleId(Long roleId) {
this.roleId = roleId;
} public String getRoleName() {
return roleName;
} public void setRoleName(String roleName) {
this.roleName = roleName;
} @Override
public String toString() {
return "Role{" +
"roleId=" + roleId +
", roleName='" + roleName + '\'' +
", users=" + users +
'}';
}
}

创建数据访问层的接口

IUserDao

package xyz.ytfs.dao;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import xyz.ytfs.entity.User; /**
* @author by ytfs
* @Classname UserDao
* @Description TODO(用户的数据访问层接口)
* @Date 2020/5/10 0:05
*/ public interface IUserDao extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
}

IRoleDao

package xyz.ytfs.dao;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import xyz.ytfs.entity.Role; /**
* @author by ytfs
* @Classname IRoleDao
* @Description TODO(用户对应的职位数据访问层)
* @Date 2020/5/10 0:07
*/ public interface IRoleDao extends JpaRepository<Role, Long>, JpaSpecificationExecutor<Role> {
}

测试类

package xyz.ytfs.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import xyz.ytfs.dao.IRoleDao;
import xyz.ytfs.dao.IUserDao;
import xyz.ytfs.entity.Role;
import xyz.ytfs.entity.User; import javax.transaction.Transactional;
import java.util.HashSet; /**
* @author by ytfs
* @Classname JpaManyToManyTest
* @Description TODO(多对多的测试类)
* @Date 2020/5/10 0:08
*/ @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class JpaManyToManyTest { @Autowired
private IRoleDao roleDao; @Autowired
private IUserDao userDao; /**
* 保存一个用户,保存一个角色
* <p>
* 多对多放弃维护权:被动的一方(这里就是被选择的一方Role)放弃
*/
@Test
@Transactional
@Rollback(false)
public void testSave() { User user = new User();
user.setUserName("雨听风说"); Role role = new Role();
role.setRoleName("程序猿"); /*
表达多对多的关系,双方都表达的时候必须有一方放弃维护中间表,不然会抛出异常
*/
role.getUsers().add(user); user.getRoles().add(role); this.userDao.save(user);
this.roleDao.save(role); } //测试级联添加(保存一个用户的同时保存用户的关联角色)
@Test
@Transactional
@Rollback(false)
public void testCasacdeSave() {
User user = new User();
user.setUserName("雨听风说"); Role role = new Role();
role.setRoleName("程序猿"); /*
表达多对多的关系
*/
role.getUsers().add(user); user.getRoles().add(role); //级联操作,在保存用户的同时保存用户的类型
this.userDao.save(user); } /**
* 级联删除,删除id为1的客户
*/ @Test
@Transactional
@Rollback(false)
public void testDeleteCasaced() {
//查询id为1的用户
User user = this.userDao.getOne(1L); //删除id为1的用户,级联删除用户对应的类型
this.userDao.delete(user);
} }

spring data jpa 多对多 ManyToMany的更多相关文章

  1. spring data jpa 多对多查询

    package com.ytkj.dao; import com.ytkj.entity.Customer; import com.ytkj.entity.Role; import org.sprin ...

  2. Spring Data JPA 初体验

    一,JPA相关的概念 JPA概述 全称是:JavaPersistence API.是SUN公司推出的一套基于ORM的规范. Hibernate框架中提供了JPA的实现. JPA通过JDK 5.0注解或 ...

  3. Spring Data JPA实体详解

    1. Spring Data JPA实体概述 JPA提供了一种简单高效的方式来管理Java对象(POJO)到关系数据库的映射,此类Java对象称为JPA实体或简称实体.实体通常与底层数据库中的单个关系 ...

  4. Spring Data Jpa系列教程--------实体解析和关联关系

    Spring Data Jpa是基于HIbernate开发的,所以建立实体建的实体和映射关系需要好好好的去了解一下,本文有以下内容,实体管理器介绍,实体与数据库表的映射介绍,关联关系(一对多,多对多) ...

  5. spring data jpa使用 (转:http://www.manongjc.com/article/25284.html#four_1_7)

    Jap相关的使用 时间:2018-12-18 本文章向大家介绍Jap相关的使用,主要包括Jap相关的使用使用实例.应用技巧.基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下. ...

  6. Spring Data JPA入门及深入

    一:Spring Data JPA简介 Spring Data JPA 是 Spring 基于 ORM 框架.JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据库的访问 ...

  7. SpringBoot学习笔记:Spring Data Jpa的使用

    更多请关注公众号 Spring Data Jpa 简介 JPA JPA(Java Persistence API)意即Java持久化API,是Sun官方在JDK5.0后提出的Java持久化规范(JSR ...

  8. Spring data JPA 理解(默认查询 自定义查询 分页查询)及no session 三种处理方法

    简介:Spring Data JPA 其实就是JDK方式(还有一种cglib的方式需要Class)的动态代理 (需要一个接口 有一大堆接口最上边的是Repository接口来自org.springfr ...

  9. Spring Boot + Spring Data JPA + PostgreSQL

    最近在用Java重写之前实习生用.netcore写的微信后台应用. 规定用Spring Boot框架,PostgreSQL数据库.之前一直习惯于基于XML的Spring app,也没用过Postgre ...

随机推荐

  1. Daily Scrum 1/18/2016

    Yandong & Zhaoyang: Prepare bug bash slides for Beta release; Dong & Fuchen:Prepare demo for ...

  2. chrome Provisional headers are shown错误提示(转载)

    今天开发时遇到了一个问题,由于要做一个支付等待页,大概的意思就是点击支付之后,跳出来一个页面,告知用户正在跳转到支付页面.这个时候问题来了,指鹤要做的这个静态支付等待页中有图片,而为了要让这个静态页面 ...

  3. Git速查表大全

  4. 网站防止sql注入

    防止sql注入代码:(1)修改php.ini magic_quotes_gpc=Off,打开开关,不常用: (2)获取到参数后,调用$username = addslashes($username); ...

  5. 打印js对象内容

    function writeObj(obj){ var description = ""; for(var i in obj){ var property=obj[i]; desc ...

  6. docker的网络(5)

    当 Docker 启动时,会自动在宿主机上创建一个 docker0 虚拟网桥,实际上是Linux 的一个 bridge. Docker 随机分配一个本地未占用的私有网络(在RFC1918中定义)中的一 ...

  7. SpringBoot 集成Swagger2自动生成文档和导出成静态文件

    目录 1. 简介 2. 集成Swagger2 2.1 导入Swagger库 2.2 配置Swagger基本信息 2.3 使用Swagger注解 2.4 文档效果图 3. 常用注解介绍 4. Swagg ...

  8. 【深入AQS原理】我画了35张图就是为了让你深入 AQS

    申明 本文首发自公众号:程序员cxuan,此文章为本人投稿文章.已经和cxuan沟通,文章投递公众号,博客平台我自己发布可标记为原创. 此文章肝了很久,图片较多,希望大家喜欢. 另外,感兴趣的小伙伴可 ...

  9. Struts2漏洞利用

    Struts漏洞合集 Struts-S2-013漏洞利用 受影响版本 Struts 2.0.0 - Struts 2.3.14.1 漏洞利用 任意命令执行POC: ${(#_memberAccess[ ...

  10. 【linux运维】rsync+inotify与sersync+rsync实时数据同步笔记

    Rsync(remote sync)远程同步工具,通过rsync可以实现对远程服务器数据的增量备份通过,但rsync自身也有缺陷,同步数据时,rsync采用核心算法对远程服务器的目标文件进行对比,只进 ...