级联赋值(Bean管理XML方式)
在实际需求中, 我们可能会存在有很多的实体类之间都是有一对多的关系的, 比如部门和员工之间一个部门中就有很多的员工, 一个员工属于一个部门, 这个时候如果我们在创建员工实体类对象的时候, 我们肯定是有一个属性是部门实体类类型的, 所以也就是我们在创建员工实体对象时要给其中的部门实体类类型的属性赋一个值
-
此时不仅仅是创建一个部门实体对象然后赋值给员工对象的对应属性就可以, 我们在创建员工对象的时候我们要给对应的部门类型属性赋值, 这个时候赋值的时候我们要创建一个部门实体类类型的对象赋值给对应的员工对象中对应的部门类型属性中, 这个时候我们又多个部门, 所以这个时候我们的每个员工对象的部门可能不同, 所以我们创建部门对象的时候不是简单的new一下就可以, 而是要也进行一个赋值操作, 因为我们的某个员工肯定是对应某一个确定的部门的
一对多的关系其实就是一个正面的一对多的关系加上一个反面的一对一的关系, 就好比部门和员工之间部门对员工就是一对多, 员工对部门就是一对一
级联赋值的两种方式:
1. 注入内部Bean的方式
① : 给出员工类和部门类:
员工类:
public class Dept {
//声明私有属性, 表示部门名称
private String dname;
//提供共有的set()方法, 为了使用set方式完成注入
public void setDemo(String dname){
this.dname = dname;
}
}
部门类:
package com.ffyc.bean;
public class Emp {
private String ename;
private String gender;
//员工属于某一个部门, 对应员工属于的部门我们使用对象的形式来表示
public Dept dept;
public void setDept(Dept dept){
this.dept = dept;
}
public void setEname(String ename) {
this.ename = ename;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Emp{" +
"ename='" + ename + '\'' +
", gender='" + gender + '\'' +
", dept=" + dept +
'}';
}
}
② : 在Spring配置文件中进行配置
<!-- Service类的对象创建 -->
<bean id = "emp" class = "com.ffyc.spring5.bean.Emp">
<!-- 设置两个普通的属性 -->
<property name = "ename" value = "lucy"></property>
<property name = "gender" value = "女"></property>
<!-- 设置对象类型属性, 这里使用注入内部Bean的方式 -->
<property name = "dept">
<bean name = "dept" class = "com.ffyc.spring5.bean.dept">
<!-- 完成级联赋值, 给属性对应的实体类对象的属性赋值 -->
<property name = "dname" value = "安保部"></property>
</bean>
</property>
</bean>
-
注入内部Bean是直接在对应的property标签体中写一个bean标签, 而注入外部Bean是用对应的property标签的ref属性来引入一个外部bean标签
- 这里说的外部bean标签指的是在此Spring配置文件中, 并且在当前配置的bean标签之外的bean标签
- 说白了外部bean标签其实就是和当前配置的bean标签同级的bean标签, 我们就称之为: 外部bean, 而在当前配置的bean标签内部的bean标签我们就称之为: 内部bean
- 这里说的外部bean标签指的是在此Spring配置文件中, 并且在当前配置的bean标签之外的bean标签
③ : 测试代码
@Test
public void TestBeans(){
//1. 加载Spring配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
//2. 获取配置创建的对象
Emp emp = context.getBean("emp",Emp.class);
//3. 测试, 我们在Emp类中重写了toString()方法, 所以我们只需要打印输出测试
System.out.println(emp);
}
2.注入外部Bean方式
注入外部Bean方式来完成级联赋值又分为了两种方式:
-
在创建外部Bean时在外部Bean中完成级联赋值
① : 给出员工类和部门类:
员工类:
public class Dept { //声明私有属性, 表示部门名称 private String dname; //提供共有的set()方法, 为了使用set方式完成注入 public void setDemo(String dname){ this.dname = dname; } }
部门类:
package com.ffyc.bean; public class Emp { private String ename; private String gender; //员工属于某一个部门, 对应员工属于的部门我们使用对象的形式来表示 public Dept dept; public void setDept(Dept dept){ this.dept = dept; } public void setEname(String ename) { this.ename = ename; } public void setGender(String gender) { this.gender = gender; } @Override public String toString() { return "Emp{" + "ename='" + ename + '\'' + ", gender='" + gender + '\'' + ", dept=" + dept + '}'; } }
②在Spring配置文件中进行配置
<!-- Service类的对象创建 --> <bean id = "emp" class = "com.ffyc.spring5.bean.Emp"> <!-- 设置两个普通的属性 --> <property name = "ename" value = "lucy"></property> <property name = "gender" value = "女"></property> <!-- 设置对象类型属性, 这里使用的是注入外部Bean的方式 --> <property name = "dept" ref = "dept"></property> </bean> <bean name = "dept" class = "com.ffyc.spring5.bean.dept"> <!-- 完成级联赋值, 给属性对应的实体类对象的属性赋值 --> <!-- 这里是创建外部Bean的时候就完成了对外部Bean的赋值操作 --> <property name = "dname" value = "安保部"></property> </bean>
③ : 测试
@Test public void TestBeans(){ //1. 加载Spring配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml"); //2. 获取配置创建的对象 Emp emp = context.getBean("emp",Emp.class); //3. 测试, 我们在Emp类中重写了toString()方法, 所以我们只需要打印输出测试 System.out.println(emp); }
-
在引入外部Bean时完成外部Bean的赋值, 也就是级联赋值
① : 给出员工类和部门类:
员工类:
package com.ffyc.bean; public class Dept { //声明私有属性, 表示部门名称 private String dname; //提供共有的set()方法, 为了使用set方式完成注入 public void setDemo(String dname){ this.dname = dname; } //提供公共的get()方法, 以便于在xml文件中可以从其他类中获取到此私有属性 public String getDname() { return dname; } }
部门类:
package com.ffyc.bean; public class Emp { private String ename; private String gender; //员工属于某一个部门, 对应员工属于的部门我们使用对象的形式来表示 public Dept dept; public void setDept(Dept dept){ this.dept = dept; } public void setEname(String ename) { this.ename = ename; } public void setGender(String gender) { this.gender = gender; } @Override public String toString() { return "Emp{" + "ename='" + ename + '\'' + ", gender='" + gender + '\'' + ", dept=" + dept + '}'; } }
②在Spring配置文件中进行配置
<!-- Service类的对象创建 --> <bean id = "emp" class = "com.ffyc.spring5.bean.Emp"> <!-- 设置两个普通的属性 --> <property name = "ename" value = "lucy"></property> <property name = "gender" value = "女"></property> <!-- 设置对象类型属性, 这里使用的是注入外部Bean的方式 --> <property name = "dept" ref = "dept"></property> <property name = "dept.dname" value = "技术部"></property> </bean> <bean name = "dept" class = "com.ffyc.spring5.bean.dept"></bean>
-
注意:我们此时给dept.dname赋值的时候是在emp对应的bean对象中, 这个时候如果我们给emp对象中的私有属性赋值是没有问题的, 但是这个时候我们对emp对象中的某个属性对象中的某个私有属性赋值, 这个时候就是有问题的了, 此时我们的dname是Dept类中的私有属性, 但是此时我们却是在Emp类中完成对其的赋值, 这个时候是不对的, 因为我们的私有属性只有在本类中才可以拿到, 这个时候就会有问题, 所以我们必须要将Dept类中的dname属性声明为public或者提供对应的dname属性的公共的get()方法, 然后我们能获得到这个属性之后才能在xml文件中对其属性进行一个赋值
- 这个时候我们提供了公共的set()方法, 按理说是可以对对应的dname属性赋值的, 但是这个时候不相同, 可能是由于此时我们在xml文件中首先要知道你有这个属性, 否则xml文件就会直接爆红
- 所以我们此时要在Dept类中提供dname属性的公共get()方法
③ : 测试
@Test public void TestBeans(){ //1. 加载Spring配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml"); //2. 获取配置创建的对象 Emp emp = context.getBean("emp",Emp.class); //3. 测试, 我们在Emp类中重写了toString()方法, 所以我们只需要打印输出测试 System.out.println(emp); }
-
补充:
我们使用在外部Bean注入中的引用时完成外部Bean赋值时要先引入外部bean, 引入了外部bean之后我们才能给引用的外部bean的属性在当前正在配置的bean中完成赋值
-
也就是先执行:
<property name = "dept" ref = "dept"></property>
- 给dept属性注入对应的name值(或者id值都可以)为dept的bean对象
-
然后执行:
<property name = "dept.dname" value = "技术部"></property>
- 然后给dept属性中的dname属性赋值为"技术部"
- 注意: 此时给dept中的dname属性赋值不是在本类中, 也就是不是在class属性为Dept类的全类名的bean标签中, 所以我们要提供公共的get()方法, 否则我们的私有属性是访问不到的, 在xml中就会爆红
- 然后给dept属性中的dname属性赋值为"技术部"