Dao模型设计(基于Dao与Hebernate框架)

时间:2023-01-02 21:59:10

以前没有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与Hebernate框架)

客户Dao

Dao模型设计(基于Dao与Hebernate框架)

③Dao实现

学生Dao实现

Dao模型设计(基于Dao与Hebernate框架)

客户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);
}
}

  结果:

Dao模型设计(基于Dao与Hebernate框架)customer表

Dao模型设计(基于Dao与Hebernate框架)student表

这就是Dao设计模型

Dao模型设计(基于Dao与Hebernate框架)

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

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": [], &quot ...

  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&period;Security的实现分析

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

随机推荐

  1. 关于Java static 的学习心得

    static,大家都很熟悉.但是要说真的懂,那就很少了.(当然我也不是很懂,但不妨碍学习吗.) 首先,我认为static修饰的成员就是属于类本身的成员.如果你加了一个static修饰符,好吧,那就相当 ...

  2. mybatis单个插入和批量插入的简单比较

    在J2EE项目中,mybatis作为主流持久层框架,许多知识值得我们去钻研学习,今天,记录一下数据插入性能(单个插入和批量插入). 一,测试对象 public class Test { private ...

  3. 如何用分析函数找出EMP表中每个部门工资最高的员工

    EMP表是Oracle测试账户SCOTT中的一张雇员表,首先,我们来看看emp表的数据 SQL> select * from emp; EMPNO ENAME JOB MGR HIREDATE ...

  4. Android -- 自定义View(一)

    1,引言:刚从国庆长假的放荡中醒过来,已经有将近十天没碰电脑了,上午写写代码感觉手还是挺生的,想把自定义view好好的系统的学学,在网上看了看别人出的教程 ,stay4it的自定义view感觉还是挺好 ...

  5. 在mybatis执行SQL语句之前进行拦击处理

    转载自:http://blog.csdn.net/hfmbook/article/details/41985853 比较适用于在分页时候进行拦截.对分页的SQL语句通过封装处理,处理成不同的分页sql ...

  6. io系统

    一.浅谈io系统 io系统的结构化思想是:输入-转换流-装饰器-输出. 对于字节流来说,常见的结构类为: package com.handchina.yunmart.middleware.servic ...

  7. Python元编程

    简单定义"元编程是一种编写计算机程序的技术,这些程序可以将自己看做数据,因此你可以在运行时对它进行内审.生成和/或修改",本博参考<<Python高级编程>&gt ...

  8. appium 3-31603调试分析方法

    1.Appium Log 清晰记录了所有的请求和结果 @Test public void testDebug() throws InterruptedException,IOException{ Mo ...

  9. rails 国际化、validate校验、flash提示

      1.Rails的国际化 根据特定的locale信息,提取相应的内容 通过config/environment.rb,指定应用的转换文件 config.i18n.load_path +=Dir[Ra ...

  10. 支撑大规模公有云的Kubernetes改进与优化 &lpar;2&rpar;

    接下来我们按照kubernetes创建容器的详细过程,以及可能存在的问题. 一.API Server的认证,鉴权,Quota 当客户需要创建一个pod的时候,需要先请求API Server. Kube ...