Dao模型设计(基于Dao与Hebernate框架)
以前没有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框架)的更多相关文章
- 基于maven的ssm框架整合
基于maven的ssm框架整合 第一步:通过maven建立一个web项目. 第二步:pom文件导入jar包 (1 ...
- 基于springboot的SSM框架实现返回easyui-tree所需要数据
1.easyui-tree easui-tree目所需要的数据结构类型如下: [ { "children": [ { "children": [], " ...
- MyBatis开发Dao的原始Dao开发和Mapper动态代理开发
目录 咳咳...初学者看文字(Mapper接口开发四个规范)属实有点费劲,博主我就废了点劲做了如下图,方便理解: 原始Dao开发方式 1. 编写映射文件 3.编写Dao实现类 4.编写Dao测试 Ma ...
- 基于LoadRunner构建接口测试框架
基于LoadRunner构建接口测试框架 http://www.docin.com/p-775544153.html
- 8个强大的基于Bootstrap的CSS框架
做过前端开发的小伙伴们应该对Bootstrap不会陌生,它是由Twitter推出的开源CSS框架,其中包含了很多Web前端开发的工具包和应用组件.当然,和jQuery一样,Bootstrap同时也是一 ...
- 基于cocos2d-x的游戏框架设计——李成
视频:http://v.youku.com/v_show/id_XMzc5ODUyMTI4.html?f=17330006 网易科技讯 3月31日,第四届CocoaChina开发者大会暨Cocos2d ...
- 基于MEF的插件框架之总体设计
基于MEF的插件框架之总体设计 1.MEF框架简介 MEF的全称是Managed Extensibility Framework(MEF),其是.net4.0的组成部分,在3.5上也可以使用.熟悉ja ...
- 【百度地图开发之二】基于Fragment的地图框架的使用
写在前面的话: [百度地图开发之二]基于Fragment的地图框架的使用(博客地址:http://blog.csdn.net/developer_jiangqq),转载请注明. Author:hmji ...
- 基于NetMQ的TLS框架NetMQ.Security的实现分析
基于NetMQ的TLS框架NetMQ.Security的实现分析 前言 介绍 交互过程 支持的协议 TLS协议 支持的算法 实现 握手 第一次握手 Client Hello 第二次握手 Server ...
随机推荐
- HW4.38
import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...
- clock_t与time_t的区别及联系
clock_t <ctime> Clock type Type capable of representing clock tick counts and support arithmet ...
- Camtasia Studio8使用教程
tip:善于使用ctrl+f搜索目录查看内容 目录 软件的下载与安装 软件的汉化与界面介绍 录制前准备与试机录制 录像机的设置 屏幕画 导入与编辑视频(包括图片,音乐,媒体) 时间线轨道时间轴 标记的 ...
- POJ 1657 Distance on Chessboard 简单的计算问题
Distance on Chessboard Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 23096 Accepted ...
- 算法 - 求和为n的连续正整数序列(C++)
//************************************************************************************************** ...
- cocos2d-x 3.0 Armature jsb 初体验
有段时间没有写游戏代码了,这回来主要任务是要用jsb构建一个aprg动作游戏,看到3.0官方已经绑定好了armature的js函数,先来体验一把 3.0新建项目比2.2方便了很多,在终端运行tools ...
- native为本地方法
在java中,native方法是指本地方法,当在方法中调用一些不是由java语言写的代码或者在方法中用java语言直接操纵计算机硬件时要声明为native方法. native方法的执行依赖于JVM的设 ...
- vim中的一些高级命令的使用
现在一般在windows下面对txt文档操作的时候,我一般使用gvim软件来操作,虽然没有unix/linu下面的正宗,并且很多命令没有,但是还是有很多方便之处的 下面是重温vim命令时,我我自己以前 ...
- Default route and zero route
A default route of a computer that is participating in computer networking is the packet forwarding ...
- Java基础知识强化之IO流笔记57:数据输入输出流(操作基本数据类型)
1. 数据输入输出流(操作基本数据类型) (1)数据输入流:DataInputStream DataInputStream(InputStream in) (2)数据输出流:DataOutputStr ...