JavaBean-DAO模式
一、信息系统的开发架构
客户层-------显示层-------业务层---------数据层---------数据库
1.客户层:客户层就是客户端,简单的来说就是浏览器。
2.显示层:JSP/Servlet,用于给浏览器显示。
3.业务层:对于数据层的原子操作进行整合。
4.数据层:对于数据库进行的原子操作,增加、删除等;
二、DAO(Data Access Object)介绍
DAO应用在数据层那块,用于访问数据库,对数据库进行操作的类。
三、DAO设计模式的结构
DAO设计模式一般分为几个类:
1.VO(Value Object):一个用于存放网页的一行数据即一条记录的类,比如网页要显示一个用户的信息,则这个类就是用户的类。主要用来做数据库的映射.
2.DatabaseConnection:用于打开和关闭数据库。用于向其他接口提供数据库游标conn.
3.DAO接口:用于声明对于数据库的操作。子类继承后向上转型,覆盖DAO接口的方法.数据操作只需要调用这个接口的方法就行.
4.DAOImpl:必须实现DAO接口,真实实现DAO接口的函数,但是不包括数据库的打开和关闭。
5.DAOProxy:也是实现DAO接口,但是只需要借助DAOImpl即可,但是包括数据库的打开和关闭。
6.DAOFactory:工厂类,含有getInstance()创建一个Proxy类。
四、DAO的好处
DAO的好处就是提供给用户的接口只有DAO的接口,所以如果用户想添加数据,只需要调用create函数即可,不需要数据库的操作。
五、DAO包命名
对于DAO,包的命名和类的命名一定要有层次。
六实例分析:
1.VO层,这个类似于Django的model,做的是将数据库和这个javabean映射起来,每个属性对应的是数据库的一个字段
- //采用DAO设计模式,这里是VO类,也就是Value Object类,用户映射数据库
- package org.vo;
- import java.sql.*;
- public class UserBean{
- //映射user表
- private int userId;
- private String username;
- private String password;
- private int age;
- private String sex;
- public UserBean(String name,String password,int age,String sex){
- this.setUsername(name);
- this.setPassword(password);
- this.setAge(age);
- this.setSex(sex);
- }
- public void setUserId(int userId) {
- this.userId = userId;
- }
- public void setUsername(String username) {
- this.username = username;
- }
- public void setPassword(String password) {
- this.password = password;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public void setSex(String sex) {
- this.sex = sex;
- }
- public int getUserId() {
- return (this.userId);
- }
- public String getUsername() {
- return (this.username);
- }
- public String getPassword() {
- return (this.password);
- }
- public int getAge() {
- return (this.age);
- }
- public String getSex() {
- return (this.sex);
- }
- }
2.DataBaseConnection层,数据库连接层,操作数据库的链接和关闭,主要用于返回数据库游标和关闭数据库资源
- //采用DAO模式,这里做数据库关闭和打开
- package org.dbc;
- import java.sql.*;
- public class DataBaseConnection{
- //游标
- private Connection conn = null;
- //驱动
- private static final String DRIVER = "com.mysql.jdbc.Driver";
- //用户
- private static final String USER = "root";
- //链接地址
- private static final String URL = "jdbc:mysql://localhost:3306/test";
- //密码
- private static final String PASS = "";
- //构造函数,用于初始化游标
- public DataBaseConnection() throws Exception{
- Class.forName(this.DRIVER);
- this.conn = DriverManager.getConnection(this.URL,this.USER,this.PASS);
- }
- //得到游标
- public Connection getConnection()throws Exception{
- return this.conn;
- }
- //关闭资源
- public void close()throws Exception{
- if(this.conn != null){
- this.conn.close();
- }
- }
- }
3.DAO接口层.声明的是javabean的操作接口(供业务逻辑调用的)
- //采用DAO模式,这里设置的是DAO接口,用于声明对数据库的操作,但是不实现
- package org.dao;
- import java.util.ArrayList;
- import org.vo.UserBean;
- //定义用户Bean的接口
- public interface UserBeanImpl{
- public boolean createUser(UserBean user)throws Exception;
- public ArrayList<UserBean> findAll()throws Exception;
- public UserBean findByName(String name)throws Exception;
- }
实际上在工厂模式调用的时候是直接调用这个接口的函数,但是直接这样调用是无效的,因为没有实现,所以做法是将一个实现了的接口子类的实例向上转型,然后将接口的方法给覆盖,然后调用.
4.实现DAO接口层
- //采用DAO模式,这里必须实现DAO接口,真实实现DAO接口的函数,但是不包括数据库的打开和关闭。
- package org.dao.impl;
- import org.dao.*;
- import org.vo.*;
- import java.sql.*;
- import java.util.*;
- public class UserBeanDAOImpl implements UserBeanImpl{
- //数据库操作的游标
- private Connection con;
- private PreparedStatement stat = null;
- //构造函数,传入游标(这个类不包含数据库的打开和关闭)
- public UserBeanDAOImpl(Connection conn){
- this.con = conn;
- }
- //覆写接口中的方法
- public boolean createUser(UserBean user)throws Exception{
- String sql = "INSERT INTO `user`(`username`, `password`, `age`, `sex`) VALUES (?,?,?,?)";
- this.stat = this.con.prepareStatement(sql);
- stat.setString(1,user.getUsername());
- stat.setString(2,user.getPassword());
- stat.setInt(3,user.getAge());
- stat.setString(4,user.getSex());
- int update = stat.executeUpdate();
- if(update>0){
- return true;
- }else{
- return false;
- }
- }
- public UserBean findByName(String name)throws Exception{
- UserBean u = null;
- return u;
- }
- public ArrayList<UserBean> findAll()throws Exception{
- ArrayList<UserBean> users = new ArrayList<UserBean>();
- return users;
- }
- }
这里通过构造函数传入游标,然后操作数据库,这里没有数据库的连接和释放等操作,这样将连接资源和操作分开,可以很方便的修改数据库配置.这里定义的是对数据库的原子操作.
5.Userbean的代理层,相当于在实现DAO接口层定义并实现了用户的操作,但是没对修改和认证权限进行认证,就像代理模式中,首先定义了一个上网方法,直接调用这个方法就能上网,但是还定义了一个供给用户使用的上网方法,在这个方法中先对用户进行验证,并且可以设定用户上网的时间等,然后通过了就调用之前的上网方法,而这里也是有异曲同工的效果.
- //这里是用户Bean的代理,也是实现DAO接口,但是只需要借助DAOImpl即可,但是包括数据库的打开和关闭。
- package org.dao.impl;
- import org.dao.*;
- import java.sql.*;
- import org.vo.*;
- import java.util.*;
- import org.dbc.*;
- public class UserBeanDAOProxy implements UserBeanImpl{
- private DataBaseConnection dbc = null;
- private UserBeanImpl dao = null;
- //构造函数,用于初始化私有变量
- public UserBeanDAOProxy()throws Exception{
- this.dbc = new DataBaseConnection();
- this.dao = new UserBeanDAOImpl(dbc.getConnection());
- }
- //覆写接口中的方法
- public boolean createUser(UserBean user)throws Exception{
- boolean flag = false;
- //如果用户不存在,就创建一个新的用户
- if(dao.findByName(user.getUsername()) == null){
- flag = this.dao.createUser(user);
- }
- //调用数据库层的close方法(在数据库层实际上是执行了游标的关闭)
- this.dbc.close();
- //返回标志
- return flag;
- }
- public UserBean findByName(String name)throws Exception{
- UserBean u = null;
- return u;
- }
- public ArrayList<UserBean> findAll()throws Exception{
- ArrayList<UserBean> users = new ArrayList<UserBean>();
- return users;
- }
- }
可以看到,这里实际上对实现DAO接口类的原子操作进行了整合,比如创建用户的话,那么首先判断用户是否存在等,而这个也是用来专门覆写接口的.这里对实现DAO接口层的原子操作做了一个整合,实现了让上层调用的业务逻辑.
6.DAOFactory类,是一个工厂类.工厂模式可以这样理解,主要是将业务进行分层,用户只需要通过factory调用相应的方法就行,而屏蔽了上面所有的细节.就好比我知道有个超市,我跟他说,我要苹果,超市就直接给了我苹果,给我梨子,他就能给我梨子,而我完全不用去关心内部的实现,工厂把相关联的类集合起来,在里面统一进行处理,这里我可以用Python举一个例子(之前学了工厂模式自己写的一个微信服务端):
首先,用户会给服务器发送各种各样的消息,文本消息,图片消息,还有一些事件比如关注等,这些东西都会由微信服务器发送xml信息过来我的后台是这样处理的:
- def responseMsg(request):
- rawStr = smart_str(request.body)
- //将xml消息转换为字典
- msg = paraseMsgXml(ET.fromstring(rawStr))
- //将消息传入消息工厂
- factory = MsgFactory(msg)
- //从工厂获取返回消息
- return factory.getReplyXml()
可以看到,前面两句就是对xml信息做了一个预处理,转换了格式,而完全不去关心消息的类型等等.
主要是第三句,将消息传递到消息处理工厂,得到了一个工厂实例,然后调用工厂的返回消息函数,将返回的消息回复给用户就行.那么代码是怎么做到区分不同的代码类型而且回复消息的呢,现在主要是工厂类的实现(我这里这个工厂的返回消息没有写成静态函数,其实写成静态的更好,大多数都写成静态了);
下面是工厂的实现:
- class MsgFactory(object):
- """消息工厂,用来返回作为各种消息的媒介,向用户返回各种消息"""
- #未指定类型的消息类型,用于接受构造函数返回的消息类
- __mymsg = None
- def __init__(self, dict={}):
- for case in switch(dict.get('MsgType')):
- if case('text'):
- self.__mymsg = TextMessage(dict)
- break
- if case('event'):
- self.__mymsg = Event(dict)
- break
- if case():
- self.__mymsg = UnsolvedMsgType(dict)
- break
- pass
- def getReplyXml(self):
- return self.__mymsg.returnXml()
可以看到,工厂内部有个无类型的变量,根据传递过来的消息,识别不同的消息类型,然后将这个变量实例化成不同的消息类(比如假如传递进来的是文本消息,那么就实例化文本消息类),然后返回消息是调用的工厂的getReplyXml()函数,看代码可以发现,这个其实调用的是具体消息类型的returnXml()函数,而在每种消息的实现中,都包含了回复策略之类的.
这样可以看到,其实工厂做了一个很好的管理,对上层来说屏蔽了底层的实现细节.下面开始看DAOFactory类.
- //采用DAO设计模式,含有一个UserBean接口的实例
- package org.dao.factory;
- import org.dao.*;
- import java.sql.*;
- import org.vo.*;
- import java.util.*;
- import org.dbc.*;
- import org.dao.impl.*;
- public class UserBeanFactory{
- public static UserBeanImpl getInstance(){
- UserBeanImpl instance = null;
- try{
- instance = new UserBeanDAOProxy();
- }catch(Exception e){
- e.printStackTrace();
- }
- return instance;
- }
- }
可以看到,这里实际上是定义了一个用户bean操作接口,然后通过传入用户bean操作代理,发生向上转型(强类型语言,比如java,要使用工厂模式的话,很重要的一点就是向上转型),方法被覆写,然后调用接口的方法就可以实现对应的操作.这个时候其实工厂做了的事情就是,给Servlet或者jsp调用的时候,他只需要调用工厂,然后调用一个创建用户的函数,那么就可以完成所需要的功能了,完全不用去关心数据库的链接等操作.同样的,要修改用户信息就调用工厂的修改用户信息的函数.这样看起来就好像根本上层开发人员根本不用懂数据库就可以开发了,做了很好的分层.
我们现在来分析下框架,这样做有很好的扩展性:
1.比如要对存储方法进行改变,如果是更改数据库的话只需要更改DataBaseConnection类中的配置即可,其他部分只关心得到的游标,不关心数据库的链接等问题.
2.现在该更改存储方式,比如改成用文件存储,那么用户操作接口是不用改变的,只需要重新写一个文件的存储方法继承用户bean操作接口并且实现.然后DAO代理的构造函数中传入新的存储方法即可
3.给上层开发人员带来的好处是,假如数据库迁移或者更改了存储方式,那么只需要对工厂下层的东西进行修改,而上层的业务逻辑完全没影响,因为他们调用的是下层的接口,而我底层配置改了的话接口还是没变.就好像tcp/ip的分层结构一样.
JavaBean-DAO模式的更多相关文章
- Jsp+Struts2+JavaBean+DAO开发模式(1)
DAO模式就实现了把数据库表的操作转化对Java类的操作,从而提高程序的可读性,并实现更改数据库的方便性.其架构图如下图. 一共分为五个组件(component) jsp提交页面(一下四其中的一个例子 ...
- javaweb学习总结(二十二)——基于Servlet+JSP+JavaBean开发模式的用户登录注册
一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+JavaBean模式(MVC)适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp ...
- 咸鱼入门到放弃11--Servlet+JSP+JavaBean开发模式
本篇搬运了大佬blog:https://www.cnblogs.com/xdp-gacl/p/3902537.html 一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servle ...
- 2、原生jdbc的dao模式
一.dao模式 (data access object)1.作用:持久层,专门操作数据的层次结构,不掺杂任何的业务和其他内容2.dao组成部分: a.数据库工厂类 b.数据实体类 javabean p ...
- JavaWeb学习 (二十一)————基于Servlet+JSP+JavaBean开发模式的用户登录注册
一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+JavaBean模式(MVC)适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp ...
- 基于Servlet+JSP+JavaBean开发模式的用户登录注册
http://www.cnblogs.com/xdp-gacl/p/3902537.html 一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+JavaBea ...
- javaweb(二十二)——基于Servlet+JSP+JavaBean开发模式的用户登录注册
一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+JavaBean模式(MVC)适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp ...
- 数据持久化以及DAO模式的简单使用
持久化:(是将程序中的数据在瞬时状态和持久状态间转换机制) 即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘).持久化的主要应用是将内存中的对象存储在关系型的数据库中,当然 ...
- 创建DAO模式的步骤
1.建立数据库epet 2.创建实体类,和相对应的数据库是对应的 3.创建Dao的基类接口类BaseDao 4.创建Dao的实现类BaseDaoImpl 5.创建具体表的Dao类 6.创建具体表的Da ...
- Servlet+JSP+JavaBean开发模式(MVC)介绍
好伤心...写登陆注册之前看见一篇很好的博文,没有收藏,然后找不到了. 前几天在知乎上看见一个问题,什么时候感觉最无力. 前两天一直想回答:尝试过google到的所有solve case,结果bug依 ...
随机推荐
- sencha怎么在control层调用按钮
暂时在这里总结了3种方法: config: { refs: { sendMaint: 'sendMaint', basicinfolist:'basicinfolist',refreshButton: ...
- 浅析-博客Ping服务
简介:PING服务是博客站点向博客目标网站.搜索引擎等发出的博客内容更新通知服务,然后博客目标网站.搜索引擎就会及时的索引.收录以及传播您的博客内容. PING原理 PING 服务是博客站点向博客目标 ...
- js写当鼠标悬浮及移开出现背景变化
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 行业集中度(Concentration Ratio)
行业集中度是决定市场结构最基本.最重要的因素,集中体现了市场的竞争和垄断程度,经常使用的集中度计量指标有:行业集中率(CRn指数).赫尔芬达尔—赫希曼指数(Herfindahl-HirschmanIn ...
- HTML静态网页 css样式表
CSS(Cascading Style Sheet,叠层样式表),作用是美化HTML网页. /*注释区域*/ 此为注释语法 一.样式表 (一)样式表的分类 1.内联样式表 和HTML联合显示,控 ...
- oracle initialization or shutdown in progress问题解决步骤
今天像往常一样打开电脑,启动plsql工具连接数据库,但是尽然连接不了,报了“oracle initialization or shutdown in progress”的提示信息,从操作系统 ...
- VC++6.0编译器标记的那些内存值
栈内存初始值 0xcccccccc 和-858993460. 二者是一样的, 一个是16进制, 另一个是10进制
- subprocess模块还提供了很多方便的方法来使得执行 shell 命令
现在你可以看到它正常地处理了转义. 注意 实际上你也可以在shell=False那里直接使用一个单独的字符串作为参数, 但是它必须是命令程序本身,这种做法和在一个列表中定义一个args没什么区别.而如 ...
- response的outputStream输出数据的问题
package cn.itcast.response; import java.io.IOException; import java.io.OutputStream; import java.io. ...
- 使用DB4o做一个.Net版的website(一)环境
一个机缘巧合之下,知道了DB4o这个数据库引擎,下载查看之后,被其方便.高效.以及便捷的管理方式锁折服. 故决定使用其做一个.NET版本的web站点,来巩固学到的知识,以及为后来人做一点点贡献. 首先 ...