精华内容
下载资源
问答
  • 重新命名为UFT,虽然研究人确实很多,价格也很昂贵,但无可否认是它快速入门,(也许有人就会说录制的没什么用,但我认为这个得根据实际来,如果UI很稳定,对象基本都是标准,又没有太大时间成本去做话,...

            喜欢看代码的,请直接从第五章节开始,以下内容希望先看完,否则会有点晕

     

            QTP作为行业较早出现的自动化测试工具到现在最新的重新命名为UFT,虽然研究的人确实很多,价格也很昂贵,但无可否认的是它快速入门,(也许有人就会说录制的没什么用的,但我认为这个得根据实际来,如果UI很稳定,对象基本都是标准的,又没有太大时间成本去做的话,为什么不可以直接用,不一定是录制,直接写也可以),特别是强大的对象库识别功能,支持多BS/CS结构,这是其它大多数功能自动化测试工具无法比的。有些自动化工作量几乎要把程序都重写一次了,这样的我觉得是没有任何意义的,直接让开发去搞好了。成本可能更低

           所以,在这我们就直奔主题,好的自动化测试框架,首先应该 是可扩展性强,跨平台支持广,特别是对于现在需求变动越来越频繁的情况下,不用专门的自动化开发人员投入太大精力维护变得越来越重要。

          今天介绍的自动化框架主要有以下几个特点:

          1.依赖于QTP本身,所以支持BS/CS   ,强大的对象库识别功能

          2.支持描述性对象库来作为补充

          3.维护功能简单,仅需要扩展对应的操作事件就行

          4.框架结构清晰,不会出现每一个测试都有一个文件夹的情况

          5.颠覆了传统使用QTP的思路,特别是执行测试的时候会有较大调整

          6.重新定义了测试报告样式,以支持调整后测试执行方式

          7.增加EXCEL简要报告

          8.可自动发送测试结果到指定的邮箱

          9.关键字驱动,同时也可以平常过渡至数据驱动方式

         10.框架稳定后,普通测试人员、甚至产品 都可组织测试

         11.支持场景恢复

     

     主要思想:

        QTP正常脚本 的运行方式是

      window(XX).object("ss").XX

       broswer(xxx).page.set...

    如上。其实我们发现(参照其它框架思想)以上的结尾部分很多地方是重复用的,前面是对象,后面是事件。

      事件是有限个的,所以我们可以把它当作一个方法

      而window...page...这些其实就是对象,QTP强大 的功能在于它的对象库管理功能,这块终于可以派对上用场了,当然 有人说这样很验证管理,我一直想必不明白,有什么难管理的,不同模块分开管理能有什么问题,另外 本框架对此次部分进行了扩展,支持描述性编程,描述性文件当作对象库一样来处理,只不过传递参数的时候会有前缀标识,这样就读取描述对象库而不是共享对象库了。而且更大的一个好处是支持不同语言了,对象库完全 分享,即使业务有了变化 ,我们只需要调整EXCEL中的步骤及对象就行了,框架不要任何的修改,不涉及代码,普通的测试人员即可创建测试并运行,这样维护脚本就只需要很小的工作量,并且 支持多个平台,适用于公司 不同产品直接套用(当然 有些操作是需要对方法进行扩展的。)

     

      这里对象要转换成字符串,QTP已经做好了,可以 将对象库直接转换成XML文件,不过在做之前需要对转换后的XML文件进行深入理解,才能通过读取XML文件来拼接字符串。果然 这个功能是有目的的。

     

    同时这里优化了一部分是action部分,正常情况下action与aciton之前是平行的,每一个测试的入口是action文件,但这样会带来一个问题,会有很大一堆 东西,所以我们调整,所以有的测试只从一个aciton走一次,剩下的工作就交由核心框架处理,通过循环一个EXCEL文件中的关键字来处理。

     

    这样带一的一个问题是,测试报告,这里给了两种解决办法,一种是通过创建node改写已有的report.(有人说不太好用,但因为直接能插入截图,且是树形结构还是有它优势 的,所以这里保留)。另外 补充了一个EXCEL测试报告 ,可自己扩展,生产简要的测试报告。

     

    最后还有一个问题是场景 恢复,之前  一大堆 在实际 中可能设置的比较复杂,并且不一定是我们想必要的,这里统一处理成当出错时直接跳过当前循环进入下一个测试(有人说这样不好,不过一般大多数情况你再次重新执行也无效)。运行过程中将运行中的如循环参数,测试模块名称,测试名称记录在恢复文件中,然后一旦捕获到报错信息时,重新启动QTP,运行测试,这个时候直接从中断地方的下一循环开始即可。

     

    以上即为基本的思路。有更好的想法或意见请留言。

     

     

     

    以下是基本结构图,执行模式

        
         

     
     2.  基本的结构图

               

     

     
               

     
       

        

        

    展开全文
  • 这个我学过,每次遇到有点懵,今天补补课,记性不如烂博客~ 因为数组存储引用数据类型时有局限性,比如不能自动增长,为了方便封装了一些集合类供使用。 数组与集合区别 数组可以存储基本数据类型也可以...

    这个我没学过,每次遇到都有点懵,今天补补课,好记性不如烂博客~
    在这里插入图片描述
    因为数组存储引用数据类型时有局限性,比如不能自动增长,为了方便封装了一些集合类供使用。

    数组与集合的区别

    数组可以存储基本数据类型也可以存储引用类型,集合只可以存引用数据类型(对象),但是利用JDK1.5自动装箱的特性,基本数据类型会被自动转换成对象,所以不影响。
    数组长度是不可变的,集合的长度是可变的,可以随着元素的增加而增长(有的还是通过数组实现的,重新new一个1.5倍的数组,然后把原来数组中的数据存进去,原来的数组变成垃圾,1.5倍增长是一个折中的办法为了避免频繁地产生垃圾)。

    集合继承体系图

    在这里插入图片描述
    这些集合名字左边表示通过算法什么实现,右边表示派别(除了Vector),Vector是最早有的集合JDK1.0就有了,和ArrayList很像,Vector是线程安全的,ArrayList是线程不安全的。
    ArrayList是通过数组实现,LinekedList是通过链表实现。
    Collection就是所有集合的根接口。

    Collection的常用方法:add、clear、contains、equals、isEmpty、addAll

    常规操作: 父类引用指向子类对象,通过add添加元素,clear清空。
    clear()方法中从此集合中删除所有元素,只是把引用的指向删除了,集合中不再指向那些对象了,那些对象在堆中会变成垃圾,随后被垃圾回收机制回收。

     	Collection coll = new ArrayList();
        coll.add("a");
        coll.add("b");
        System.out.println(coll);
        coll.clear(); 
        System.out.println(coll);
    

    运行结果:
    [a, b]
    []

    contains方法判断是否包含指定元素,equals方法不是集合与元素之间的比较,而是集合与集合之间的比较。(List是有序的,相同元素顺序不同是不相等的)
    isEmpty()方法判断集合是否为空。

    Collection col1 = new ArrayList();
    col1.add("a");
    col1.add("b");
    System.out.println(col1.contains("a"));//是否包含该元素
    
    Collection col2 = new ArrayList();
    col2.add("b");
    col2.add("a");
    System.out.println(col2.equals(col1));//是否相等
    

    运行结果:
    true
    false

    remove方法用于移除指定元素,并且返回boolean表示移除成功与否。
    size方法获取集合中元素个数

    Collection col1 = new ArrayList();
    col1.add("a");
    col1.add("b");
    col1.remove("a");
    System.out.println(col1);
    System.out.println(col1.remove("c"));//是否移除元素成功
    

    运行结果:
    [b]
    false

    Collection的高级方法:addAll、containsAll、removeAll、retainAll

    Collection col1 = new ArrayList();
    col1.add("a");
    col1.add("b");
    Collection col2 = new ArrayList();
    col2.add("c");
    col2.add("d");
    
    col1.add(col2);
    System.out.println(col1);
    System.out.println(col1.size());
    

    运行结果:
    [a, b, [c, d]]
    3
    add方法在添加的是另一个集合的时候会把整个集合当做一个元素填入。
    如果想要把另一个集合所有元素加到这个集合中,需要用的是addAll方法:

    Collection col1 = new ArrayList();
    col1.add("a");
    col1.add("b");
    Collection col2 = new ArrayList();
    col2.add("c");
    col2.add("d");
    col1.addAll(col2);
    System.out.println(col1);
    System.out.println(col1.size());
    

    运行结果:
    [a, b, c, d]
    4

    containsAll方法用于比较调用的集合是否包含传入的集合:

    Collection col1 = new ArrayList();
    col1.add("a");
    col1.add("b");
    Collection col2 = new ArrayList();
    col2.add("c");
    col2.add("b");
    
    System.out.println(col1.containsAll(col2));
    

    运行结果:false

    removeAll删除的是两个集合的交集,一个元素都没有被删除,返回false。

    col1.add("a");
    col1.add("b");
    Collection col2 = new ArrayList();
    col2.add("c");
    col2.add("b");
    
    System.out.println(col1.removeAll(col2));
    System.out.println(col1);
    

    运行结果:
    true
    [a]

    retainAll用来取两个集合的交集。当调用的集合元素没有被改变,返回false。

    Collection col1 = new ArrayList();
    col1.add("a");
    col1.add("b");
    Collection col2 = new ArrayList();
    col2.add("c");
    col2.add("d");
    
    System.out.println(col1.retainAll(col2));
    System.out.println(col1);
    

    运行结果:true
    []

    iterator迭代器遍历集合的方法

    如果要遍历集合,可以转为数组再遍历,但是这样有点麻烦。可以封装好的函数iterator获取iterator迭代器来遍历集合。

    Collection col1 = new ArrayList();
    col1.add("a");
    col1.add("b");
    col1.add("c");
    col1.add("d");
    
    Iterator it =  col1.iterator();//获取iterator迭代器
    while (it.hasNext()){
        Object obj1 = it.next();//使用it.next()元素就会往后移一位,一次循环应该只用一次
        System.out.println(obj1);
    }
    

    运行结果:
    a
    b
    c
    d
    或者使用for循环(可以节省点内存,循环结束以后迭代器就会被释放):

    for (Iterator i = col1.iterator();i.hasNext();){
        Object obj1 = i.next();
        System.out.println(obj1);
    }
    

    void forEachRemaining(Consumer action),这是Java 8为Iterator新增的默认方法,该方法可使用Lambda表达式来遍历集合元素。

    List l = new ArrayList();
    l.add(1);
    l.add(2);
    ListIterator lI = l.listIterator();
    lI.forEachRemaining(str->{
        System.out.println(str);
    });
    

    Iterator迭代器的原理

    为什么iterator要设置成接口,不直接在iterator类实现呢?因为collection底下的子类(例如ArrayList类、LinkedList类)他们的数据存储结构和迭代方式是不一样的,所以要设置成接口让他们用内部类各自实现。
    那为什么不直接在这些子类里面直接定义hasNext()、next()这些方法呢,因为这样做的话整个体系中的类都要定义这些方法,过于臃肿,而且用接口能保证整个集合体系的遍历方式都是next和hasNext。

    Iterator接口里面有四个抽象方法(JDK1.8版本):
    在这里插入图片描述
    要调用这些方法肯定有子类对他们进行重写,事实上就是子类中的内部类重写了这些方法,比如说在上一小节的例子中,就是ArrayList类中的内部类Itr继承了Iterator接口,重写了这些方法。
    在这里插入图片描述
    调用iterator()获取迭代器时,表面上(编译时)调用的是collection中的方法,实际上(运行中)调用的是collection的子类ArrayList类中的方法(因为创建对象时父类引用了子类对象,Collection col1 = new ArrayList();),在ArrayList类中,iterator()方法会创建 继承自Iterator的内部类Itr的一个对象,并且返回这个对象。

    后续调用的hasNext()、next()等方法,运行时都是调用的ArrayList内部类Itr的方法,编译时调用的是Iterator这个接口中的方法。

    展开全文
  • //建立自己新建的类的对象my1 if(my1.exec()==QDialog::Accepted) //利用Accepted 信号判 断enterBtn 是否被按下 { w.show(); //如果被按下,显示主窗口 return a.exec(); //程序一直执行,直到主窗口 关闭 } else ...
  • PS:好久写博客了... ...4.使用AndBase框架实现对DAO调用实现数据库基本操作.. 1.DAO.. DAO..这个说法大家不陌生..数据库操作访问对象的抽象接口层..在DAO内部封装通用方法..然后再使用一个具体类...

    PS:好久没写博客了...

     

    学习内容:

    1.DAO介绍,通用DAO的简单调度过程..

    2.数据库映射关系...

    3.使用泛型+反射+注解封装通用DAO..

    4.使用AndBase框架实现对DAO的调用实现数据库基本操作..

     

    1.DAO..

      DAO..这个说法大家都不陌生..数据库操作访问对象的抽象接口层..在DAO内部封装好通用的方法..然后再使用一个具体类来进行实现..在我们想要调用这些方法对数据库进行相关操作时..只需要传递数据实体对象,就可以通过实体对象的传递从而实现对数据库进行操作..

      一个典型的DAO首先要有一个父类..这个父类是抽象出来的DAO接口层..内部封装了通用的抽象方法..一个简单的例子:

    package com.example.databaseactivity;
    
    import java.util.List;
    import java.util.Map;
    import android.database.sqlite.SQLiteOpenHelper;
    
    
    /*
     * 通用DAO父类..
     * */
    public interface DBDAO<T>{
    
        public SQLiteOpenHelper getDbHelper();
    
        /*
         * insert 函数..默认主键自增...
         * */
        public abstract long insert(T entity);
        
        /*
         * insert 函数..flag的值决定主键是否自增...
         * */
        public abstract long insert(T entity,boolean flag);
        
        /*
         * 插入实体类列表,默认主键自增..
         * */
        public abstract long insertList(List<T>entityList);
        
        /*
         * 插入实体类列表,flag决定主键是否自增..
         * */
        public abstract long insertList(List<T>entityList,boolean flag);
        
        /*
         * 根据id删除数据..
         * */
        public abstract long delete(int id);
        
        /* 
         * 根据id删除多个数据..
         * */
        public abstract long delete(Integer...ids);
        
        /*
         * 根据指定条件删除数据..
         * */
        public abstract long delete(String whereCaluse,String[] whereArgs);
        
        /*
         * 删除所有数据..
         * */
        public abstract long deleteAll();
        
        /*
         * 更新数据..
         * */
        public abstract long update(T entity);
        
        /*
         * 根据数据列表更新数据..
         * */
        public abstract long updateList(List<T> entityList);
        
        /*
         * 根据ID获取一行数据..
         * */
        public abstract T queryOne(int id);
        
        /*
         * 执行SQL查询语句..
         * class<T> 返回对象类型..
         * */
        public abstract List<T> rawQuery(String sql,String[] selectionArgs,Class<T> clazz);
        
        /*
         * 查询列表..
         * */
        public abstract List<T> queryList();
        
        /*
         * 根据多种限制条件进行查询.. 
         * */
        public abstract List<T> queryList(String[] columns,String selections,String[] selectionArgs,String groupBy,String having,String orderby,String limit);
    
        /*
         * 根据where条件进行查询..
         * */
        public abstract List<T> queryList(String selection,String selectionArgs);
        
        /*
         * 检查数据是否存在..
         * */
        public abstract boolean isExist(String sql,String[] selectionArgs);
        
        /*
         * 根据条件执行查询结果..将数据封装在map中..
         * */
        public List<Map<String, String>>queryMapList(String sql,String selectionArgs);
        
        /*
         * 返回查询结果条数..
         * */
        public int queryCount(String sql,String[] selectionArgs);
        
        /*
         * 封装执行sql代码..
         * */
        public void execSql(String sql, Object[] selectionArgs);
    }

      这就是一个DAO父类..内部提供了众多的抽象方法..那么有了抽象的方法..自然要有实现的子类..并且这个抽象的DAO接口层是不提供类型的..使用泛型的方式,那么为什么直接使用泛型呢?为什么不直接定义一个接口,后面还需要加上泛型..其实目的就是为了实现良好的扩展性..那么这个良好扩展的体现就是通过使用泛型来完成的...

      比如说我们把上面的类仅仅定义成一个抽象类..

    public interface DBDao{...封装了许多抽象函数...}

      那么只要我们想要进行数据库操作的时候,我们就需要implements这个接口...那么如果一个数据库中存在了多个表,那么就需要多个子类去implements这个抽象接口..那么这多个子类中的方法我们还是需要自己去人为去书写..这样就会导致每implements一次DBDao..我们都需要对内部的方法进行重写..这样显然是给我们自己去找麻烦..何必不再向上抽取呢?向上抽取目的就是为了减少这样的操作..避免一次次的重写..那么向上抽取就需要使用泛型了..

    public interface DBDao<T> {..抽闲函数..}

      我们同样使用一个泛型类进行实现..实现的过程需要使用到Java的注解和Java强大的反射机制..这里原理我们先不说..一会下面会有相关的解释..那么实现类就这样定义..

    public class AbDBDaoImpl<T> extends AbBasicDBDao implements AbDBDao<T>{..实现的过程..}

      这里实现的过程仍然以泛型的方式去实现...使用泛型的好处就是..无论我们传递的是什么类型..我们通过反射机制就能够获取传递来的实体类型从而去实例化对象..通过使用注解的方式我们就能够获取实体类型中的相关属性..有了实体对象以及实体对应的属性...那么就可以对数据表进行操作了...也就是说无论是一个表还是多个表的操作..我们只需要重写一次父类DAO的方法..在进行表操作的时候..我们只需要传递数据实体对象就可以了...或许还有点抽象..那么就来个实例..比如说上面的DBDAO<T>和DBDaoImpl<T>都已经写好了..那么我们就可以直接调用

    private UserInsideDao userDao = new UserInsideDao(MainActivity.this);//实例化对象..
    userDao.startReadableDatabase(false);//获取数据库..
    userDao.queryList(null,null,null,null,null,"create_time desc limit "+String.valueOf(pageSize)+" offset "+0,null);//直接可以执行查询函数..

      UserInsideDao其实就是一个服务层..使用它来传递我们想要初始化的数据表..以及获取数据库辅助类...这里的UserInsideDao继承了实现Dao抽象层的子层..那么UserInsideDao就可以去调用实现层的构造函数..将想初始化的表传递过去..那么这些表就会根据解析注解的方式对表进行相关的创建..

    public class UserInsideDao extends AbDBDaoImpl<LocalUser> {
        public UserInsideDao(Context context) {
            super(new DBInsideHelper(context),LocalUser.class);
        }
    }

      这里的DBInsideHelper才是真正对数据库进行操作的类...DBInsideHelper继承了AbDBHelper..获取数据库辅助类的同时..同时把LocalUser实体传递给AbDBDaoImpl..这就表示当前我需要对LocalUser表进行相关操作了..以下是DBInsideHelper的实现...

    public class DBInsideHelper extends AbDBHelper {
        // 数据库名
        private static final String DBNAME = "andbasedemo.db";
        
        // 当前数据库的版本
        private static final int DBVERSION = 1;
        // 要初始化的表
        private static final Class<?>[] clazz = { User.class,LocalUser.class,Stock.class,ChatMsg.class};
    
        public DBInsideHelper(Context context) {
            super(context, DBNAME, null, DBVERSION, clazz);
        }
    
    }

      总之最后会去调用AbDBDaoImpl中的构造函数..从而完成对数据表的一些初始化操作...然后就可以在主类中直接去调用相关函数来完成对数据库的基本操作了...

    2.数据库映射关系..

      数据库映射关系..说起来有点抽象..实际理解起来还是非常的简答的...数据库映射关系无非三种..一对一,一对多,多对多..这三种映射关系..映射关系其实就是实体和实体之间的实在关系..什么是一对一,一对多,多对多..拿一个简单的例子来说...

      比如说我们有三个数据表:

    学生表(学号,姓名,性别,年龄)    不难看出学生ID是主键..
    课程表(课程号,课程名称)       这里课程ID是主键..
    成绩表(学号,课程号,成绩)      这里的主键由学生ID和课程ID共同构成..

      一对一:比如说我们想要查询学生表ID为1,课程号ID为1的成绩..那么这行成绩只能对应学生表和课程表的一行数据..这就是一对一..也就是说表与表之间的数据相互对应只能是一行..

      一对多:查询学号为1的学生的成绩..这样在成绩表中会对应多条数据..但成绩表中的多条数据在学生表中只会对应一条..这个关系数据一对多..

      多对多:查询所有学生的成绩..那么数据表中多条数据对应多行...

      数据库映射关系如果真的理解过来还是比较容易的..千万不要理解反了..就拿查询一个班级里学号为1的学生...这个映射关系是一对一的关系...千万不要理解成一对多的关系...不要以为经过了多个层次就表示是一对多..这样去理解反而理解错了..这个关系是实体与实体之间的一对一,一对多,多对多..而不是经过了几层...这里还是需要注意的...

    3.使用泛型+反射+注解书写通用DAO...

      其实通用DAO最难实现的部分是使用反射去解析注解..也就是AbDBDaoImpl中方法的书写..这部分还是比较费劲的...

      通用DAO就拿这个例子来说吧...方法就一个..我就不多列举了..玩过JavaEE的对这方面还是非常清楚的...Hibernate DAO和SpringJDBC DAO都是以这种方式来对数据库进行操作的..不过传递数据对象的时候..类需要进行序列化操作..由于自己对SSH并不是很了解..就不在这班门弄斧了...还是说如何去实现的...

    public interface AbDBDao<T> {
        
         //获取数据库辅助类..
         public SQLiteOpenHelper getDbHelper();
         //查询数据,,以列表的形式进行展示..
         public abstract List<T> queryList(String[] columns, String selection,String[] selectionArgs, String groupBy, String having,String orderBy, String limit);     
    }    

      实现过程就需要AbDBDaoImpl类去实现了...

    public class AbDBDaoImpl<T> extends AbBasicDBDao implements AbDBDao<T> {
        
        /** The tag. */
        private String TAG = "AbDBDaoImpl";
        
        /** The db helper. */
        private SQLiteOpenHelper dbHelper;
        
        /**锁对象*/
        private final ReentrantLock lock = new ReentrantLock();
        
        /** The table name. */
        private String tableName;
        
        /** The id column. */
        private String idColumn;
        
        /** The clazz. */
        private Class<T> clazz;
        
        /** The all fields. */
        private List<Field> allFields;
        
        /** The Constant METHOD_INSERT. */
        private static final int METHOD_INSERT = 0;
        
        /** The Constant METHOD_UPDATE. */
        private static final int METHOD_UPDATE = 1;
    
        /** The Constant TYPE_NOT_INCREMENT. */
        private static final int TYPE_NOT_INCREMENT = 0;
        
        /** The Constant TYPE_INCREMENT. */
        private static final int TYPE_INCREMENT = 1;
        
        /**这个Dao的数据库对象*/
        private SQLiteDatabase db = null;
    
        /**
         * 用一个对象实体初始化这个数据库操作实现类.
         *
         * @param dbHelper 数据库操作实现类
         * @param clazz 映射对象实体
         */
        public AbDBDaoImpl(SQLiteOpenHelper dbHelper, Class<T> clazz) {
            this.dbHelper = dbHelper;
            if (clazz == null) {
                this.clazz = ((Class<T>) ((java.lang.reflect.ParameterizedType) super
                        .getClass().getGenericSuperclass())
                        .getActualTypeArguments()[0]);  //这里是获取传递过来的实体类型,比如说LocalUser.class...
            } else {
                this.clazz = clazz; //这里是直接获取...
            }
    
            if (this.clazz.isAnnotationPresent(Table.class)) { //如果存在声明的注解...这个注解数据表名属性..
                Table table = (Table) this.clazz.getAnnotation(Table.class);
                this.tableName = table.name(); //获取数据表名..
            }
    
            // 加载所有字段
            this.allFields = AbTableHelper.joinFields(this.clazz.getDeclaredFields(),
                    this.clazz.getSuperclass().getDeclaredFields());
    
            // 找到主键
            for (Field field : this.allFields) {
                if (field.isAnnotationPresent(Id.class)) {  //这里都是对注解的解析...这里的注解信息为ID...
                    Column column = (Column) field.getAnnotation(Column.class);
                    this.idColumn = column.name();
                    break;
                }
            }
    
            Log.d(TAG, "clazz:" + this.clazz + " tableName:" + this.tableName
                    + " idColumn:" + this.idColumn);
        }
    
        /**
         * 初始化这个数据库操作实现类.
         *
         * @param dbHelper 数据库操作实现类
         */
        public AbDBDaoImpl(SQLiteOpenHelper dbHelper) {
            this(dbHelper, null);
        }
    
        
        /**
         * 描述:TODO.
         *
         * @return the db helper
         * @see com.ab.db.orm.dao.AbDBDao#getDbHelper()
         */
        @Override
        public SQLiteOpenHelper getDbHelper() {
            return dbHelper;
        }
        @Override
        public List<T> queryList(String[] columns, String selection,
                String[] selectionArgs, String groupBy, String having,
                String orderBy, String limit) {
        
                List<T> list = new ArrayList<T>();
                Cursor cursor = null;
                try {
                    lock.lock();  //获取锁..避免多次操作导致问题发生...
                    Log.d(TAG, "[queryList] from"+this.tableName+" where "+selection+"("+selectionArgs+")"+" group by "+groupBy+" having "+having+" order by "+orderBy+" limit "+limit);
                    cursor = db.query(this.tableName, columns, selection,
                            selectionArgs, groupBy, having, orderBy, limit); //执行查询函数...
        
                    getListFromCursor(this.clazz,list, cursor);
                    
                    closeCursor(cursor);
                    
                    //获取关联域的操作类型和关系类型
                    String foreignKey = null;
                    String type = null;
                    String action = null;
                    //需要判断是否有关联表
                    for (Field relationsField : allFields) {
                        if (!relationsField.isAnnotationPresent(Relations.class)) {
                            continue;
                        }
                        
                        Relations relations = (Relations) relationsField.getAnnotation(Relations.class);
                        //获取外键列名
                        foreignKey = relations.foreignKey();
                        //关联类型
                        type = relations.type();
                        //操作类型
                        action = relations.action();
                        //设置可访问
                        relationsField.setAccessible(true);
                        
                        if(!(action.indexOf(ActionType.query)!=-1)){
                            return list;
                        }
                        
                        //得到关联表的表名查询
                        for(T entity:list){
                                
                                if(RelationsType.one2one.equals(type)){
                                    //一对一关系
                                    //获取这个实体的表名
                                    String relationsTableName = "";
                                    if (relationsField.getType().isAnnotationPresent(Table.class)) {
                                        Table table = (Table) relationsField.getType().getAnnotation(Table.class);
                                        relationsTableName = table.name();
                                    }
                                    
                                    List<T> relationsList = new ArrayList<T>();
                                    Field[] relationsEntityFields = relationsField.getType().getDeclaredFields();
                                    for (Field relationsEntityField : relationsEntityFields) {  //这里涉及到对主表进行再次遍历..这里主要原因是受到了外键的影响...
                                        Column relationsEntityColumn = (Column) relationsEntityField.getAnnotation(Column.class);
                                        //获取外键的值作为关联表的查询条件
                                        if (relationsEntityColumn.name().equals(foreignKey)) {
                                            
                                            //主表的用于关联表的foreignKey值
                                            String value = "-1";
                                            for (Field entityField : allFields) {
                                                //设置可访问
                                                entityField.setAccessible(true);
                                                Column entityForeignKeyColumn = (Column) entityField.getAnnotation(Column.class);
                                                if(entityForeignKeyColumn==null){
                                                    continue;
                                                }
                                                if (entityForeignKeyColumn.name().equals(foreignKey)) {
                                                    value = String.valueOf(entityField.get(entity));
                                                    break;
                                                }
                                            }
                                            //查询数据设置给这个域
                                            cursor = db.query(relationsTableName, null, foreignKey+" = ?",new String[]{value}, null, null, null, null);
                                            getListFromCursor(relationsField.getType(),relationsList, cursor);
                                            if(relationsList.size()>0){
                                                //获取关联表的对象设置值
                                                relationsField.set(entity, relationsList.get(0));
                                            }
                                            
                                            break;
                                        }
                                    }
                                    
                                }else if(RelationsType.one2many.equals(type) || RelationsType.many2many.equals(type)){
                                    //一对多关系
                                    
                                    //得到泛型里的class类型对象
                                    Class listEntityClazz = null;
                                    Class<?> fieldClass = relationsField.getType();
                                    if(fieldClass.isAssignableFrom(List.class)){
                                         Type fc = relationsField.getGenericType(); 
                                         if(fc == null) continue;  
                                         if(fc instanceof ParameterizedType) {
                                             ParameterizedType pt = (ParameterizedType) fc;  
                                             listEntityClazz = (Class)pt.getActualTypeArguments()[0];
                                         }
                                         
                                    }
                                    
                                    if(listEntityClazz==null){
                                        Log.e(TAG, "对象模型需要设置List的泛型");
                                        return null;
                                    }
                                    
                                    //得到表名
                                    String relationsTableName = "";
                                    if (listEntityClazz.isAnnotationPresent(Table.class)) {
                                        Table table = (Table) listEntityClazz.getAnnotation(Table.class);
                                        relationsTableName = table.name();
                                    }
                                    
                                    List<T> relationsList = new ArrayList<T>();
                                    Field[] relationsEntityFields = listEntityClazz.getDeclaredFields();
                                    for (Field relationsEntityField : relationsEntityFields) {
                                        Column relationsEntityColumn = (Column) relationsEntityField.getAnnotation(Column.class);
                                        //获取外键的值作为关联表的查询条件
                                        if (relationsEntityColumn.name().equals(foreignKey)) {
                                            
                                            //主表的用于关联表的foreignKey值
                                            String value = "-1";
                                            for (Field entityField : allFields) {
                                                //设置可访问
                                                entityField.setAccessible(true);
                                                Column entityForeignKeyColumn = (Column) entityField.getAnnotation(Column.class);
                                                if (entityForeignKeyColumn.name().equals(foreignKey)) {
                                                    value = String.valueOf(entityField.get(entity));
                                                    break;
                                                }
                                            }
                                            //查询数据设置给这个域
                                            cursor = db.query(relationsTableName, null, foreignKey+" = ?",new String[]{value}, null, null, null, null);
                                            getListFromCursor(listEntityClazz,relationsList, cursor);
                                            if(relationsList.size()>0){
                                                //获取关联表的对象设置值
                                                relationsField.set(entity, relationsList);
                                            }
                                            
                                            break;
                                        }
                                    }
                                    
                                }
                        }
                    }
                    
                } catch (Exception e) {
                    Log.e(this.TAG, "[queryList] from DB Exception");
                    e.printStackTrace();
                } finally {
                    closeCursor(cursor);
                    lock.unlock();
                }
        
                return list;
        }
    }

      这就是实现的过程..主要是通过使用反射机制+解析注解的方式来实现的...这里涉及到了一个关联表的事情...就拿刚才的那三个表来说吧...我想要查询学生号为1,课程号为1的成绩..这样成绩表就涉及到了两个表...因此还需要对关联表进行相关的操作..因此需要对所有的关联表进行遍历..然后进行相关的操作..我们可以看到这里又涉及到了主表的再次遍历...原因取决于外键的影响...

      简单的说一下外键..我们知道成绩表中主键是学生ID和课程ID的组合...但是学生ID又在学生列表中是主键..因此学生ID在成绩表中被称为成绩表关于学生表的外键...同样课程ID是成绩表关于课程表的外键...因为成绩表中的主键是复合型的..因此需要对外键进行一一获取..外键的获取通过对主表的遍历...最后把所有获取的外键进行保存..用来进行联合查询..这也就是那个步骤的目的...

      这样就简单的书写了一个通用的DAO..虽然只有一个方法..其他方法的实现我们可以自己去重写...

    4.使用AndBase中提供的DAO来完成对数据库的一系列操作...

      在AndBase中...源码就是通过对上面的封装给我们直接提供了一个通用的DAO接口层...我们都不需要去进行实现..直接就可以完成方法的调度过程...如果想要重写更多的方法..请继承实现类AbDBDaoImpl,然后在子类中去书写更多的方法...

      private UserInsideDao userDao = null
      //初始化数据库操作实现类
      userDao = new UserInsideDao(DBInsideSampleActivity.this);
            
      //(1)获取数据库 
      userDao.startReadableDatabase(false);
      //(2)执行查询
      userList = userDao.queryList(null, null, null, null, null, "create_time desc limit "+String.valueOf(pageSize)+ " offset " +0, null);
      totalCount = userDao.queryCount(null, null);
      //(3)关闭数据库
      userDao.closeDatabase(false);

      使用AndBase直接操作数据库...非常的简单...UserInsideDao类..这里表示我要对LocalUser实体对象进行操作...也就是对LocalUser表进行操作..剩下所有函数的调用都是对这个表进行相关的操作...

    package com.andbase.demo.dao;
    
    import android.content.Context;
    
    import com.ab.db.orm.dao.AbDBDaoImpl;
    import com.andbase.db.DBInsideHelper;
    import com.andbase.demo.model.LocalUser;
    
    public class UserInsideDao extends AbDBDaoImpl<LocalUser> {
        public UserInsideDao(Context context) {
            super(new DBInsideHelper(context),LocalUser.class);
        }
    }

      DBInsideHelper类...获取数据库辅助类的过程...初始化所有的数据表...

    package com.andbase.db;
    
    import android.content.Context;
    
    import com.ab.db.orm.AbDBHelper;
    import com.andbase.demo.model.LocalUser;
    import com.andbase.demo.model.Stock;
    import com.andbase.friend.ChatMsg;
    import com.andbase.model.User;
    
    public class DBInsideHelper extends AbDBHelper {
        // 数据库名
        private static final String DBNAME = "andbasedemo.db";
        
        // 当前数据库的版本
        private static final int DBVERSION = 1;
        // 要初始化的表
        private static final Class<?>[] clazz = {LocalUser};
    
        public DBInsideHelper(Context context) {
            super(context, DBNAME, null, DBVERSION, clazz);
        }
    
    }

      最后贴一下LocalUser类...传递的Class仅仅是一个LocalUser表..一般会传递多个表的..传递多个表就需要定义多个实体类就行了...

    package com.andbase.demo.model;
    
    import java.util.List;
    
    import com.ab.db.orm.annotation.Column;
    import com.ab.db.orm.annotation.Id;
    import com.ab.db.orm.annotation.Relations;
    import com.ab.db.orm.annotation.Table;
    @Table(name = "local_user")
    public class LocalUser {
    
        // ID @Id主键,int类型,数据库建表时此字段会设为自增长
        @Id
        @Column(name = "_id")
        private int _id;
        
        @Column(name = "u_id")
        private String uId;
    
        // 登录用户名 length=20数据字段的长度是20
        @Column(name = "name", length = 20)
        private String name;
    
        // 用户密码
        @Column(name = "password")
        private String password;
    
        // 年龄一般是数值,用type = "INTEGER"规范一下.
        @Column(name = "age", type = "INTEGER")
        private int age;
    
        // 创建时间
        @Column(name = "create_time")
        private String createTime;
        
        // 包含实体的存储,指定外键
        @Relations(name="stock",type="one2one",foreignKey = "u_id",action="query_insert")
        private Stock stock;
    
        // 包含List的存储,指定外键
        @Relations(name="stocks",type="one2many",foreignKey = "u_id",action="query_insert")
        private List<Stock> stocks;
        
        // 有些字段您可能不希望保存到数据库中,不用@Column注释就不会映射到数据库.
        private String remark;
    
    
        public int get_id() {
            return _id;
        }
    
    
        public void set_id(int _id) {
            this._id = _id;
        }
    
    
        public String getuId() {
            return uId;
        }
    
    
        public void setuId(String uId) {
            this.uId = uId;
        }
    
    
        public String getName() {
            return name;
        }
    
    
        public void setName(String name) {
            this.name = name;
        }
    
    
        public String getPassword() {
            return password;
        }
    
    
        public void setPassword(String password) {
            this.password = password;
        }
    
    
        public int getAge() {
            return age;
        }
    
    
        public void setAge(int age) {
            this.age = age;
        }
    
    
        public String getCreateTime() {
            return createTime;
        }
    
    
        public void setCreateTime(String createTime) {
            this.createTime = createTime;
        }
    
    
        public List<Stock> getStocks() {
            return stocks;
        }
    
    
        public void setStocks(List<Stock> stocks) {
            this.stocks = stocks;
        }
    
    
        public String getRemark() {
            return remark;
        }
    
    
        public void setRemark(String remark) {
            this.remark = remark;
        }
    
    
        public Stock getStock() {
            return stock;
        }
    
    
        public void setStock(Stock stock) {
            this.stock = stock;
        }
    
    }

     

    转载于:https://www.cnblogs.com/RGogoing/p/4953980.html

    展开全文
  • 在学习这两个对象之前,我们应该已经有了http协议的基本了解了,如果不清楚http协议可以看我关于http协议的介绍。因为其实request和response使用大部分是对http协议操作。 request对象的介绍 我们先从...
  • 目前,已经有数量众多的写好的DTD文件可以利用。针对不同的行业和应用,这些DTD文件已经建立了通用的元素和标签规则。你不需要自己重新创建,只要在他们的基础上加入你需要的新标识。 当然,如果愿意,你可以创建...
  • 翻译过程中,译者感到此言不虚:作者从数据库的基本概念到数据库建模,从如何运用规范化原则到如何做成实际数据库表,从如何保护数据库完整性到如何提高数据库性能,从数据库安全机制到并发事务控制,从...
  • Hibernate的对象化关联处理确实挺强大,但是使用起来坑太多,有多少人敢在项目 中大范围使用真不知道,屠龙刀不是人人提的起啊。 2、mybatis:轻量级,基于xml的模式感觉不利于封装,代码量不小,基于xml维护也...
  • 面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。 4. 多态性:  多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化...
  • 所有函数可以通过 <code>__proto__</code> 找到它</li><li><code>Function.prototype</code> 和 <code>Object.prototype</code> 是两个特殊的对象,他们由引擎来创建</li><li>除了以上两个特殊对象,...
  • 至于shouldConvert和后续的几个判断则是为了防止value不是单纯的对象而是Regexp或者函数之类的,或者是vm实例再或者是不可扩展的,shouldConvert则是某些特殊情况下为false,它的解释参见源码里尤...
  • 笔试 大家围着会议室坐后,招聘经理简单介绍了一下公司情况,以及对应聘者的基本要求,然后就开始发试卷,笔试时间70分钟。 我也想太多,考了这么多年试了,还怕这一次?于是心平气和地做题,结果第一题...

     笔试

     

     大家围着会议室坐好后,招聘经理简单介绍了一下公司的情况,以及对应聘者的基本要求,然后就开始发试卷,笔试时间70分钟。

     我也没想太多,都考了这么多年的试了,还怕这一次?于是心平气和地做题,结果第一题就给我来了个下马威:JSP有哪些内置对象?它们分别有何作用?我一下懵了,JSP虽如雷贯耳,但它到底是什么东西呢?Java Server Page?不清楚;内置对象?也不清楚。然而我想,既然与网站设计有关,那么JSP很有可能指网页了;我虽然没有用Java做过网站开发,但用C#做过ASP.NET网站啊,既然都是网页,那么它们肯定有相通之处。照着这个思路,我写上了答案。还好就这一题是关于JSP的,其他都与Java相关。

     

    整套试卷,我总体感觉做得一般。第一页有两道编程题不会,但我本着“宁可写错,不可放过”的原则,写上了编程思路(后来事实证明这么做也是明智的)。让我很意外的是:最后一题竟来一段英文翻译。我前前后后看了三遍,还是不明白他讲的是什么。最后狠下心来,配以数据库三层模式设计思想,对这段话进行了直译。后来,请教了面试官才知道,原来那段话描述的是他们开发的ERP系统的部分功能。

      试题其他的都很常规,但如果事先没有准备,有可能一题都不会(个人观点),比如:Java中的GC是什么,为什么用GC;面向对象程序设计中的接口问题等。因为我昨天晚上有准备,所以答得不是很困难。

     

    总结:

    1、参加笔试前复习相关知识,唤起知识记忆,做好笔试准备;

    2、笔试时,千万不要留有空题,即时不会,也要写上解题思路。

     

     

    展开全文
  • 和传统 t-sql书籍不同,本书以独特 “技巧 ”形式来介绍知识点,涵盖了数据处理(增删改、视图、索引、存储过程、触发器等)、数据应用(web服务、 clr集成、分布式查询等)和数据库配置(主体、安全、数据库...
  • 基本都采纳了这种模式。平常所讲MVC基本是这种服务端MVC。 <h2>MVP <p>MVP模式有两种: 1. Passive View 2. Supervising Controller 而大多数情况下讨论都是Passive View模式。本文会对PV模式进行较为...
  • 是一名专业Web性能优化者的基本功。本章将详细介绍Web性能领域一些专业术语,通过这些术语也可以侧面了解是哪些因素在影响加载性能。 背景 衡量网页性能是一个比较琐碎事情,因为没有某一个指标或...
  • 成员水平不一样可以采取结对方式提升人员水平,但成本回收周期长,基本不会对本项目(3月内项目)产生benefit,但遇到有苗子要坚决培养,否则日后还是会死,留不留得住人,就是另外一个管理topic了。...
  • “window 方案会不会是更好的选择?”,首先想到的是效率问题。 测试效率 一般来说,一个浏览器窗口或者 tab 是独立进程,iframe 则和父窗口共享进程。所以直觉上会认为,在 window ...
  • 与所有程序语言编译器/解释器一样,输入内容为一有效表达式存储字符流数据,而输出是按照某种运算规则评估出此表达式结果(数据类型由具体某种运算法则决定)。因此,显然它属于动态地评估表达式...
  • 如果你看过我前面几篇关于HttpClient文章或者官网示例,应该知道HttpClient对象在创建时,可以设置各种参数, 但是却没有简单进行封装,比如对我来说比较重要3个: 代理、ssl(包含绕过证书验证和自定义...
  • 设计模式(一)

    2011-03-10 23:37:00
    其实接触过设计模式时候感觉挺神秘,等看了这本书以后,发现也什么,用到技术就是面向对象语言中最基本的封装继承、多态,有点模式大家其实也经常用,只是不知道它还有个规范定义和特定名字。...
  • 上面RoadMap图中列出了作为一个java程序员需要掌握技术路线,所有技术懂那当然非常,如果还掌握也关系,just keep learning! 必须掌握基础知识 作为程序员当然是有门槛,这个门槛就是所需要掌握...
  • C#微软培训教材(高清PDF)

    千次下载 热门讨论 2009-07-30 08:51:17
    9.1 面向对象的基本概念.101 9.2 对象的模型技术 .103 9.3 面向对象的分析 .105 9.4 面向对象的设计 .107 9.5 小 结 .110 第十章 类 .112 10.1 类 声 明 .112 10.2 类 成 员 .113 10.3 构造...
  • JavaScript学习指南.pdf

    热门讨论 2013-01-22 15:52:13
     本书系统地介绍了JavaScript的基本语法、基本对象、调试工具与排错技术、事件处理机制、浏览器对象模型/文档对象模型(BOM/DOM)等方面知识,并通过一个复杂示例深入探讨了Ajax应用。本书提供了许多简单易懂、...
  • 书中涉及概念基本涵盖了js大部分内容,包括 作用域链、js数据类型、OOP对象在js中实现、闭包、BOM和DOM模型、对变态IE系列兼容解决方案、事件流、还有xml、jason、E4X这些数据格式与js交互操作简介、...
  • JavaScript学习指南

    热门讨论 2011-08-18 09:59:11
    《JavaScript学习指南(第2版)》系统地介绍了JavaScript的基本语法、基本对象、调试工具与排错技术、事件处理机制、浏览器对象模型/文档对象模型(BOM/DOM)等方面知识, 并通过一个复杂示例深入探讨了Ajax应用。...
  • 基础升级之Enum枚举

    2020-01-08 14:24:31
    --一路追踪,原来一开始想的都是内部类,怎么得到实例对象,一开始就偏了。 终于明白了。故记下本次学习历程。再次明白了关键字搜索重要性。 1、枚举基本介绍 参考博文:--https://www.iteye.com/b...
  • 软件工程教程

    热门讨论 2012-07-06 23:10:29
    (6)按照系统开发主体面向的对象 国内图书管理系统应用情况 国内Android开发行业市场现状 国内的Android开发还是以应用开发为主,主要分成3类: 为企业开发应用 开发通用应用(Android Market或者其他App Market...
  • c#学习笔记.txt

    热门讨论 2008-12-15 14:01:21
    另外我发现论坛上学习Java非常有个性,当有人问起学习哪种语言更时,他会打出几百个“JAVA”来,填满整个屏幕,也不说是为了什么。我觉得这样做未免有些太霸道了,如果你说这叫偏执狂我也不反对,虽然我...
  • C#微软培训资料

    2014-01-22 14:10:17
    9.1 面向对象的基本概念.101 9.2 对象的模型技术 .103 9.3 面向对象的分析 .105 9.4 面向对象的设计 .107 9.5 小 结 .110 第十章 类 .112 10.1 类 声 明 .112 10.2 类 成 员 .113 10.3 构造...

空空如也

空空如也

1 2 3 4 5 6
收藏数 107
精华内容 42
关键字:

介绍的对象基本都没好的