JPA中的@Embedded和@Embeddable注释的使用
JPA中的@Embedded和@Embeddable注释
概念很枯燥, 通过代码理解吧
模拟场景
1.建表,插入一条数据
create table if not exists `User`(
`id` int(4) auto_increment not null,
`name` varchar(8) not null,
`city` varchar(12) not null,
`district` varchar(12) not null,
`street` varchar(12) not null,
primary key(`id`)
)engine=innodb default charset=utf8;
insert into user values(1, 'Joshua', '男', 1.75, '重庆', '璧山区', 'XX街道', 'XXX小区');
2.建立对应 实体类 以及 repository接口
User类
@Entity
@Table(catalog = "jpa", name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "name")
private String name;
@Column(name = "sex")
private String sex;
@Column(name = "height")
private Float height;
@Column(name = "city")
private String city;
@Column(name = "district")
private String district;
@Column(name = "street")
private String street;
@Column(name = "community")
private String community;
}
UserRepository接口
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
}
进行环境搭建测试
@SpringBootTest
class DemoSpringApplicationTests {
@Autowired
private UserRepository userRepository;
@Test
void test01() {
userRepository.findById(1).ifPresent(System.out::println);
// 输出结果 => User(id=1, name=Joshua, sex=男, height=1.75, city=重庆, district=璧山区, street=XX街道, community=XXX小区)
}
}
至此,一个简单的环境搭建成功了
那么问题来了, User类字段过多,是不是可以整合一下 ?
比如 city 、district 、street 、community这些字段,我们都可以整合为一个 Address 类,并通过@Embedded和@Embeddable注解进行关联
Address 类
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
//以上四个注解用于构造对象,以及get/set/toString...
@Embeddable // 声明该类是可嵌入的
public class Address {
/*
属性名有些问题需要注意下:
1. 尽量和数据库字段一样
2. 如果属性名和数据库字段名不一样,加上@Column(name = "数据库字段名")
3. 拓展: 如果Address类不仅被 User 引用,其他类也在使用,说明这些表结构类似,但是字段名在每个表不一样,可以去了解一下@AttributeOverrides注解
*/
private String city;
private String district;
private String street;
private String community;
}
改造后的 User 类
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(catalog = "jpa", name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "name")
private String name;
@Column(name = "sex")
private String sex;
@Column(name = "height")
private Float height;
@Embedded // 其实通过测试发现,这个注解在Address使用了@Embeddable后可省略,但是防止后面出问题还是加上
private Address address;
}
进行测试
@SpringBootTest
class DemoSpringApplicationTests {
@Autowired
private UserRepository userRepository;
@Test
void test02() {
Address address = Address.builder()
.city("重庆").district("合川区").street("YY街道").community("YYY小区").build();
User user = User.builder()
.id(2).name("Jack").height(1.8f).sex("男").address(address).build();
User save = userRepository.save(user);
System.out.println(save);
// 输出结果 => User(id=8, name=Jack, sex=男, height=1.8, address=Address(city=重庆, district=合川区, street=YY街道, community=YYY小区))
}
}
查看数据库发现, 这条数据成功插入