队列、循环队列、反射的简单应用

今天主要是 队列 循环队列的学习。以及反射的应用,基于反射我们学习了如何只做一个通用的dao层。利用这个基本逻辑处理类我们可以实现对于数据库的插入和查看。当然剩下的方法还没有写,一会儿尝试写出来。不过最好先把刚刚那段代码抄一遍,然后背一下。做到融会贯通。然后其实可以再背一遍JDBCTemplate模板。

 

队列与循环队列:

这个 版本的反射的应用应该是 1.0版本的。比起前面那一张的那个 坑爹类,可强太多了。只有3个方法,但是 要展示的 反射的应用 却用的比较到位。

以下例程

队列:

package MyQueue;
public class MyQueue {//线性队列
    private Object[] obs = new Object[5];
    private int start=-1;//队头
    private int end=-1;//队尾
    /**
     * 添加元素,这个可以封装Object[] 当然也可把我们昨天写的链表结构拿过来,用作对象的存储
     * @param object
     */
    public void add(Object object){
        if(end>=obs.length){
            System.out.println("队列已满");
            return ;
        }
        obs[++end]=object;
    }
    /**
     * 得到队列的开始元素
     * @return
     */
    public Object getStart(){
        return obs[start+1];
    }
    /**
     * 得到队尾元素
     * @return
     */
    public Object getEnd(){
        return obs[end];
    }
    /**
     * 得到队列的长度
     * @return
     */
    public int getSize(){
        return end-start;
    }
    /**
     * 出队操作
     * @return
     */
    public Object putOut(){
        start++;
        Object object = obs[start];
        obs[start]=null;
        return object;
    }
    /**
     * 按照队列顺序查看队列中的元素
     */
    public void lookout(){
        for(int i=start+1;i<end+1;i++){
            System.out.println(obs[i]);
        }
    }
}

循环队列:

package MyQueue;
/**
 * 线性队列的存在总是很爽,但是很浪费空间,如果每次都能让队列满载,这样就很节省空间。
 * @author Administrator
 *浪费一个空间作为队满的标志
 *修改的时候,总是要记得%,不能直接++
 *对比的时候也要记得,%
 */
public class MyCircleQueue {
    Object[] obs = new Object[5];
    private int start=0;//队头
    private int end=0;//队尾
    /**
     * 为循环队列添加元素
     * @param object
     */
    public void add(Object object){
        if(isFull()){
            System.out.println("队列已满,请等待");
            return ;
        }
        end=(end+1)%obs.length;
        obs[end]=object;
    }
    /**
     * 判断队列是否已满,消耗一个空间用作队满的标志
     * @return
     */
    public boolean isFull(){
        return (end+1)%obs.length==start;
    }
    /**
     * 判断队列是否为空,如果start==(end)%obs.length 则队空
     * @return
     */
    public boolean isEmpty(){
        return (end)%obs.length==start;
    }
    /**
     * 出队操作,里面的队头不可能大于5,所以 上面关于 队满和队空的判断是合理的。并不用为strat也进行求余操作。
     * @return
     */
    public Object putout(){
        if(isEmpty()){
            System.out.println("队列中没有元素");
            return null;
        }
        Object object = obs[start];
        obs[start]=null;
        start=(start+1)%obs.length;
        return object;
    }
    /**
     * 得到循环队列中等待元素的数量
     * @return
     */
    public int getSize(){//如果数组短还好,可以直接访问得到数据个数,如果数组长了这样就不划算了,应该可以有算法
        //数组长度一定小于obs.length()
        int i=0;
        for(;i<obs.length;i++){
            if((end+i)%obs.length==start){
                break;
            }
        }
        return obs.length-i;
    }
    
    /**
     * 按照队列顺序额查看队列中的元素
     */
    public void lookout(){
        if(isEmpty()){
            System.out.println("队列为空");
            return ;
        }
        int i=0;
        while((start+i)%obs.length!=(end+1)%obs.length){
            System.out.println(obs[(start+i)%obs.length]);
            i++;
        }
    }
}

基于jdbc的template:

package com.letben.dao;

import java.lang.reflect.GenericArrayType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.letben.bean.user_tb;
import com.letben.util.JDBCTemplate;
/**
 * 当前BaseDao使用的前提是:类名和表名要保持一致,属性名和字段名要保持一致
 * 之后我们会写一个映射表,来解决数据库和表名命名需要符合规范的问题
 * @author Administrator
 * 抽空补齐 改 和删!
 */
public class BaseDao extends JDBCTemplate{
    /*
    static String className=null;
    static String tableName = null;
     * 并且发现老师的代码里面每一个地方都有className。所以不妨在程序开始的时候,写一个出来。
     * 表名也是
    BaseDao(){}
    BaseDao(Class c){
        className = c.getName();
        tableName = className.substring(className.lastIndexOf(".")+1);
    }
    static {
        //静态块儿并实现不了,需要一个构造函数
    }
     * 类型安全问题,是不是可以把List后面加一个泛型。
     * @param c
     * @return
     * 
     不不不,这些东西不能放在BaseDao,里面而要放在对应的 user_tb 的dao里面
     */
    public     void addObject(Object obj){
        Class c  = obj.getClass();
        String className = c.getName();
        String tableName = className.substring(className.lastIndexOf(".")+1);
        
        StringBuffer sql = new StringBuffer();
//        对于我们要反复修改的字符串语句来讲,我们最好使用StringBuffer 以节省空间。每new的一个String都会在内存中占用一个地址
        //组拼sql语句: insert into tableName (column1,column2...) values (value1,value2...);
        sql.append(" insert into ");
        sql.append(tableName);
        List<String> fields = new ArrayList<String>();
        List values = new ArrayList();
        Method[] methods = c.getMethods();
        for (Method method : methods) {
            //组拼时,需要对应的属性和值,那么新建了两个集合,通过整体添加的方式保持两者对应一致。
            String methodName = method.getName();
            if(methodName.startsWith("get")&&!methodName.equalsIgnoreCase("getclass")){
                String fieldName = methodName.substring(3);
                fields.add(fieldName);
                try {
                    values.add(method.invoke(obj, new Object[]{}));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
        
        sql.append(" ( ");//这个里面空格可以多不能少,所以尽量在每一个单词前后都加上空格,以免字符连在一起,sql无法解析
        for(int i=0;i<fields.size();i++){
            if(i==fields.size()-1){
                sql.append(fields.get(i));
            }else{
                sql.append(fields.get(i)+",");
            }
        }
        sql.append(" ) ");
        sql.append(" values ");
        sql.append(" ( ");
        for (int i = 0; i < values.size(); i++) {
            if(i==values.size()-1){
                sql.append("'"+values.get(i)+"'");
            }else{
                sql.append("'"+values.get(i)+"',");
            }
        }
        sql.append(" ) ");
        System.out.println(sql.toString());
        updateData(sql.toString());
    }
    
    
    
    
    
    public Object getObjectById(Class c,int id){
        String className = c.getName();//大类名
        String tableName = className.substring(className.lastIndexOf(".")+1);//表名,因为我们的前提是类名与表名一致
        String sql = "select * from "+tableName+" where id = "+id;
        ResultSet resultSet = query(sql);
        Object object  = null;
        try {
            object = c.newInstance();
            if(resultSet.next()){
                Method[] methods = c.getMethods();
                for (Method method : methods) {
                    String methodName = method.getName();
                    if(methodName.startsWith("set")){
                        String fieldName = methodName.substring(3);
                        Class[] cla=method.getParameterTypes();
                        if(cla[0]==String.class){//要求属性和字段都放是String和name的依然没有那么通用
                            method.invoke(object, new Object[]{resultSet.getString(fieldName)});
                        }else{
                            method.invoke(object, new Object[]{resultSet.getInt(fieldName)});
                        }
                        //method.invoke(object,new Object[]{resultSet.getString(fieldName)});
                        //取不出来,事实证明真的不通用,只能是对应的读取
                    }
                }
            }
        } catch (SQLException e) {//resultSet.next();
            e.printStackTrace();
        } catch (InstantiationException e) {//c.newInstance
            e.printStackTrace();
        } catch (IllegalAccessException e) {//c.newInstance
            e.printStackTrace();
        } catch (IllegalArgumentException e) {//invoke
            e.printStackTrace();
        } catch (InvocationTargetException e) {//invoke
            e.printStackTrace();
        }
        return object;
    }

    
    public List getAllObject(Class c){
        String className = c.getName();//得到类名
        System.out.println(className);
        String tableName = className.substring(className.lastIndexOf(".")+1);//得到表名或者 类的类名。
        System.out.println(tableName);
        String sql  = "select * from "+ tableName;
        ResultSet resultSet = query(sql);//这是JDBCTemplate里面的方法
//        System.out.println("****************");
        List list = new ArrayList();
        Object object = null;
        try{
            while(resultSet.next()){
                object=c.newInstance();
                Method[] methods = c.getMethods();//得到所有公开的方法。
                for (int i=0;i<methods.length;i++){
                    Method m=methods[i];//得到当前遍历到的这个方法
//                    System.out.println(m);
                    String methodName = m.getName();
//                    System.out.println(methodName);
                    if(methodName.startsWith("set")){//如果这个方法以set开头
                        String fieldName = methodName.substring(3);//得到对应属性名称
                        Class[] cla = m.getParameterTypes();//得到m方法的全部参数的参数类型。
                        if(cla[0]==String.class){
//                            m.invoke(object, new Object(){});
                            //方法召唤,反射得到的方法再进行调用,先传一个类作为实际使用这个方法的参数进去,后面是参数列表
                            m.invoke(object,resultSet.getString(fieldName));
                            //等效于:object.set<fieldName>(resultSet.getString(fieldName));
                            //即:对象把从结果集里面取出来的属性值赋给对应的属性。
                        }else{
                            m.invoke(object, resultSet.getInt(fieldName));
                            //我们常见的getters和setters的语句是:对象.setField(FieldValue);
                            //在反射里面这样写: 方法(对象,参数们)所以针对参数们:的标准写法是:new Object(){p1,p2...}
                        }
                    }
                }
                //这些轮完一圈儿,说明一个对象已经赋值完成。可以使用。故:
                list.add(object);
                object=null;
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        return list;
    }
    public static void main(String[] args) {
        BaseDao baseDao= new BaseDao();
        List<com.letben.bean.user_tb> list =baseDao.getAllObject(user_tb.class);//刚刚到这里有点儿蒙,忘记了类名.class
        for (user_tb user_tb : list) {
            System.out.println(user_tb);
        }
    }
}

 

那个 jdbc:刚写过了【笑哭】去那篇名叫jdbc的blog里面找一下吧

 

posted on 2016-02-08 15:57  木鸟飞  阅读(561)  评论(0编辑  收藏  举报

导航