穿插之前的JAVAWEB项目,之后的Spring框架。
JAVAWEB项目:用到技术点
使用tomcat,配置运行一下
某新闻系统,主题为例,Topic
搭建框架
controller是之前的写法,今天的测试,换成了一个test包,在test包下建立一个test类,来测试业务层接口及其实现类。
这个其实和使用servlet测试是一样。
刚才我们讲了,搭建。在控制台做了测试输出。
数据库mysql,oracle
有mysql的数据访问层的实现,有oracle的数据访问层的实现。
业务层,这里实现的是TopicDaoMysqlImpl,针对的mysql数据库的操作。
我们现在的操作都变了,要去操作oracle数据库。怎么办呢???
TopicDao topicDao=new TopicDaoMysqlImpl();
代码改变:
TopicDao topicDao=new TopicDaoOracleImpl();
运行之后,可以看到,会改变为删除oracle数据库中的主题编号:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GKiyCtrG-1591145306194)(E:\政通路\课堂笔记\S2\Spring\assets\image-20200601163742411.png)]y
大家要总结一下,当我们的数据库变更的时候,这样操作的方式好不好呢???
假如说,我们的项目已经部署上线了,项目在运行,你来改变代码来了。不能说肯定会出现问题,但是出现问题的几率一定是比较大。
能不能有一种方式,由客户自己来决定变更使用哪种数据库或者是客户自己决定某种操作。
这种问题,其实就是程序的耦合问题。
之前学习过OOP,三大特征:封装、继承、多态。
要实现的目标是:高内聚、低耦合、高复用
我们在写程序的时候,尽量低耦合。不new具体的对象;
重点代码:
package com.aaa.service.impl;
import com.aaa.dao.TopicDao;
import com.aaa.dao.impl.TopicDaoMysqlImpl;
import com.aaa.dao.impl.TopicDaoOracleImpl;
import com.aaa.service.TopicService;
/**
* Created by 张晨光 on 2020/6/1 16:19
* 主题业务层的实现类;java程序员 调用dao层,不改.
* 调用dao层的接口及其实现;
*/
public class TopicServiceImpl implements TopicService {
//定义dao层对象,及其实现类;
//TopicDao topicDao=new TopicDaoMysqlImpl();
//TopicDao topicDao=new TopicDaoOracleImpl();
//这种方式:是通过new 出来dao层对象的具体的实现类。
//能不能有一种方式,交由客户自己来调用的时候来实现呢???
//尽量少的动代码;
//这种其实就是程序之间的耦合问题。
//********************松耦合的实现************
TopicDao topicDao;
//创建它的getter/setter
public TopicDao getTopicDao() {
return topicDao;
}
//重点看这个:参数是一个TopicDao的对象;
public void setTopicDao(TopicDao topicDao) {
this.topicDao = topicDao;
}
@Override
public void deleteTopicById(Integer id) {
//在方法里面,通过dao层对象去执行删除操作;
//注意看:这里面有topicDao的对象的new ???没有了
topicDao.deleteTopicById(id);
}
}
客户端的使用:
TopicService topicService=new TopicServiceImpl();
//在业务层实现类代码里面,已经没有了new TopicDaoOracleImpl的代码,我们的目标就是去掉这个
//代码,实现松耦合
//通过setter来实现
//((TopicServiceImpl) topicService).setTopicDao(new TopicDaoOracleImpl());
//客户变更为了mysql
((TopicServiceImpl) topicService).setTopicDao(new TopicDaoMysqlImpl());
//由原来在业务层实现类的具体的new xxxImpl,交由客户端test类自动选择,我要new。
//
topicService.deleteTopicById(3);//模拟实现;
总结
作业:
—************
首先是熟练操作IDEA,创建WEB项目,使用tomcat,配置、部署运行等。
复习:
面向对象的目标:高内聚、低耦合、高复用
原来JAVAWEB项目存在高耦合的情况,我们要解耦,我们使用的接口对象的setter()方法进行解耦操作。
程序的耦合 耦合:程序间的依赖关系,包括: a.类之间的关系 b.方法间的关系 解耦:降低程序间的依赖关系 为bug生,为bug死,为bug奋斗终生 为解耦生,为解耦死,为解耦奋斗终生–》只要项目你不断完善,就存在类、方发、模块、项目之间的耦合度。 实际开发中: 应该做到,编译时不依赖,运行时依赖 解耦的思路: 第一步:使用反射来创建对象,而避免使用new关键字。Class.forName("") 第二步:通过读取配置文件来获取要创建的对象全限定类名。xxx.properties/xxx.xml文件
使用xml文件的解耦,这个将来和spring框架会联系起来,将我们的技术串起来。以听为主,不用记忆。
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<!--beans:指的所有bean的集合,使用xml文件进行解耦-->
<!--bean:单个bean的配置文件;id:bean的编号;class:bean路径-->
<!--class:mysql下数据库的实现类;给这个类起id名topicDaoMysqlImpl-->
<bean id="topicDaoMysqlImpl" class="com.aaa.dao.impl.TopicDaoMysqlImpl"></bean>
<!--topicServiceImpl解耦-->
<bean id="topicServiceImpl" class="com.aaa.service.impl.TopicServiceImpl"></bean>
</beans>
bean:咖啡豆;在java 组件
JAVABEAN:指的就是JAVA里面的可重用组件,玩具:可以由若干零部件组成,组件(组成的零件),在JAVA里面,业务层的接口、接口的实现类、dao层接口、dao层接口的实现类,可以被多次调用(被重用),这些被重用的类、接口都是JAVABEAN。
JAVABEAN的范围远大于实体类,实体类仅仅指的是业务传递数据时的一种重用形态。
IDEA的web-INF创建,lib目录,然后把xml的jar放进去,然后Add as Library
package com.aaa.util;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* Created by 张晨光 on 2020/6/2 15:01
* Bean:重用组件;--》JAVABEAN;
* Factory:工厂的意思;BeanFactory:Bean的工厂;
* 顾名思义:批量创建Bean;操作beans.xml文件,创建bean
*/
public class BeanFactory {
//定义静态方法根据id来获取Bean对象;
public static Object getBean(String id){
//用类加载器解析xml文件
try {
SAXReader reader = new SAXReader(); //xml的reader对象
//getClassLoader():类加载器,getResourceAsStream:将资源加载为流;
Document document = reader.read(BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml"));
//xpath技术获得bean元素;相当于之前js:document.getElementById("id")
Element element = (Element) document.selectSingleNode("//bean[@id='"+id+"']");
//拿到class属性里面的值
String value = element.attributeValue("class");
//获得反射对象
System.out.println(value);
//通过类的全限定名加载类对象[包名+类名];得到value类的class(TopicDaoMysqlImpl):它的类信息;
//是不是可以想到:Class.forName("com.mysql.cj.jdbc.Driver")
Class clazz = Class.forName(value);
//获得实例
return clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
}
}
//2.1通过BeanFactory来获取一下;
TopicService topicService = (TopicService) BeanFactory.getBean("topicService");
//2.直接调用即可
topicService.deleteTopicById(2);