Java学习打卡:第二十三天
Java养成计划(打卡第22天)
内容管理
昨天我们讲解反射的时候就提到过这个数据库迁移,由于昨天讲解的内容很多,所以就没有上小项目,这里我们就详细讲解一下数据库迁移模拟这个项目
实例背景
一个公司随着业务的扩大需要将所有与MySQL绑定的Java业务全部换成存储量更大的Oracle,你发现java业务中一共几千个文件,那难道要累死累活几天一个个点开文件,将所有的MySOL改成Oracle? 那效率太低下了
架构的补充
我们这里具体实现是我们的service服务器和数据库不是直接绑定的,中间会有一个Dao接口,该街廓中含有操作数据库的具体方法,我们通过实现具体的Dao来达到操作的目的
实例解答
创建具体的类实现模拟的功能
在具体的软件开发中不同的类的功能是分明的,比如我们的service类是专门用作业务处理的,那么与业务不相关的操作就不能放在该类
用于实现相关的操作,调用具体的实现类
Dao接口
package flectDemo;
public interface Dao {
//向数据库中添加成员
public void add(String name);
//从数据库中删除成员
public void delete(String name);
//这里不会具体去连接数据库,就不写set和get操作了
}
这里利用接口来实现多态
MySQLDao实现类
package flectDemo;
public class MySQLDao implements Dao{
@Override
public void add(String name) {
System.out.println("向MySQL数据库中添加"+ name);
}
@Override
public void delete(String name) {
System.out.println("从MySQL数据库中删除"+ name);
}
}
OracleDao实现类
package flectDemo;
public class OracleDao implements Dao{
//根据不同的接口创建不同的实现类,Strategery pattern
@Override
public void add(String name) {
System.out.println("向Oracle数据库中添加"+ name);
}
@Override
public void delete(String name) {
System.out.println("从Oracle数据库中删除"+ name);
}
}
Sevrice类
package flectDemo;
public class Sevrice {//这个时候我们就读取文件的字符串产生相应的类,那这里这个读取操作不属于我们的业务操作,因此需要创建一个新的类DaoFactory
//为了应对数据库迁移,我们这里创建具体的实现类对象就要用到反射
// Dao d = new OracleDao(); //按照原始方法就需要这样,但是我们一旦迁移就要进入servic中修改这个语句
//那我们就把改动部分提取出来,为类的配置文件
Dao d = DaoFactory.getFactory().getInstance();//先创建一个factory对象再调用读取方法
//逻辑操作
public void add(String name)
{
d.add(name);
}
public void delete(String name)
{
d.delete(name);
}
public static void main(String[] args) {
Sevrice s1 = new Sevrice();
s1.add("Tom");
}
}
DaoFactory类(反射)
package flectDemo;
import java.io.FileInputStream;
import java.util.Properties;
public class DaoFactory {//用于读取配置文件产生相应的实现类
private Properties prop;//属性列表
private static DaoFactory factory;//创建一个类对象变量
//这里我们读取该文件只能产生一个Dao对象,为了防止有多个对象,使用Singleton
private DaoFactory() {
};//创建一个无参的私有的构造方法
//产生了一个代理读取工厂
public static DaoFactory getFactory() {
if(factory == null)
{
factory = new DaoFactory();
}
return factory;
}
//从配置文件中获取到具体的Dao对象
public Dao getInstance()
{
prop = new Properties();
try {//真是生气,这里我们加载文件还要写绝对路径才找到
prop.load(new FileInputStream("D:\\Java项目\\cFng.javaLearn\\src\\flectDemo\\dao.properties"));//从文件输入流中读取属性列表
String dao = prop.getProperty("dao");//获取到具体的属性列表(字符串形式)
//将字符串利用反射机制转换成对应的类
@SuppressWarnings("unchecked")
Class<Dao> stz = (Class<Dao>)Class.forName(dao);//将字符串转换成类
return stz.getDeclaredConstructor().newInstance(); //java9之后就不能直接使用newInstance获取对象,要使用getDeclaredConstructor().newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;//创建不成功,返回null
}
}
配置文件
dao = flectDemo.MySQLDao
我们运行之后输出的结果是
向MySQL数据库中添加Tom
这里如果我们要进行数据库迁移,就不需要进入每个service中去修改实现类了,我们直接在配置文件中来修改就好了,这样所有的就改好了,所以说反射真的非常强大
总结分享
这里的项目只是简单的演示,这里有几个需要注意的点,
- 关于根据类的字节码获取对象的时候,java9之后的版本就必须加上getDeclredConstructor之后再newInstance才能创建对象
- 获取文件的路径时,单独只写文件名是不可以的,要写上路径
- 文件中写类名要加上包名,也就是路径,防止歧义
好了,我们今天的分享就到此结束了,如果有什么疑问欢迎咨询~~