1.1 通用的DA0

1.1.1 通用的DAO的编写:泛型的反射.

Hibernate的概述:

Hibernate :是持久层的ORM的框架.
持久层:DAO层.Data Access Object.封装的是对数据源的单个操作.
ORM:Object Relational Mapping.对象关系映射.
将Java中对象与数据库中表建立一种映射关系.从而操作对象就能操作数据库.
传统方式:
创建表:MySql/Oracle—Relational
user:
创建类:Java—Object
User:
ORM的思想:
通过配置文件将对象与数据库中表建立映射:







Hibernate完成CRUD的操作:
使用Hibernate的Session对象中的方法:
保存数据:save(Object obj);
修改数据:update(Object obj);
删除数据:delete(Object obj);
* 查询一个记录:get(Class clazz,Serializable s);

使用Hibernate完成DAO的代码的编写:

步骤一:创建一个项目,引入Hibernate的jar包.
步骤二:创建包结构:
com.juwins.basedao.demo1
步骤三:编写DAO:
public class BookDao {

// 定义Session的对象.
private Session session;

/**
添加图书的方法
/
public void save(Book book){
session.save(book);
}

/**
修改图书的方法:
/
public void update(Book book){
session.update(book);
}

/**
删除图书的方法:
/
public void delete(Book book){
session.delete(book);
}

/**
查询一条记录:
/
public Book findById(Integer id){
return (Book) session.get(Book.class, id);
}
}
**
发现很多的DAO中都有CRUD的基本操作,那么每个DAO中的代码都是类似的.可以抽取一个通用的父类.让具体的子类继承通用的DAO的类.在子类中不需要编写任何的代码就可以完成CRUD的操作.**

使用构造方法的方式完成通用的DAO的编写:

代码实现:
public class BaseDao {

private Session session;
private Class clazz;

public BaseDao(Class clazz){
this.clazz = clazz;
}

/
通用的保存的方法
/
public void save(T t){
session.save(t);
}

/

通用的修改的方法
/
public void update(T t){
session.update(t);
}

/
通用的删除的方法:
/
public void delete(T t){
session.delete(t);
}

/

通用的查询的方法:
/
public T findById(Integer id){
return (T)session.get(clazz, id);
}
}

* 这种方式编写通用的DAO并不是特别的好!!!因为现在子类继承BaseDao 同时提供一个构造方法.能不能在子类中不提供构造方法?**

通过泛型的反射完成通用的DAO的编写:

泛型的基本术语:
以ArrayList为例:
<> :念为 typeof
E :称为类型参数变量
ArrayList中Integer :称为实际类型参数.
ArrayList :整个称为 参数化类型

通过反射获得参数化类型(有具体参数的类型)从而得到实际类型参数(具体的参数类)
**
查询相应的API:
*
Class:
通用的DAO和动态代理 - 图1
获得带有泛型的接口.
通用的DAO和动态代理 - 图2
获得带有泛型的父类.
*
ParameterizedType
通用的DAO和动态代理 - 图3
* 获得实际类型参数

编码实现通用DAO的编写(
核心代码**):
public BaseDao(){
// 获得到子类的Class的对象.
Class c = this.getClass();
// System.out.println(c);
// 获得带有泛型的父类:BaseDao
Type type = c.getGenericSuperclass();
// System.out.println(type);
ParameterizedType pType = (ParameterizedType) type;
// 通过参数化类型获得到具体实际类型参数Book
Type[] types = pType.getActualTypeArguments();
this.clazz = (Class) types[0];
}

1.2 动态代理:

1.1.1 增强一个类的某个方法的时候:

继承的方式:

  • public class Man{
    public void run(){
    System.out.println(“跑…”);
    }
    }

    public class SuperMan extends Man{
    public void run(){
    System.out.println(“跑的飞快…”);
    }
    }

    **
    使用的环境:必须能够控制这个类的构造.**

    装饰者模式:

  • public interface Bird{
    public void fly();
    }

    public class BigBird implements Bird{
    public void fly(){
    System.out.println(“飞…”);
    }
    }

    public class BigBirdWrapper implements Bird{
    private Bird bird;
    public BigBirdWrapper(Bird bird){
    this.bird = bird;
    }

    public void fly(){
    // 增强代码.
    bird.fly();
    }
    }

    使用:
    Bird bird = new BigBirdWrapper(new BigBird());
    bird.fly();

    **
    使用环境:
    *
    1.被增强的类和增强类需要实现相同的接口.
    *
    2.在增强的类中获得被增强的类的引用.**

    动态代理:(*最为灵活的一种增强的方式)

    * 使用环境:
    *
    类必须实现接口.JDK动态代理可以对实现了接口的类产生代理.

    *
    使用动态代理:
    *
    了解动态代理API:
    *
    Proxy:代理.
    通用的DAO和动态代理 - 图4
    *
    newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h);
    *
    ClassLoader :类的加载器.
    *
    Class[] :类实现的所有的接口的Class的对象.
    *
    InvocationHandler :真正的处理对象.**

    1.1.2 动态代理完成入门案例:

    使用动态代理完成一个增强的操作:

    public class WaitressProxy implements InvocationHandler{

    private Waiter waiter;

    public WaitressProxy(Waiter waiter) {
    this.waiter = waiter;
    }

    public Waiter createWaiterProxy() {
    Waiter waiterProxy = (Waiter) Proxy.newProxyInstance(waiter.getClass()
    .getClassLoader(), waiter.getClass().getInterfaces(), this);
    return waiterProxy;
    }

    @Override
    /*
    proxy:代理对象.
    method:指代的方法本身(正在执行的方法)
    args :方法的参数列表
    */
    public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {
    // System.out.println(“=============”);
    System.out.println(“微笑====”);
    waiter.serve();
    return null;
    }
    }

    深入理解动态代理:

    public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {
    // System.out.println(“=============”);
    // System.out.println(“微笑====”);
    // waiter.serve();
    // Object obj = method.invoke(waiter, args);
    if(“sayHello”.equals(method.getName())){
    System.out.println(“微笑====”);
    Object obj = method.invoke(waiter, args);
    return obj;
    }else{
    return method.invoke(waiter, args);
    }

    }

    通用的字符集编码过滤器:(使用JDK动态代理完成)

    @WebFilter(urlPatterns=”/*”)
    public class GenericEncodingFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
    FilterChain chain) throws IOException, ServletException {
    // 强制转换成HttpServletRequest:
    final HttpServletRequest req = (HttpServletRequest) request;
    // 使用JDK的动态代理对req对象生成代理:
    HttpServletRequest myHttpReq = (HttpServletRequest) Proxy
    .newProxyInstance(req.getClass().getClassLoader(), req
    .getClass().getInterfaces(), new InvocationHandler() {

    @Override
    public Object invoke(Object proxy, Method method,
    Object[] args) throws Throwable {
    // 判断执行的方法是否是getParameter:
    if (“getParameter”.equals(method.getName())) {
    // 判断请求的方式:
    // 获得请求的方式:
    String type = req.getMethod();
    if (“get”.equalsIgnoreCase(type)) {
    String value = (String) method
    .invoke(req, args);
    value = new String(
    value.getBytes(“ISO-8859-1”), “UTF-8”);
    return value;
    } else if (“post”.equalsIgnoreCase(type)) {
    req.setCharacterEncoding(“UTF-8”);
    }
    }
    return method.invoke(req, args);
    }
    });
    // 放行过滤器:
    chain.doFilter(myHttpReq, response);
    }

    @Override
    public void destroy() {

    }

    }