java 使用BeanFactory实现service与dao层解耦合详解

目录
  • BeanFactory实现service与dao层解耦合
    • 整体的实现思路是
  • DAO层实现类CreatFactory.java

BeanFactory实现service与dao层解耦合

在实际网站开发过程中,在service会new一个dao从而调用该dao中的方法,如下代码,但是一旦更换数据库需要改变dao的指向,此时就需要重新部署新的项目

UserDao UserDao=new UserDaoImpl();

在本文中使用BeanFactory的方式,在xml中配置dao的指向,一旦发生变化,无需重新部署,只需要改变xml中的配置即可,代码如下:

UserDao UserDao=(UserDao)BeanFactory.createObject("UserDao");

全部实现代码如下,请重点关注解耦思想,即关注BeanFactory中的实现

整体的实现思路是

UserServiceImp调用BeanFactory中的createObject("UserDao")方法----》在BeanFactory中解析xml文件,获取xml中id与UserDao相同的节点,并获取该节点上的class文件----》利用反射机制创建对象并返回。

UserServiceImp.java

package cn.itcast.store.service.serviceImp;
import java.sql.SQLException;
import cn.itcast.store.dao.UserDao;
import cn.itcast.store.dao.daoImp.UserDaoImp;
import cn.itcast.store.domain.User;
import cn.itcast.store.service.UserService;
import cn.itcast.store.utils.BeanFactory;
public class UserServiceImp implements UserService {
 UserDao UserDao=(UserDao)BeanFactory.createObject("UserDao"); 

 @Override
 public void userRegist(User user) throws SQLException {
  //实现注册功能
  UserDao.userRegist(user);
 }

 @Override
 public boolean userActive(String code) throws SQLException {
  //实现注册功能

  ///对DB发送select * from user where code=?
  User user=UserDao.userActive(code);
  if(null!=user){
   //可以根据激活码查询到一个用户
   //修改用户的状态,清除激活码
   user.setState(1);
   user.setCode(null);
   //对数据库执行一次真实的更新操作  update user set state=1 , code=null where uid=?
   //update user set username=? , password=? ,name =? ,email=?, telephone =? ,birthday =? ,sex=? ,state=? ,code= ? where uid=?
   UserDao.updateUser(user);
   return  true;
  }else{
   //不可以根据激活码查询到一个用户
   return false;
  }
 }

 @Override
 public User userLogin(User user) throws SQLException {
  //此处:可以利用异常在模块之间传递数据   

  //select * from user where username=? and password=?
  User uu=UserDao.userLogin(user);
  if(null==uu){
   throw new RuntimeException("密码有误!");
  }else if(uu.getState()==0){
   throw new RuntimeException("用户未激活!");
  }else{
   return uu;
  }
 }
}

BeanFactory.java

package cn.itcast.store.utils;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import cn.itcast.store.dao.UserDao;
import cn.itcast.store.domain.User;
public class BeanFactory { 

 //解析XML
 public static Object createObject(String name) {
  try {
   //通过传递过来的name获取application.xml中name对应的class值

   //获取到Document对象
   SAXReader reader=new SAXReader();
   //如果获取application.xml文件的输入流 (application.xml必须位于src下)
   InputStream is=BeanFactory.class.getClassLoader().getResourceAsStream("application.xml");
   Document doc=reader.read(is);
   //通过Document对象获取根节点  beans
   Element rootElement = doc.getRootElement();
   //通过根节点获取到根节点下所有的子节点 bean,返回集合
   List<Element> list = rootElement.elements();
   //遍历集合,判断每个元素上的id的值是否和当前的name一致
   for (Element ele : list) {
    //ele相当于beans节点下的每个bean
    //获取到当前节点的id属性值
    //如果一致,获取到当前元素上class属性值
    String id=ele.attributeValue("id");
    if(id.equals(name)){
     String str=ele.attributeValue("class");
     //通过反射创建对象并且返回
     Class clazz=Class.forName(str);
     //利用class值通过反射创建对象返回
     return  clazz.newInstance();
    }
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
  return null;
 }

 public static void main(String[] args) throws SQLException {
  UserDao ud=(UserDao)BeanFactory.createObject("UserDao");
  User user=new User();
  user.setUsername("aaa");
  user.setPassword("aaa");
  User uu = ud.userLogin(user);
  System.out.println(uu);
 }
}

application.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans>
   <bean id="CategoryDao" class="cn.itcast.store.dao.daoImp.CategoryDaoImp"/>
   <bean id="UserDao" class="cn.itcast.store.dao.daoImp.UserDaoImp"/>
   <bean id="ProductDao" class="cn.itcast.store.dao.daoImp.ProductDaoImp"/>
</beans>

DAO层实现类CreatFactory.java

public class CreatFactory {
 //单例模式
 private static SqlSessionFactory factory=null;
 public static SqlSessionFactory creatFactory(){
  if(factory==null){
   //加载配置文件
   String resource = "mybatis/config.xml";//配置文件地址
   //读取文件resource,变成字符流
   Reader reader;
   try {
    reader = Resources.getResourceAsReader(resource);
    //将字符流,相当于Connection
    factory= new SqlSessionFactoryBuilder().build(reader);
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
  return factory;
 }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 结合Service层讲解DAO层的异常处理操作

    domain:只是定义一个javabean. dao:对于数据库的操作,都放到dao层,也就是dao里面通常是对数据库的增.删.改.查等操作. service:完成相应的业务逻辑处理,调用dao层. (web)servlet:完成界面请求.对界面进行跳转等等.servlet调用service层. 例子: 在domain包中,新建Xxx.java:在dao包中,新建IXxxDAO.java:在impl包中,新建XxxDAOImpl类:在test包中,新建XxxDAOTest.java,在XxxDA

  • 如何基于Spring使用工厂模式实现程序解耦

    这篇文章主要介绍了如何基于Spring使用工厂模式实现程序解耦,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1. 啥是耦合.解耦? 既然是程序解耦,那我们必须要先知道啥是耦合,耦合简单来说就是程序的依赖关系,而依赖关系则主要包括 1. 类之间的依赖 2. 方法间的依赖 比如下面这段代码: public class A{ public int i; } public class B{ public void put(A a){ System.o

  • SpringBoot Service和Dao的编写详解

    本文主要介绍了SpringBoot Service和Dao的编写详解,分享给大家,具体如下: 效果图 配置环境 创建数据库 数据库中文编码 建表 create table `student` ( `id` int(11) Not NULL AUTO_INCREMENT COMMENT '主键自增id', `name` varchar(250) NOT NULL DEFAULT ' ' COMMENT '姓名', PRIMARY KEY(`id`) )ENGINE=INNODB DEFAULT C

  • java 使用BeanFactory实现service与dao层解耦合详解

    目录 BeanFactory实现service与dao层解耦合 整体的实现思路是 DAO层实现类CreatFactory.java BeanFactory实现service与dao层解耦合 在实际网站开发过程中,在service会new一个dao从而调用该dao中的方法,如下代码,但是一旦更换数据库需要改变dao的指向,此时就需要重新部署新的项目 UserDao UserDao=new UserDaoImpl(); 在本文中使用BeanFactory的方式,在xml中配置dao的指向,一旦发生变

  • java 设计模式(DAO)的实例详解

    java 设计模式(DAO)的实例详解 应用场景:在Java程序中,经常需要把数据持久化,也需要获取持久化的数据,但是在进行数据持久化的过程中面临诸多问题(如:数据源不同.存储类型不同.供应商不同.访问方式不同等等),请问如何能以统一的接口进行数据持久化的操作? 其实这个我没学号(≧ ﹏ ≦).我的理解就是一个产品面向的用户不是单一的,所以我们要兼容许多情况如前面提到的数据源不同.存储类型不同.供应商不同.访问方式不同等等. ★ 解决方案 DAO的理解: 1.DAO其实是利用组合工厂模式来解决问

  • Java微服务实战项目尚融宝接口创建详解

    目录 需求 一.创建父工程srb 二.创建模块guigu-common 1.创建Maven模块 2.配置pom 三.创建模块service-base 1.创建Maven模块 2.配置pom 四.创建模块service-core 1.创建Maven模块 2.配置pom 五.代码生成器 1.创建数据库 2.创建代码生成器 六.启动应用程序 1.创建application.yml 2.创建SpringBoot配置文件 3.创建SpringBoot启动类 需求 积分等级CRUD列表和表单 一.创建父工程

  • Service Activity的三种交互方式(详解)

    service有两种类型: 本地服务(Local Service):用于应用程序内部 远程服务(Remote Sercie):用于android系统内部的应用程序之间 前者用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好. 后者可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可. 编写不需和Activity交互的本地服务示例 本地服务编写比较简单.首先,要创建一个Se

  • java编程实现并查集的路径压缩代码详解

    首先看两张路径压缩的图片: 并查集(Union-find Sets)是一种非常精巧而实用的数据结构,它主要用于处理一些不相交集合的合并问题.一些常见的用途有求连通子图.求最小生成树的 Kruskal 算法和求最近公共祖先(Least Common Ancestors, LCA)等. 使用并查集时,首先会存在一组不相交的动态集合 S={S 1 ,S 2 ,⋯,S k } ,一般都会使用一个整数表示集合中的一个元素. 每个集合可能包含一个或多个元素,并选出集合中的某个元素作为代表.每个集合中具体包含

  • Java图形化界面设计之容器(JFrame)详解

    Java图形化界面设计--容器(JFrame) 程序是为了方便用户使用的,因此实现图形化界面的程序编写是所有编程语言发展的必然趋势,在命令提示符下运行的程序可以让我们了解java程序的基本知识体系结构,现在就进入java图形化界面编程. 一.Java基本类(JFC) Java基本类("JavaFoundationClasses",JFC),由一些软件包组成.这些软件包主要包括下面一些应用程序接口(API): ·抽象窗口工具集(AWT)(1.1及以上版本). ·Swing构件. ·Jav

  • Java中SSM框架实现增删改查功能代码详解

    记录一下自己第一次整合smm框架的步骤. 参考博客和网站有:我没有三颗心脏 How2J学习网站 1.数据库使用的是mySql,首先创建数据库ssm1,并创建表student create database ssm1; use ssm1; CREATE TABLE student( id int(11) NOT NULL AUTO_INCREMENT, student_id int(11) NOT NULL UNIQUE, name varchar(255) NOT NULL, age int(1

  • java中synchronized(同步代码块和同步方法)详解及区别

     java中synchronized(同步代码块和同步方法)详解及区别 问题的由来: 看到这样一个面试题: //下列两个方法有什么区别 public synchronized void method1(){} public void method2(){ synchronized (obj){} } synchronized用于解决同步问题,当有多条线程同时访问共享数据时,如果进行同步,就会发生错误,Java提供的解决方案是:只要将操作共享数据的语句在某一时段让一个线程执行完,在执行过程中,其他

  • java动态添加外部jar包到classpath的实例详解

    java动态添加外部jar包到classpath的实例详解 前言: 在项目开发过程中我们有时候需要动态的添加外部jar包,但是具体的业务需求还没有遇到过,因为如果动态添加外部jar包后,我们就需要修改业务代码,而修改代码就需要重新启动服务,那样好像就没有必要动态添加外部jar包了,怎么样才能不重新启动服务器就可以使用最新的代码我没有找到方法,如果各位知道的话给我点建议,回归主题,实现动态添加外部jar包到classpath的方法如下: String beanClassName = "com.dy

  • 使用Java构造和解析Json数据的两种方法(详解二)

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON数据不须要任何特殊的 API 或工具包. 在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面接着介绍用org.json构造和解析Json数据的方法

随机推荐