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
E :称为类型参数变量
ArrayList
ArrayList
通过反射获得参数化类型(有具体参数的类型)从而得到实际类型参数(具体的参数类)
**
* Class:
获得带有泛型的接口.
获得带有泛型的父类.
* ParameterizedType
* 获得实际类型参数
编码实现通用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:代理.
* 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() {
}
}