怎么在分页获取数据的还要获得到总记录数

SQL Server 获取数据的总记录数,有两种方式:

在说Session缓存之前我们先修改一下我们的项目,在项目中添加两个方法

一、VC访问数据库的技术

首先我们需要进行一下配置,这里需要修改的文件为application目录下的config目录下的database.php文件,我们修改相应的配置项,比如这里是我的配置情况:

1.先分页获取数据,然后再查询一遍数据库获取到总数量

@Before
public void setUp() throws Exception {

}

@After
public void tearDown() throws Exception {

}

  1、ODBC --Open Database Connectivity微软开放式数据互联,一组用于访问和操作数据库的API,可以访问不同的数据库产品,但只能访问关系型数据库。MFC将这组API函数封装成ODBC类,使用前需要将不同的数据库设置为ODBC数据源。

图片 1

2.使用count(1) over()获取总记录数量

我的这两个方法是我使用ide生成的,我们使用单元测试测试某个方法的时候,junit会先帮我执 setup ()方法,当单元测试结束后junit会为我们执行tearDown()方法。当然方法名无所为,只要符合规定就可以随便写,主要的是@Before与@After这两个注解。我们将hibernateTest1()
方法中的代码剪切出来最终改造成这个样子

  2、DAO --基于ODBC的,目前已经被淘汰

通常我们在操作数据库之前,首先需要进行数据库的加载,通常代码内容如下:
$this->load->database();
在连接之后,我们可以使用$this->db来获取当前的数据库对象,然后我们就可以对它进行数据库的操作了。
PS:对于查询操作,一般我们得到的都是一个结果集,我们还需要调用一下result()这个方法来或许结果集。

SELECT
    *
FROM
    (
    SELECT
        ROW_NUMBER() OVER(ORDER BY Id DESC) rn,    
        COUNT(1) OVER() AS TotalCount,
        Id
    FROM
        dbo.T_User
    )a
WHERE
    a.rn BETWEEN 1 AND 5
public class HibernateTest {
    private Session session = null;
    private Transaction transaction = null;

    @Before
    public void setUp() throws Exception {
        StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure().build();
        SessionFactory sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();

        session = sessionFactory.openSession();
        transaction = session.beginTransaction();
    }

    @After
    public void tearDown() throws Exception {
        transaction.commit();
        session.close();
    }


    @Test
    public void hibernateTest1(){

    }
}

  3、OLE DB  --基于COM技术的,提供了一组用于访问和操作数据库的接口。既可以访问关系型又可以访问非关系型数据,性能也有了很大提高。缺点是学习难度大,对程序员要求高,并未流行起来。

来做一次数据的查询,要获取user表的数据,创建一个Db控制器,然后写一个demo方法,整个文件的代码如下:

第二种方式既分页还能获取到总记录数量。就是多一个字段,如果获取一次数据较多的话,会浪费一些流量。

看明白了吧,在开始单元测试的时候帮我们获取一个Session对象并且开启一个事务,结束单元测试的时候,帮我们提交事务和关闭Session。

  4、ADO --基于OLE DB,对OLE DB又进行了封装,提供了一组简单的接口,逐渐流行起来,成为使用最广泛的技术之一。

图片 2

如果使用第一种的话,会多访问一次数据库,增加一次数据连接的关闭和打开,会消耗数据库资源。

获取一条记录

    还记得我们在数据库中插入了一条 name字段值为张三的一条记录吧?我们现在来从数据库中取出来。哦,对了我忘了和大家说一下由于Mac电脑安装oracle安装比较麻烦,再者使用服务器还是有点不方便。以后我都会使用mysql社区版做演示。

图片 3

Hibernate6-1.png

可以看出跟我们的预期效果是一样,发送了一条sql语句来查询数据,我们在使用get方法获取一遍数据

图片 4

Hibernate6-2.png

    可以看出连续两条打印结果,但是只发送了一条sql语句来做查询。那么问题来了,为什么第一遍使用get方法获取数据需要发送sql语句,而第二次使用get方法获取数据则不需要发送sql语句了呢?
    这是因为,你第一次使用get方法的时候session会将你的要查询的数据拿出来返回给你之后,并且会在session缓存中保存一份,所以当你在同一个session中查询相同数据的时候,会先到自己的缓存中去找,如果有则返回给你,如果没有就去二级缓存中找,如果在没有数据彩绘发送sql语句从数据库中查找。

  5、ADO.NET --基于.net平台的,适用于该平台之上的VB、VC、C#等各种语言。是一组用于访问和操作数据库的类。

我们就可以看到它数据取出后的结果了

第二种方式还是我同事开始使用的,然后我们就这样使用了。

操作session缓存

    flush:当我们调用flush方法时,会将我们的增删改操作同步到数据库中。
    reflesh:强制同步缓存中的一个对象,就是说我们获取了数据,当我们过了一段时间要继续使用此数据的时候,但是不确定别人是否修改了此数据,所以使用此方法来重新获取一遍。当然我们也可以先使用evict 方法将对象从session缓存中移除,然后在使用    get 方法获取。
    clear:清空缓存。
    evict:从session缓存中移除某个对象。
    commit和flush区别:flush执行一系列sql语句,但不提交事务;commit方法先调用flush方法,然后提交事务。

二、ODBC类的使用

图片 5

注意:目前发现只有sqlserver有,mysql没有这个效果,大家如果发现其他的可以使用,可以评论。3Q.

理论

    一级缓存生命周期很短与Session生命周期一致,所以一级缓存也叫Session缓存或事物级缓存。为什么也叫事务级缓存呢,是因为增删改方法需要事务来完成,每次执行增删改后都要commit,所以也叫事务级缓存。
    位于缓存中的对象处于持久化状态,它和表中的相关记录对应,Session能够在某些时间点,按照缓存中持久话对象的属性变化来同步数据库中表的记录,这一过程称为清理缓存。也就是说当我们使用get方法查询出数据库某条记录的时候,这时对象就处于持久状态,例如:User user = session.get(User.class, 1);
我们从数据库中查询出主键为1的数据,这个时候user对象就处于持久状态。说白了就是通过session得到的对象都是持久状态对象。
    当我们修改了此对象的属性值,在使用session的方法进行提交和刷新缓存时,就会将你修改过的对象属性值同步到数据库表中,在提交或刷新缓存时的过程称为清理缓存。当然清理缓存不只是提交和刷新缓存,还有别的方法。

  1、相关类

其他框架转过来的朋友们会不习惯每次查询后都需要写一个result()来获取结果集,但是不得不承认的是这种方式也有不少优点的,而且它本身也有比较丰富的方法可供我们调用:
(1)num_rows()用来获取总的行数。
(2)list_fields()用来获取所有的字段数。
(3)result_array()用数组的方式来获取数据。
(4)result_object()用对象的方式来获取数据。
(5)row()用来获取一行数据。
(6)next_row()用来获取下一行数据。
(7)first_row()用来获取第一行数据。
(8)previous_row()用来获取上一行数据。

一级缓存实现原理:

    session缓存是由它的实现类SessionImpl中定义的一些集合属性构成的,原理是保证有一个引用在关联某个持久话对象,保持它的生命周期不会结束。 大家都知道java中有垃圾回收器也就是GC,如果我们长时间不使用某个对象,那么他会在一定时间内,被java的垃圾回收器从内存中清理掉,所以hibernate为了防止通过session获取的对象被清理掉,在session缓存中一直保持着此对象的引用,直到session被关闭。

    CDatabase类 -提供了数据库的连接和关闭功能,另外还提供了执行Sql语句的功能。

在Db控制器中新建一个result()方法,然后书写如下代码:

一级缓存的作用

    减少数据库访问量,例如我们总是要获取数据,每次都要链接数据库查询,这样大大降低了运行效率,所以我们都会通过session缓存来获取数据。

图片 6

配图

    CRecordset类 -提供了对数据表中数据的操作。

图片 7

    以上两个类需包含头文件 #include <afxdb.h>

在上面的代码中,直接执行了一条SQL语句,然后我们用一个循环的方式来输出每条记录的内容,需要说明的是,这里的每条记录默认返回的格式是对象格式。然后我们就会看到具体的输出如下:

  2、使用步骤:

图片 8

    2.1设置ODBC数据源

增删改查

      控制面板->管理工具->数据源ODBC

首先是增加数据,我们可以使用insert()方法来插入数据,它的第一个参数是表名,第二个参数是一个数组。

      图片 9

 图片 10

    2.2使用ODBC类

在上面,我们向role表中插入了一条数据

      1--连接ODBC数据源 CDatabase::Open

图片 11

      2--执行sql语句  CDatabase::ExecuteSQL

我们也可以进行批量插入,这个时候我们可以使用insert_batch()方法,它的第一个参数也是一个表名,第二个参数可以是一个多维数组。代码范例如下:

      3--打开数据表  CRecordset::Open

图片 12

      4--获取字段数量  CRecordset::GetODBCFieldCount

这里表示成功插入的行数

      5--获取字段的信息  CRecordset::GetODBCFieldInfo

图片 13

      6--获取字段的值   CRecordset::GetFieldValue

对于查询数据来说,则有比较多的方法,下面是几个常用的方法:
(1)from()表示选择的表
(2)select()表示要选择哪些字段,可以用数组表示,也可以用逗号分隔多个字段的字符串,如果为空则表示选择所有字段,相当于填写了"*"
(3)distinct()表示去除重复的记录
(4)limit()表示要获取多少条记录
(5)offset()表示选择的偏移量
(6)where()表示where条件,一般第一个参数是字段名,第二个参数是值,也可以把第一个参数设置为整个条件
(7)group_by()表示按哪些字段进行分组
(8)order_by()表示按哪些字段进行排序,第一个参数为字段名,第二个参数用'asc'表示升序,用'desc'表示降序
(9)join()表示进行表的连接,第一个参数为连接的表名,第二个参数为连接的条件
(10)get()表示进行获取操作,在它之后通常跟result()来检索出具体的结果
其实具体的方法还有很多,这里只是列举了比较常用的几个

      7--记录的指针移动  CRecordset::MoveFirst/MoveLast/Move/MoveNext/MovePrevious

 图片 14

        CRecordset::IsBOF  //是否移动到了最开始

 

        CRecordset::IsEOF  //是否移动到了最末尾

 图片 15

      8--关闭记录集  CRecordset::Close

不过对于查询来说,它所涉及的方法还是有点太多了,很多功能我们还是需要去查看手册。

      9--关闭数据源  CDatabase::Close

对于数据的删除,我们可以使用delete()来执行,我们可以用from()来选择表,用where()来表示条件,用delete()来表示最后的删除。

   了解 CRecordView -显示数据库中记录的视图

 图片 16

三、使用ADO访问数据库

 

  1、ADO的文件:msado15.dll

图片 17

    所在路径-C:/Program Files/Common Files/System/ado/msado15.dll

 

  2、导入ADO组件

对于数据的修改,我们可以使用update()来进行修改,我们可以使用from()来选择要更新的表,我们可以用where来表示更新的条件,我们可以用set()表示要更新的数据。

    #import "组件文件所在路径" no_namespace rename("EOF","adoEOF")

 图片 18

    在项目头文件StdAfx.h中添加以上导入命令,编译后,在Debug文件下生成msado15.tlh、msado15.tli,这两个文件类似于控件的包装类。

 

  3、在使用任何COM组件时,都必须首先初始化COM库。

图片 19

    3.1使用组件前,初始化COM库  CoInitialize(NULL);

 

    3.2使用组件后,卸载COM库  CoUninitialize();

  4、ADO组件的使用

    使用C 类封装ADO组件的接口,好处是方便C 程序对ADO的使用。

    4.1 Connection接口(使用CAdoDatabase类封装)

      功能与ODBC类的CDatabase类似

      1-- Open()函数,连接数据库

        HRESULT Open (

                                        _bstr_t ConnectionString,  //连接字符串

                                        _bstr_t UserID,  //登录名称;在连接字符串中设置了该处即为""

                                        _bstr_t Password,  //登录密码;在连接字符串中设置了该处即为""

                                        long Options   //连接方式,直接写-1

        );

        由于不同的数据库“连接字符串”各不相同,所以通过新建*.udl文件自动生成连接字符串:

在桌面新建文本文档->重命名为1.udl->打开该文件->选择[提供程序]选项卡->选择对应的数据库驱动,点击“下一步”->输入相关信息后,测试连接,成功后确定即可;将1.udl重新以记事本方式打开,即可见连接字符串,如:

          Provider=Microsoft.Jet.OLEDB.4.0;

          Data Source=D:ado.mdb;

          或

          Provider=Microsoft.Jet.OLEDB.4.0;

          Password=123;User ID=ZWQ;

          Data Source=D:ado.mdb;

    4.2 Recordset接口(使用CAdoRecordset类封装)

      功能与ODBC类的CRecordset类似

      1-- Open()函数,执行sql语句、打开表、执行存储过程

        HRESULT Open (

                         const _variant_t & Source,  //sql语句、表名、存储过程

                             const _variant_t & ActiveConnection,  //活动连接

                             enum CursorTypeEnum CursorType,  //游标类型

                             enum LockTypeEnum LockType,  //锁定类型

           long Options   //标识第一个参数,sql语句-adCmdText/表名-adCmdTable/存储过程-adCmdStoredProc

        );

        游标类型:

        enum CursorTypeEnum{

                                    adOpenForwardOnly = 0,  //单向的静态游标

                                    adOpenKeyset = 1,  //键集游标,动态游标

                                    adOpenDynamic = 2,  //动态游标

                                    adOpenStatic = 3  //双向的静态游标

        };

        如果记录集使用的是动态游标,记录集会随着用户对表的修改发生变化;如果使用的静态游标,从表中取出数据后不再改变。

        锁定类型(多用户对同一数据库进行操作时):

        enum LockTypeEnum{

                                adLockReadOnly = 1,  //只读记录集

                                adLockPessimistic = 2,  //悲观锁

                                adLockOptimistic = 3,  //乐观锁

                                adLockBatchOptimistic = 4  //批处理方式的乐观锁

        };

      2-- 获取字段的数量(Fields)  Fields->GetCount()

      3-- 获取字段标题  Fields->GetItem(nIndex)->GetName()

      4-- 获取字段的值  Fields->GetItem(nIndex)->Value

      5-- 记录集的指针操作  MoveNext/MovePrevious/MoveFirst/MoveLast/Move(long nNums)

        IsEOF -是否移动到了最末尾 / IsBOF -是否移动到了最开始

      6-- 方式一:通过记录集的方式增、删、改

        6.1添加记录

          1--从数据表中获取数据到记录集  OpenTable()

          2--在记录集中添加一条新记录  AddNew()

          3--设置该记录各个字段的值  SetFieldValue

          4--更新到数据库  Update()

          5--重新显示数据  ShowData()

        6.2删除记录

          1--从数据表中获取数据到记录集  OpenTable()

          2--将记录指针移动到要删除的记录  MoveLast()

          3--执行删除操作  Delete()

          4--更新到数据库  Update()

          5--重新显示数据  ShowData()

        6.3修改记录

          1--从数据表中获取数据到记录集  OpenTable()

          2--将记录指针移动到要修改的记录  MoveFirst()

          3--执行修改操作  SetFieldValue

          4--更新到数据库 Update()

          5--重新显示  ShowData()

      7--方式二:通过执行sql语句的方式增、删、改操作

        1、Connection接口Execute()函数

          返回一个记录集,无法通过参数设置记录集的游标类型和锁定类型,是一个只读的,游标类型是单向的静态游标,所以,常用它执行增、删、改操作

        2、Recordset接口Open()函数

          常用Open()函数执行查询操作,可结合记录集的增、删、改方式对数据表中的数据进行增、删、改

  5、事务处理

    Connection接口提供了事务处理的功能

      启动事务 BeginTrans()

      结束事务 EndTrans(FALSE)--事务结束时包含了执行事务CommitTrans和回滚事务RollbackTrans

  6、如何在数据表中保存视频、图片数据?

    通常在数据库中保存视频、图片所对应的文件的路径

 

本文由星彩网app下载发布于星彩彩票app下载,转载请注明出处:怎么在分页获取数据的还要获得到总记录数

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。