SpringBoot-SpringData-oneToOne
来源:互联网 发布:怎么样开淘宝店视频 编辑:程序博客网 时间:2024/05/18 03:03
前面说了SpringBoot-SpringData-JPA集成
以这个项目为基础,继续SpringData的一些功能
下面说一下一对一关系 @oneToOne
一些概念:
单向关联:一个实体可以获得另一个实体对象双向关联:两个实体可以相关或得对方对象一对一关联:一个实体只能获得一个对方实体的引用
@OneToOne的注解
@Target({METHOD, FIELD}) @Retention(RUNTIME)public@interfaceOneToOne { Class targetEntity() default void.class; CascadeType[]cascade()default(); FetchType fetch() default EAGER; boolean optional() default true; String mappedBy() default "";}
1,targetEntity 属性表示默认关联的实体类型,默认为当前标注的实体类。
2,cascade属性表示与此实体一对一关联的实体的级联样式类型。
3,fetch属性是该实体的加载方式,默认为即时加载EAGER
4,optional属性表示关联的该实体是否能够存在null值,默认为ture,如果设置为false,则该实体不能为null,
并且要配合使用@JoinColumn标记,将实体关系关系设置为唯一的,不为null而且不能更新
@OneToOne(optional=false)@JoinColumn(name="address_id", unique=true, nullable=false, updatable=false)private AddressEo address;
@JoinColumn注解
@Target({METHOD, FIELD}) @Retention(RUNTIME)public@interfaceJoinColumn { String name() default ""; String referencedColumnName() default ""; boolean unique() default false; boolean nullable() default true; boolean insertable() default true; booleanupdatabledefaulttrue; String columnDefinition() default ""; String table() default "";}
1,@JoinColumn注释是保存表与表之间关系的字段
2,如果不设置name,默认name = 关联表的名称+”-“+关联表主键的字段名,在上面实例3,中,默认为“address_id”
默认情况下,关联实体的主键一般是用来做外键的,但如果此时不想用主键作为外键,则需要设置referencedColumnName属性,如:
create table address ( id int(20) not null auto_increament, ref_id int(20) notn ull, province varchar(50), city varchar(50), postcode varchar(50), detail varchar(50), primary key(id))@OneToOne@JoinColumn(name="address_id", referencedColumnName="ref_id")private AddressEO address;
@PrimarKeyJoinColumn
@Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface PrimaryKeyJoinColumn { String name() default ""; String referencedColumnName() default ""; String columnDefinition() default ""; }
模型
以人和身份证一对一关系进为模型
用户和身份证为例模拟SpringData在实际开发中为我们带来的便利
项目目录
项目包含用户User表,身份证Card表,及各自的数据库操作层,和一个测试类
domain
表关联方式
a、若使用外键关联,则考虑默认关联,只需要加@OneToOne标记即可。
b、若使用主键关联,则需要配合@PrimaryKeyColumn注释
c、若使用字段关联,则需要配合@JoinColumn注释使用
@Entitypublic class User { //没有默认构造会报错 public User(){ } public User(String name, Integer age, Card card) { this.name = name; this.age = age; this.card = card; } @Id @GeneratedValue private Long id; @Column(nullable = false) private String name; @Column(nullable = false) private Integer age; /** * @OneToOne:一对一关联 * cascade:级联配置 * CascadeType.PERSIST: 级联新建 * CascadeType.REMOVE : 级联删除 * CascadeType.REFRESH: 级联刷新 * CascadeType.MERGE : 级联更新 * CascadeType.ALL : 以上全部四项 * @JoinColumn:主表外键字段 * cid:Care所映射的表中的一个字段(会在User表创建一个cid字段,与Care外键关系) */ @OneToOne(cascade = CascadeType.REFRESH)//使用CascadeType.ALL无法保存成功 @JoinColumn(name = "cid", unique=true) private Card card; public Card getCard() { return card; } public void setCard(Card card) { this.card = card; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; }}
如果不做双向oneToOne,Card表不需要添加user参数及注解
@Entitypublic class Card { public Card() { } public Card(Integer cardId, String cardNumber) { this.cardNumber = cardNumber; this.cardId = cardId; } @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer cardId; @Column(nullable = false) private String cardNumber; /** * @OneToOne:一对一关联 * mappedBy = "card":一对一配置参考了card * mappedBy = "card"中的User类中的getCard()中的Care(去除get) * 如果User类getCard()改为getIdCard(),这里就要写成:mappedBy = "idCard" */ @OneToOne(mappedBy = "card", fetch=FetchType.EAGER) private User user; public Integer getCardId() { return cardId; } public void setCardId(Integer cardId) { this.cardId = cardId; } public String getCardNumber() { return cardNumber; } public void setCardNumber(String cardNumber) { this.cardNumber = cardNumber; } public User getUser() { return user; } public void setUser(User user) { this.user = user; }}
DAO
public interface UserRepository extends JpaRepository<User, Long> { User findByName(String name); User findByNameAndAge(String name, Integer age); @Query("from User u where u.name=:name") User findUser(@Param("name") String name);}public interface CareRepository extends JpaRepository<Card, Long> { Card findByCardNumber(String name);}
application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/testspring.datasource.username=rootspring.datasource.password=123spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.jpa.properties.hibernate.hbm2ddl.auto=update#开启SQL显示spring.jpa.show-sql=true
Test
@RunWith(SpringJUnit4ClassRunner.class)@SpringApplicationConfiguration(DemoApplication.class)public class oneToOneTest { @Autowired private UserRepository userRepository; @Autowired private CareRepository careRepository; @Test public void test() throws Exception { // 创建测试数据 careRepository.save(new Card(1, "aaabbbccc")); //保存 Card care1 = new Card(); care1.setCardId(1); userRepository.save(new User("Test1", 20, care1)); //正向取数 User user = userRepository.findByName("Test1"); Card card = user.getCard(); Assert.assertEquals("aaabbbccc", card.getCardNumber()); //反向取数 Card care = careRepository.findByCardNumber("aaabbbccc"); User user_Temp = care.getUser(); Assert.assertEquals("Test1", user_Temp.getName()); }}
运行结果
SpringData输出的SQL:
Hibernate: insert into card (card_number) values (?)Hibernate: insert into user (age, cid, name) values (?, ?, ?)Hibernate: select user0_.id as id1_1_, user0_.age as age2_1_, user0_.cid as cid4_1_, user0_.name as name3_1_ from user user0_ where user0_.name=?Hibernate: select card0_.card_id as card_id1_0_0_, card0_.card_number as card_num2_0_0_, user1_.id as id1_1_1_, user1_.age as age2_1_1_, user1_.cid as cid4_1_1_, user1_.name as name3_1_1_ from card card0_ left outer join user user1_ on card0_.card_id=user1_.cid where card0_.card_id=?Hibernate: select user0_.id as id1_1_1_, user0_.age as age2_1_1_, user0_.cid as cid4_1_1_, user0_.name as name3_1_1_, card1_.card_id as card_id1_0_0_, card1_.card_number as card_num2_0_0_ from user user0_ left outer join card card1_ on user0_.cid=card1_.card_id where user0_.cid=?Hibernate: select card0_.card_id as card_id1_0_, card0_.card_number as card_num2_0_ from card card0_ where card0_.card_number=?Hibernate: select user0_.id as id1_1_1_, user0_.age as age2_1_1_, user0_.cid as cid4_1_1_, user0_.name as name3_1_1_, card1_.card_id as card_id1_0_0_, card1_.card_number as card_num2_0_0_ from user user0_ left outer join card card1_ on user0_.cid=card1_.card_id where user0_.cid=?
自动创建的数据库
-- ------------------------------ Table structure for `card`-- ----------------------------DROP TABLE IF EXISTS `card`;CREATE TABLE `card` ( `card_id` int(11) NOT NULL AUTO_INCREMENT, `card_number` varchar(255) NOT NULL, PRIMARY KEY (`card_id`)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;-- ------------------------------ Records of `card`-- ----------------------------BEGIN;INSERT INTO `card` VALUES ('1', 'aaabbbccc');COMMIT;-- ------------------------------ Table structure for `user`-- ----------------------------DROP TABLE IF EXISTS `user`;CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `age` int(11) NOT NULL, `name` varchar(255) NOT NULL, `cid` int(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `UK_luurgctv320vav1gdny78j1a5` (`cid`), CONSTRAINT `FK_luurgctv320vav1gdny78j1a5` FOREIGN KEY (`cid`) REFERENCES `card` (`card_id`)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;-- ------------------------------ Records of `user`-- ----------------------------BEGIN;INSERT INTO `user` VALUES ('1', '20', 'Test1', '1');COMMIT;
结论
可以看到user表中有一个cid字段与Card中的card_id形成了外键关系从Test测试结果看出,双向映射成功,即取User可以拿到Card实例,反之亦然
代码下载:
CSDN下载
GitHub下载
- SpringBoot-SpringData-oneToOne
- SpringBoot-SpringData-JPA集成
- SpringBoot-SpringData-ManyToMany
- SpringBoot-SpringData-ManyToOne
- SpringBoot-SpringData-懒加载
- Springboot+SpringData+jpa
- SpringBoot-SpringData-懒加载
- SpringBoot+SpringData整合开发
- springBoot整合springData Jpa
- SpringBoot-SpringData-多数据源
- SpringBoot-03JPA Hibernate SpringData
- SpringData 基于SpringBoot快速入门
- SpringBoot+SpringData实现SpringMVC简单项目
- SpringBoot 整合 SpringData 入门案例(一)
- onetoone
- @OneToOne
- SpringData
- springData
- 静态队列
- Android应用程序组成
- AFN请求超时时间
- java中string和int相互转换
- iostat
- SpringBoot-SpringData-oneToOne
- Struts2
- Astyle 给代码调整格式
- MonoBehaviour生命周期
- ZooKeeper集群搭建实例,以及集成dubbo时的配置
- js中的function和this---new Function(a,b,body)方式
- IIS服务器配置外部访问端口及asp,php环境搭建
- Android开发工具篇:华为手机root
- Clob类型