SpringBoot整合JPA 完成关联查询
以专家和事件为例
sql语句
CREATE TABLE `expert` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`expertName` varchar(255) DEFAULT NULL COMMENT '专家名称',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
CREATE TABLE `event` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`eventName` varchar(255) DEFAULT NULL COMMENT '事件名称',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-5</artifactId>
<version>2.4.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
application文件
server:
port: 9999
spring:
application:
name: springboot-jpa
datasource:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/xxxx?useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconect=true&serverTimezone=GMT%2b8
username: xxxx
password: xxxx
driver-class-name: com.mysql.jdbc.Driver
filters: stat
maxActive: 50
initialSize: 0
maxWait: 60000
minIdle: 1
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: select 1 from dual
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxOpenPreparedStatements: 20
removeAbandoned: true
removeAbandonedTimeout: 180
jpa:
show-sql: true
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
ddl-auto: update
properties:
hibernate:
format_sql: true
show_sql: true
current_session_context_class: org.springframework.orm.hibernate5.SpringSessionContext
dialect: org.hibernate.dialect.MySQL5Dialect
实体类
@Entity
@Table ( name ="event" )
@DynamicInsert(true)
@DynamicUpdate(true)
public class Event implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id" )
private Integer id;
/**事件名称*/
@Column(name = "eventName" )
private String eventName;
//cascade = CascadeType.PERSIST 代表级联保存
@ManyToMany(cascade = CascadeType.PERSIST)
/**
* name : 中间表名称
* joinColumns : 当前表中主键关联字段
* JoinColumn 字段名 referencedColumnName 引用实体表字段名
* inverseJoinColumns : 当前表中另一个关联字段
*
*/
@JoinTable(name = "expert_event",joinColumns = @JoinColumn(name = "expert_id",referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "event_id",referencedColumnName = "id"))
private Set<Expert> expertSet = new HashSet<>();
get
set
...
@Entity
@Table ( name ="expert" )
@DynamicInsert(true)
@DynamicUpdate(true)
public class Expert implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id" )
private Integer id;
/**专家名称*/
@Column(name = "expertName" )
private String expertName;
//mappedBy 关联的另一侧字段名称
@ManyToMany(mappedBy = "expertSet")
private Set<Event> eventSet = new HashSet<>();
get
set
...
}
dao层直接继承JpaRepository即可
public interface EventRepository extends JpaRepository<Event,Integer> {
}
编写测试类
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = TmpApplication.class)
public class JpaTest {
@Autowired
private EventRepository eventRepository;
@Test
public void save(){
//创建事件
Event event = new Event();
event.setEventName("消防事件");
//创建专家
Expert expert = new Expert();
expert.setExpertName("成博士");
Expert expert1 = new Expert();
expert1.setExpertName("赵博士");
//关联
event.getExpertSet().add(expert);
event.getExpertSet().add(expert1);
expert.getEventSet().add(event);
expert1.getEventSet().add(event);
this.eventRepository.save(event);
}
@Test
public void select(){
//查询事件
Event event1 = eventRepository.findById(2).get();
System.out.println(event1.getEventName());
//在测试类中,对象下面的集合取出会报一个session错误
//是因为jpa默认是懒加载,改为立即加载或者在controller测试即可
Set<Expert> expertSet = event1.getExpertSet();
for (Expert expert : expertSet) {
System.out.println(expert.getExpertName());
}
}
至此一个JPA多对多关联添加查询就完成了。有什么问题欢迎评论区指出