以前没有Dao设计模型之前,一般都是这样的流程:

①先设计实体对象

学生对象:

package com.itheima.domain;

import java.io.Serializable;
import java.util.Date; public class Student implements Serializable {
private Integer id;//可以为null
private String name;
private Date birthday;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", birthday="
+ birthday + "]";
}
}

客户对象:

package com.itheima.domain;

import java.io.Serializable;

public class Customer implements Serializable {
private Integer id;
private String name;
private String gender;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", gender=" + gender
+ "]";
}
}

②设计Dao层

学生Dao

客户Dao

③Dao实现

学生Dao实现

客户Dao实现类似

可以发现,这样Dao多起来后,有很多的重复代码,主要集中在增删改查4个方法上面.


改进

一.在Dao包中,添加一个Dao接口

package com.itheima.dao;

import java.io.Serializable;

public interface Dao<T> {
void add(T t);
void update(T t);
/**
* 根据主键查询一个对象
* @param id
* @return
*/
T findOne(Serializable id);
/**
* 根据主键删除一个对象
* @param id
*/
void del(Serializable id);
}

二.在DaoImpl包下新建一个简单的BaseDao类(这里是重点),实现Dao接口

package com.itheima.dao.impl;

import java.io.Serializable;

import org.hibernate.Session;
import org.hibernate.Transaction; import com.itheima.dao.Dao;
import com.itheima.util.SessionFactoryUtil; public abstract class BaseDao<T> implements Dao<T> { private Class clazz;//记住外面传递过来的实体类型
public BaseDao(Class clazz){
this.clazz = clazz;
} public void add(T t) {
Session session = null;
try{
session = SessionFactoryUtil.getSession();
Transaction tx = session.beginTransaction();
session.save(t);
tx.commit();
}catch(Exception e){
throw new RuntimeException(e);
}finally{
session.close();
}
}
public T findOne(Serializable id) {
Session session = null;
try{
session = SessionFactoryUtil.getSession();
return (T)session.get(clazz, id);
}catch(Exception e){
throw new RuntimeException(e);
}finally{
session.close();
}
}
public void update(T t) {
Session session = null;
try{
session = SessionFactoryUtil.getSession();
Transaction tx = session.beginTransaction();
session.update(t);
tx.commit();
}catch(Exception e){
throw new RuntimeException(e);
}finally{
session.close();
}
} public void del(Serializable id) {
Session session = null;
try{
session = SessionFactoryUtil.getSession();
Transaction tx = session.beginTransaction();
T bean = (T)session.get(clazz, id);
session.delete(bean);
tx.commit();
}catch(Exception e){
throw new RuntimeException(e);
}finally{
session.close();
}
}
}

三.修改具体的实现类

  修改客户dao实现类

package com.itheima.dao.impl;

import java.util.List;

import com.itheima.dao.CustomerDao;
import com.itheima.domain.Customer; public class CustomerDaoImpl extends BaseDao<Customer> implements CustomerDao {
    
public CustomerDaoImpl(Class clazz) {
super(Customer.class);
} public List<Customer> findPageCustomer(int startIndex, int size) {
return null;
}
}

  修改学生dao实现类

package com.itheima.dao.impl;

import java.util.List;

import com.itheima.dao.StudentDao;
import com.itheima.domain.Student; public class StudentDaoImpl extends BaseDao<Student> implements StudentDao {
    //继承BaseDao,没有构造方法,需要构造方法,告诉父类,查的是那个类,上面的customer一样
public StudentDaoImpl(Class clazz) {
super(Student.class);
} public List<Student> findAll() {
return null;
}
}

四.service测试  

Student.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.itheima.domain">
<class name="Student" table="STUDENTS">
<id name="id" column="ID">
<!-- 根据数据库的能力管理主键 -->
<generator class="native"></generator>
</id>
<property name="name" column="NAME"></property>
<property name="birthday" column="BIRTHDAY"></property>
</class>
</hibernate-mapping>

  

Cusstomer.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.itheima.domain">
<class name="Customer" table="CUSTOMERS">
<id name="id" column="ID">
<!-- 根据数据库的能力管理主键 -->
<generator class="native"></generator>
</id>
<property name="name" column="NAME"></property>
<property name="gender" column="GENDER"></property>
</class>
</hibernate-mapping>

把配置文件交给hibernate管理

hibernate文件hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 配置Hibernate:属性配置参考 Hibernate发型包\project\etc\hibernate.properties -->
<!-- JDBC的基本链接 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.username">root</property>
<property name="connection.password">sorry</property>
<property name="connection.url">jdbc:mysql://localhost:3306/day22</property>
<!-- 配置数据库方言 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 根据映射产生表结构的类型:
create-drop:木有表结构创建,下次启动时删除重新创建。适合学习阶段
create:只做创建
update:探测表结构够的变化,对于数据库没有的,进行更新操作。适合学习阶段
validate:对比与数据库的结构
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 显示sql语句及格式:开发调试阶段非常有用 -->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>           <--最主要的就是这个-->
<!-- 告知映射文件 -->
<mapping resource="com/itheima/domain/Student.hbm.xml"/>
<mapping resource="com/itheima/domain/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>

 Dao测试

package com.itheima.test;

import java.util.Date;

import com.itheima.dao.CustomerDao;
import com.itheima.dao.StudentDao;
import com.itheima.dao.impl.CustomerDaoImpl;
import com.itheima.dao.impl.StudentDaoImpl;
import com.itheima.domain.Customer;
import com.itheima.domain.Student; public class DaoTest {
public static void main(String[] args) {
CustomerDao cDao = new CustomerDaoImpl(Customer.class);
StudentDao sDao = new StudentDaoImpl(Student.class);
Customer c = new Customer();
c.setName("刘亚雄");
c.setGender("待定");
cDao.add(c); Student s = new Student();
s.setName("吕云雪");
s.setBirthday(new Date());
sDao.add(s);
}
}

  结果:

customer表

student表

这就是Dao设计模型

虚线是实现接口,实线是继承类

BaseDao上有个abstract,注意:

为什么一个类里面没有抽象方法,还要定义声明为抽象类?

原因很简单:就是不让直接使用,干嘛不让?

BaseDao不让直接使用,是用来继承使用的.其实HTTPServlet就是典型,HTTPServlet是抽象类,里面有一个非抽象的方法doXXX(忘记叫什么名了)

继承后,满意的方法直接使用,不满意的方法直接覆盖掉就好了.

以上写法还不够优雅!下面来修改:

 一.修改StudentDaoImpl实现类,其实就是去掉构造方法

package com.itheima.dao.impl;

import java.util.List;

import com.itheima.dao.StudentDao;
import com.itheima.domain.Student; public class StudentDaoImpl extends BaseDao<Student> implements StudentDao { // public StudentDaoImpl(Class clazz) {
// super(Student.class);
// } public List<Student> findAll() {
return null;
}
}

  

 二.修改CustomerDaoImpl实现类,其实就是去掉构造方法

package com.itheima.dao.impl;

import java.util.List;

import com.itheima.dao.CustomerDao;
import com.itheima.domain.Customer; public class CustomerDaoImpl extends BaseDao<Customer> implements CustomerDao { // public CustomerDaoImpl() {
// super();
// } public List<Customer> findPageCustomer(int startIndex, int size) {
return null;
}
}

  三.修改BaseDao类

package com.itheima.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import org.hibernate.Session;
import org.hibernate.Transaction; import com.itheima.dao.Dao;
import com.itheima.util.SessionFactoryUtil; public abstract class BaseDao<T> implements Dao<T> { private Class clazz;//实体类型
public BaseDao(){
//给clazz赋值:需要知道操作的是哪个实体类,从而知道操作那张表
Type type = this.getClass().getGenericSuperclass();//得到当前实例的带有泛型类型的父类
ParameterizedType ptype = (ParameterizedType)type;//因为父类型带有泛型信息,就可以转为ParameterizedType(参数化的泛型类型)
clazz = (Class)ptype.getActualTypeArguments()[0];// Customer|Student.class
} public void add(T t) {
Session session = null;
try{
session = SessionFactoryUtil.getSession();
Transaction tx = session.beginTransaction();
session.save(t);
tx.commit();
}catch(Exception e){
throw new RuntimeException(e);
}finally{
session.close();
}
}
public T findOne(Serializable id) {
Session session = null;
try{
session = SessionFactoryUtil.getSession();
return (T)session.get(clazz, id);
}catch(Exception e){
throw new RuntimeException(e);
}finally{
session.close();
}
}
public void update(T t) {
Session session = null;
try{
session = SessionFactoryUtil.getSession();
Transaction tx = session.beginTransaction();
session.update(t);
tx.commit();
}catch(Exception e){
throw new RuntimeException(e);
}finally{
session.close();
}
} public void del(Serializable id) {
Session session = null;
try{
session = SessionFactoryUtil.getSession();
Transaction tx = session.beginTransaction();
T bean = (T)session.get(clazz, id);
session.delete(bean);
tx.commit();
}catch(Exception e){
throw new RuntimeException(e);
}finally{
session.close();
}
} }

  说明:

    this代表当前对象,this有句话可以这么理解(对象永远都是这个对象,但是指向有可能向上转型)

其实上面主要就是添加以下几句代码:

Type type = this.getClass().getGenericSuperclass();//得到当前实例的带有泛型类型的父类----->CustomerDaoImpl的父类BaseDao<Customer>就是带有泛型类型的类

ParameterizedType ptype = (ParameterizedType)type;//因为父类型带有泛型信息,就可以转为ParameterizedType(参数化的泛型类型)
clazz = (Class)ptype.getActualTypeArguments()[0];// Customer|Student.class

以上几句其实就是泛型的反射应用

修改之后,优雅多了

Dao模型设计(基于Dao与Hebernate框架)的更多相关文章

  1. 基于maven的ssm框架整合

    基于maven的ssm框架整合 第一步:通过maven建立一个web项目.                第二步:pom文件导入jar包                              (1 ...

  2. 基于springboot的SSM框架实现返回easyui-tree所需要数据

    1.easyui-tree easui-tree目所需要的数据结构类型如下: [ { "children": [ { "children": [], " ...

  3. MyBatis开发Dao的原始Dao开发和Mapper动态代理开发

    目录 咳咳...初学者看文字(Mapper接口开发四个规范)属实有点费劲,博主我就废了点劲做了如下图,方便理解: 原始Dao开发方式 1. 编写映射文件 3.编写Dao实现类 4.编写Dao测试 Ma ...

  4. 基于LoadRunner构建接口测试框架

    基于LoadRunner构建接口测试框架 http://www.docin.com/p-775544153.html

  5. 8个强大的基于Bootstrap的CSS框架

    做过前端开发的小伙伴们应该对Bootstrap不会陌生,它是由Twitter推出的开源CSS框架,其中包含了很多Web前端开发的工具包和应用组件.当然,和jQuery一样,Bootstrap同时也是一 ...

  6. 基于cocos2d-x的游戏框架设计——李成

    视频:http://v.youku.com/v_show/id_XMzc5ODUyMTI4.html?f=17330006 网易科技讯 3月31日,第四届CocoaChina开发者大会暨Cocos2d ...

  7. 基于MEF的插件框架之总体设计

    基于MEF的插件框架之总体设计 1.MEF框架简介 MEF的全称是Managed Extensibility Framework(MEF),其是.net4.0的组成部分,在3.5上也可以使用.熟悉ja ...

  8. 【百度地图开发之二】基于Fragment的地图框架的使用

    写在前面的话: [百度地图开发之二]基于Fragment的地图框架的使用(博客地址:http://blog.csdn.net/developer_jiangqq),转载请注明. Author:hmji ...

  9. 基于NetMQ的TLS框架NetMQ.Security的实现分析

    基于NetMQ的TLS框架NetMQ.Security的实现分析 前言 介绍 交互过程 支持的协议 TLS协议 支持的算法 实现 握手 第一次握手 Client Hello 第二次握手 Server ...

随机推荐

  1. CSS書寫規範及CSS Hack

    基本原则: CSS样式可细分为3类:自定义样式.重新定义HTML样式.链接状态样式. 样式为设计师自定义的新 CSS 样式,影响被使用本样式的区域,用于完成网页中局部的样式设定. 样式名 “.”+“相 ...

  2. A题进行时--浙大PAT 1001-1010

    pat链接:http://pat.zju.edu.cn 1 #include<stdio.h> 2 int main(){ 3 int a,b; 4 int c; 5 while(scan ...

  3. linux bin文件制作

    一 Linux安装文件 Linux常见的安装为tar,zip,gz,rpm,deb,bin等.我们可以简单的分为三类, 第一:打包或压缩文件tar,zip,gz等,一般解压后即可,或者解压后运行sh文 ...

  4. 互联网挣钱info

    AdSense – Google 广告 http://www.freehao123.com/tag/mianfeiphpkongjian/ [免费资源部落;] ntpdate -u time-b.ti ...

  5. 记一次 Google 面试经历

    本文由码农网 – 小峰原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划! 这是我上周去面试的地方.很顺利,我觉得——至少我认为我已经尽我所能,并且无论发生什么事情对我都是有帮助的. 由于 ...

  6. 问题-关于sharemem程序访问WEB出现内存错误处理

    [delphi技术] 关于sharemem造成dll错误的处理办法问题现象:如果程序和dll之间用string作为参数传递时容易出现错误问题处理:需要在程序的uses中使用sharemem.这个sha ...

  7. GCC扩展 __attribute__ ((visibility("hidden")))

    试想这样的情景,程序调用某函数A,A函数存在于两个动态链接库liba.so,libb.so中,并且程序执行需要链接这两个库,此时程序调用的A函数到底是来自于a还是b呢? 这取决于链接时的顺序,比如先链 ...

  8. tensorflow 实现线性方程

    下面的直接是代码: #!usr/bin/env python#coding:utf-8"""这个代码的作用是 通过 tensorflow 来计算 y = 0.3x + 0 ...

  9. "用wow64exts调试64位任务管理器抓取的32位程序的dump"

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:"用wow64exts调试64位任务管理器抓取的32位程序的dump".

  10. Sigar.jar获取系统信息

    Sigar是Hyperic-hq产品的基础包,是Hyperic HQ主要的数据收集组件. 它用来从许多平台收集系统和处理信息,这些平台包括:Linux, Windows, Solaris, AIX, ...