以前没有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. SharePoint 命令使用集锦 (持续更新中...)

    首先要定位到 cd "Program Files\Common Files\Microsoft Shared\web server extensions\14\BIN" 下面   ...

  2. A Tour of Go Range

    The range form of the for loop iterates over a slice or map. package main import "fmt" , , ...

  3. fileupload控件上传、文件下载

    常遇到上传下载的功能,这里把我习惯的用法写下来: 上传: string fileName = "";fileName = this.fu_pic.FileName;if (stri ...

  4. 新发现:原来java正则表达式不写^和$也可以运行

    最近用了好多正则表达式,都是循规蹈矩的在前面加上^在后面加上$ 像这个样子"^[.]\\S+$",但实际上我在eclipse和editplus下都试了一下,不加前缀和后缀也是可以的 ...

  5. "判断this指针是不是null有什么意义呢"

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:"判断this指针是不是null有什么意义呢".

  6. javaSE-基础部分整理

    JavaSE基础部分整理 1.java介绍 1.Java分为三个部分: javaSE,javaEE,javaME; java重要性之一:跨平台(操作系统). 跨平台:一次编译,到处运行. Java虚拟 ...

  7. [HTTP2] HTTP1 probs and HTTP2 saves

    1. HOL (HEADS of LINE BLOCKING) Too many requests in the header tag. Broswer can allow 6 reuqest to ...

  8. Hash表

    Hash表 Hash表也称散列表,也有直接译作哈希表,Hash表是一种特殊的数据结构,它同数组.链表以及二叉排序树等相比较有很明显的区别,它能够快速定位到想要查找的记录,而不是与表中存在的记录的关键字 ...

  9. cglib源码分析(三):Class生成策略

    cglib中生成类的工作是由AbstractClassGenerator的create方法使用相应的生成策略完成,具体代码如下: private GeneratorStrategy strategy ...

  10. 从Kali 2.0 转至 Kali Rolling

    1. 修改官方软件库列表 编辑/etc/apt/sources.list,注释掉原有内容,然后添加下述内容. # kali rolling deb http://http.kali.org/kali ...