时间:2025-06-08 08:02:42
关于SQL和ORM的争论,永远都不会终止,我也一直在思考这个问题。最近温习了一遍SSH框架,发了动弹,和广大猿友进行了深刻的探讨,被喷的五体投地,感慨万千,于是就有了今天这篇文章。
欲速则不达,欲达则欲速!
hibernate让你不用写sql了,这不单可以让你的应用更好移植其它数据库,更主要的是让程序员更专注业务逻辑、数据关系、对象关系等。hibernate对一对多,多对多关系实现是非常好的。很关键一点,它支持lazy,可以让你的数据只在需要的时候被加载,听起来很完美。hibernate还有一个更牛的就是HQL,这是完全可以把查询映射到你OO模型的查询语言,和mybatis的映射比起来,还是更方便和更强大的。
1、@Lazy注解是什么?
@Lazy注解用于标识bean是否需要延迟加载,源码如下:
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Lazy { /** * Whether lazy initialization should occur. */ boolean value() default true; }
只有一个参数,默认是true,也就是说只要加了这个注解就会延迟加载。
2、@Lazy注解怎么使用
没加注解之前主要容器启动就会实例化bean,如下:
AnnotationConfigApplicationContext applicationContext2 = new AnnotationConfigApplicationContext(MainConfig.class);
创建user实例
而加上@Lazy注解则必须在第一次调用的时候才会加载如下:
@Scope @Lazy @Bean(value=”user0”,name=”user0”,initMethod=”initUser”,destroyMethod=”destroyUser”) public User getUser(){ System.out.println(”创建user实例”); return new User(”张三”,26); }AnnotationConfigApplicationContext applicationContext2 = new AnnotationConfigApplicationContext(MainConfig.class); User bean2 = applicationContext2.getBean(User.class);创建user实例 实例1 === User [userName=张三, age=26]
@Lazy注解注解的作用主要是减少springIOC容器启动的加载时间
二、hibernate劣势
看完优势之后,感觉hibernate无所不能了,无敌是多么的寂寞。处理大量数据或者大并发情况的网络服务感觉不是很好用,那么现在开始说说hibernate的问题。
1、难以使用数据库的一些功能
hibernate将数据库与开发者隔离了,开发者不需要关注数据库是Oracle还是MySQL,hibernate来帮你生成查询的sql语句,但问题来了,如果你想用某种数据库特有的功能,或者要让查询的sql完全符合你的心意,这就难了。如果使用hibernate,虽然它能对生成的查询进行一定程序的定制,但就有点隔靴挠痒的感觉了,而且你开发起来付出的代价更大。至于hibernate对native sql的支持,还是挺完善的,这种native sql还能返回non-managed entity,不走hibernate的cache,优化是搞定了,但如果整个项目都这么整,那还是用mybatis吧。
很多时候,我们都有一个需求:得到数据库服务器的当前时间。这是因为本机时间和服务器时间是有差别的。各种数据库都提供了函数来获得,比如,mysql,可以用“select now()”。hibernate也提供了一个函数current_timestamp(说起timestamp,个人认为数据库的timestamp做的很差,它居然和datetime是一个数量级的(精确度),这怎么可以用来表示真正的stamp啊!)。可是,你却无法用直接使用“select current_timestamp()”来获得服务器的当前时间,你还必须加上一个查询的表!比如,“select current_timestamp() from tbl_Good”。个人十分郁闷,我只是想用这个简单功能而已,为什么我一定要知道数据库里面的表格呢????更何况还必须建立映射。。。。。。不是我不明白,这世界太复杂了 。每样产品都是拼命的复杂化,其实,它们实在是忽略了一般的用户只需要一小部分功能而已。默认的功能应该是能够满足普通用户的常见需求的,那样才算是一个好的产品。我不认为hibernate做到了这点。
2、满足不了程序对cache的需求
很多web服务,对cache的依赖是非常大的,hibernate自带的cache按理说也是很强大的,但还是满足不了很多需求。
3、耦合度高
hibernate的确是在你项目开发的时候节约了很多时间,但是它对你的业务逻辑模型和数据库模型互相依赖的程度太高了。短期没啥问题,但随着项目的变迁,这些都会改变,在维持这种仅仅耦合的关系的时候,你会发现你的代码特别脆弱,随便改一处数据库的schema,整个java项目可能要改几十次。而且现在mybatis的自动mapping做的也很好,开发起来也没花多长时间,等项目进入中后期,你需要大量定制和优化查询的时候,mybatis的开发效率就更明显了。
4、debug难
作为一个后端程序员,我比较喜欢每一行代码我都精确知道它到底在干什么。尤其是数据库访问的代码,往往系统的瓶颈就在这些地方产生,每一行都不能小看。我看过hibernate早期版本的部分代码,比我想象的复杂和强大很多。的确很多地方Hibernate可以强大的只用一行代码解决很多问题,但比如说一个update()或者save()到底做了什么,这里既有hibernate本身的逻辑,也有你应用的逻辑,如果这一行产生了问题,你该如何去做?我个人觉得这是很难搞的,还不如一开始费点事,用mybatis这种。
作为一个程序员,我始终坚持认为改代码比改配置文件容易。
5、hibernate更新大批量数据
(1)hibernate批量更新customers表中大于零的所有记录的age字段:
如果customers表中有一万条年龄大于零的记录,那么session的find()方法会一下子加载一万个customer对象到内存中。当执行tx.commit()方法时,会清理缓存,hibernate执行一万条更新customers表的update语句:
(2)以上hibernate批量更新方式有两个缺点
(3)为了迅速释放1万个Customer对象占用的内存,可以在更新每个Customer对象后,就调用Session的evict()方法立即释放它的内存:
在以上程序中,修改了一个Customer对象的age属性后,就立即调用Session的flush()方法和evict()方法,flush()方法使hibernate立刻根据这个Customer对象的状态变化同步更新数据库,从而立即执行相关的update()语句;evict()方法用于把这个Customer对象从缓存中清除出去,从而及时释放它占用的内存。
但evict()方法只能稍微提高批量操作的性能,因为不管有没有使用evict()方法,Hibernate都必须执行1万条update语句,才能更新1万个Customer对象,这是影响批量操作性能的重要因素。假如Hibernate能直接执行如下SQL语句:
那么以上一条update语句就能更新CUSTOMERS表中的1万条记录。但是Hibernate并没有直接提供执行这种update语句的接口。应用程序必须绕过Hibernate API,直接通过JDBC API来执行该SQL语句:
以上存储过程有一个参数p_age,代表客户的年龄,应用程序可按照以下方式调用存储过程:
从上面程序看出,应用程序也必须绕过Hibernate API,直接通过JDBC API来调用存储过程。
6、hibernate删除大批量数据
Session的各种重载形式的update()方法都一次只能更新一个对象,而delete()方法的有些重载形式允许以HQL语句作为参数,例如:
如果CUSTOMERS表中有1万条年龄大于零的记录,那么以上代码能删除一万条记录。但是Session的delete()方法并没有执行以下delete语句
Session的delete()方法先通过以下select语句把1万个Customer对象加载到内存中:
接下来执行一万条delete语句,逐个删除Customer对象:
由 此可见,直接通过Hibernate API进行Hibernate批量更新和Hibernate批量删除都不值得推荐。而直接通过JDBC API执行相关的SQL语句或调用存储过程,是hibernate批量更新和批量删除的最佳方式。
素小暖讲Spring JdbcTemplate
三、群众的眼光的雪亮的,千万不要逆天而行
四、被喷之后的一些感悟
感觉就是一场批斗大会,我深深的感觉到才疏学浅的无奈,我真的只是想好好学习而已,希望若干年后,我还能初心不改。
作为一个初级程序员而言,没有必要花费过多的时间去证明技术的无用论,我并没有对hibernate这个框架进行深入的研究,只是在肤浅的层面的一些个人感悟。
框架本身并没有对错一说,只有适合不适合,任何框架都有其自身的能力范围,hibernate封装了很多有用的API给我们,降低了操作数据库的难度和复杂度,同时也减少了模板代码的数量,但hibernate留给开发者的可操作空间相对mybatis少了很多;mybatis框架使用起来更加灵活,开发者可以自定义查询语句,但增加了模板代码量,看起来并没有hibernate边界。两种框架在便捷与灵活两个指标上做出了取舍和妥协,这不能说是框架的错。对于一个框架而言,需要有自身专注的领域和设计愿景,不可能面面俱到,就如这位大哥所言:
使用任何一种技术框架,都需要贴合现实的业务需求以及自身的技术能力。当你还没有深入的去了解一门技术或者当前业务需求无法与框架契合时,不要盲目的批判框架的好坏。
https://my.oschina.net/u/4006148/blog/3157757
(本文作于2010年)前不久,单位领导交给我一项任务,建立媒体资源数据查询和管理系统。随着单位媒体资源的日积月累,各种媒体存储介质越来越多,这些数以万计的媒体数据,记载着当地政治、经济、社会人文等发展的历史,是当地一笔宝贵的历史资料,因此,搞好这些媒体资源的管理尤其重要。
对于数据的管理,数据库是最好的平台。数据库,即有结构的数据集合,通俗的讲,就是数据的仓库。因此,我想到了Access。在办公软件Office套件中,最为人们熟悉的是Word和Excel,因为它们功能强大且方便易用,更因为它们不仅可用于办公,还可用于个人写作和家庭记帐理财等。同为Office套件中一部分的Access,虽然有着同样强大的功能,但使用的人却相对少些,不像Word和Excel那样广泛。事实上,真正用过Access的人,对其强大功能和灵活应用均称赞“不错,很好的……。”Microsoft Access是一种关系式数据库,关系式数据库由一系列表组成,表又由一系列行和列组成,每一行是一个记录,每一列是一个字段,每个字段有一个字段名,字段名在一个表中不能重复。
表与表之间可以建立关系(或称关联,连接),以便查询相关联的信息。Access数据库以文件形式保存,文件的扩展名是mdb。
Access 数据库由六种对象组成,它们是表、查询、窗体、报表、宏、页和模块。
表(Table) ——表是数据库的基本对象,是创建其他5种对象的基础。表由记录组成,记录由字段组成,表用来存贮数据库的数据,故又称数据表。
查询(Query)——查询可以按索引快速查找到需要的记录,按要求筛选记录并能连接若干个表的字段组成新表。
窗体(Form)——窗体提供了一种方便的浏览、输入及更改数据的窗口。还可以创建子窗体显示相关联的表的内容。窗体也称表单。
报表(Report)——报表的功能是将数据库中的数据分类汇总,然后打印出来,以便分析。
宏(Macro)——宏相当于DOS中的批处理,用来自动执行一系列操作。Access列出了一些常用的操作供用户选择,使用起来十分方便。
模块(Module)——模块的功能与宏类似,但它定义的操作比宏更精细和复杂,用户可以根据自己的需要编写程序。模块使用Visual Basic编程。
页——是一种特殊的直接连接到数据库中数据的一种WEB页。通过数据访问页将数据发布到Internet 或Intranet上,并可以适用浏览器进行数据的维护和操作。
一、开发前的准备工作
干每一项工作都不外乎这样几个阶段:即准备阶段、实施阶段和总结阶段(对于系统开发而言叫做后期调试和完善阶段)。开发数据库也是如此,实施前必须进行前期准备。
(一)准备工具
这里的工具就是备用的工具书和工作平台。开发数据时会用到至少两套工具书:《Access使用手册》和《Visual Basic编程》;开发数据库时需要的平台是Microsoft Access系统、Photoshop系统(用于图形处理和制作)、图标制作系统等,如果要制作帮助文件还需要帮助文件制作系统。应用这些系统制作“图标”和主控界面的装饰图。(下图为装饰图)
(二)需求调查
开发的应用系统是否能满足实际使用的要求,关键看你是否进行了详细的需求调查和了解。只有做了详细的需求调查,才能开发出实用的应用系统来。对于这一点,很多初学者往往会忽视,只是埋头开发,结果弄出来的东西总是离实际要求相差甚远,根本不能使用。
对于本单位的“媒体资源管理”数据库而言,主要需要调查了解以下几点:
1.数据量多大。这是一个关键,如果数据量非常之大,那么应用Access是不行的。我了解到,单位的媒体资源数据量不大,平时的使用管理数据量也不大,因此,我决定使用Access来开发;
2.基本信息。要求每一个素材登记有编号、规格、类别、时长、首拍时间、拍摄人、素材内容、存放位置等基本信息;
3.媒体资源的规格。对于存储介质而言,我了解到的规格主要有模拟和数据磁带、光盘,磁带又分为大1/2、小1/2等;
4.媒体资源的类别。因为这些媒体资源记录的是当地的政治、经济等全方位的影像资料,为了便于管理,就必须对它进行科学合理的分类。但单位还没有明确的规定,我只能暂时按素材的内容所具有的性质分为:党群类、政务类、工业类、农业类、商业类、文教类、卫生类、体育类、科技类、军事类、综合类(因为有的磁带记录的内容多而杂)共11类;
5.编号规定。对于这些素材资料,每一个体如何编号,存放库位如何规定(编号),单位没有明确;
6.管理流程。这是与工作实际最紧密的重要环节,只有了解了实际管理的工作流程,才能按照流程需要来开发数据库。我了解到单位对于媒体资源的管理有专门的部门和人员,平时使用的人员也相对集中但不确定,平时随时都可能进行数据查询、素材借出或归还,借出或归还时都要主管领导批准和保管员检查签收等,当前应用一台计算机进行管理,将来也可能利用单位内部局域网联网管理;
7.查询功能。要求能灵活的进行多种条件的查询和精确查询,查询的主要条件是首次拍摄时间、素材内容提要等;
8.报表功能。要求能准确的进行总计或分类统计,对于借出、归还要有详细的登记统计等。
(三)框架构思
框架构思十分重要,一个好的框架,使数据库结构简单、关系明确、功能实用、使用方便。根据调查了解到信息,媒体资源数据库应该是一个开放式的数据库,即所有信息都是不固定的,因此,先期开发的数据库数据不能固定死,必须可变。同时,由于使用人员对于数据库的操作使用技能不高,因此,数据库的操作使用应越简单越好,应采用点击直接选择的方式,少使用或不使用文字录入,以降低使用难度,达到方便快捷的目的。
基于上述因素的考虑,媒体资源数据库以素材基本信息为主界面,上部为单个素材的基本信息,中部为该素材的借出、归还登记明细,底部为数据查询、数据库备份、报表等功能命令按钮和库存量数据动态显示。(下图为数据库主控界面)
二、实施系统开发
(一)明确表与表之间的关系
Access数据库是关系数据库,表与表之间可以建立关系,数据可以互相调用,所以,首先必须明确表与表之间应建立哪些关系。媒体资源数据库主表是“媒体资源登记表”,与它相关的主要是“借出登记表”和“归还登记表”,主表与副表之间应建立唯一的连接关系,而表中确保“唯一性”的字段是“磁带编号”,因此,它们的连接关系是建立在“磁带编号”关键字段上的。另外,主表中的“拍摄人”、“磁带规格”、“素材类别”及副表中“借出人”、“批准人”、“经办人”、“归还人”等信息由于是随时可变的,所以必须另外建立相应的独立表并与之建立连接关系,以便主、副表中的相应字段直接从中调用数据。
(二)建立副表
1.规格表
字段:规格,类型:文本(10个字符),并设该字段为主键。
2.类别表
字段:类别,类型:文本(10个字符),并设该字段为主键。
3.部门表
字段:部门,类型:文本(8个字符),并设该字段为主键。
4.职务表
字段:职务,类型:文本(6个字符),并设该字段为主键。
5.事由表
字段:事由,类型:文本(10个字符),并设该字段为主键。
6.人员表
字段:姓名,类型:文本(8个字符),并设该字段为主键。
字段:性别,类型:文本(2个字符),并设该字段从查阅向导——键入值“男、女”中获取。
字段:部门,类型:文本(8个字符),并设该字段从查阅向导——“部门”表中获取。
7.经办人表
字段及属性设置同人员表
8.批准人表
字段及属性设置同人员表,其中“职务”字段从“职务表”中获取。
9.借出登记表
字段:借出ID,类型:自动编号,并设该字段为主键。
字段:磁带编号,类型:文本(8个字符)。
字段:借出日期,类型:日期/时间(长日期格式,默认值:=Date$())。
字段:借出时间,类型:日期/时间(长时间格式,默认值:=Time$())。
字段:借出人,类型:文本(8个字符),并设该字段从查阅向导——“人员”表中获取。
字段:借出事由,类型:文本(10个字符),并设该字段从查阅向导——“事由”表中获取。
字段:批准人,类型:文本(8个字符),并设该字段从查阅向导——“批准人”表中获取。
字段:经办人,类型:文本(8个字符),并设该字段从查阅向导——“经办人”表中获取。
字段:次数,类型:数字(长整型,默认值:1)。
10.归还登记表
字段:归还ID,类型:自动编号,并设该字段为主键。
字段:磁带编号,类型:文本(8个字符)。
字段:归还日期,类型:日期/时间(长日期格式,默认值:=Date$())。
字段:归还时间,类型:日期/时间(长时间格式,默认值:=Time$())。
字段:归还人,类型:文本(8个字符),并设该字段从查阅向导——“人员”表中获取。
字段:经办人,类型:文本(8个字符),并设该字段从查阅向导——“经办人”表中获取。
字段:次数,类型:数字(长整型,默认值:1)。
(三)建立主表
11.磁带信息登记表
字段:磁带编号,类型:文本(8个字符),并设该字段为主键。
字段:磁带规格,类型:文本(10个字符),并设该字段从查阅向导——“规格”表中获取。
字段:素材类别,类型:文本(10个字符),并设该字段从查阅向导——“类别”表中获取。
字段:素材时长,类型:数字(长整型,默认值:0)。
字段:素材节数,类型:数字(长整型,默认值:1)。
字段:首拍日期,类型:日期/时间(长日期格式,掩码:9999年99月99日;0;_)。
字段:拍摄人,类型:文本(8个字符),并设该字段并设该字段从查阅向导——“人员”表中获取。
字段:存放位置,类型:文本(10个字符)。
字段:内容提要,类型:备注。
字段:关键贞1-4,类型:OLE 对象(共4个)。
字段:次数,类型:数字(长整型,默认值:1)。
以上表如下图
(四)创建关系
创建关系很简单,只需要打开关系编辑界面,将副表中的相关字段拖到主表的相关字段即可。如:将事由表中字段“事由”拖到借出登记表中字段“借出事由”处,单击对话框“确定”,两个表中的这两个字段即建立了关系。媒体资源数据库的表间关系如下图:
(五)创建查询
如果你对Visual Basic编程比较熟练,那么,可以使用Visual Basic编程来实现相关查询,如果不熟悉Visual Basic编程,就用Access数据库中创建查询向导来建立需要的查询表。从前面了解需求情况来看,媒体资源数据库除了能灵活地进行各个字段查找外,还要实现针对首拍日期和内容提要两条件的精确查找,另外,主控界面底部是关于库存量的动态显示,这就要求我们建立实时的数据统计,因此,媒体资源数据库应建立如下图中所显示的相关查询,以便窗体和报表使用。
这里要着重说明的是,基于“首拍日期”和“内容提要”两个条件的精确查询,需要在“磁带信息登记表查询”中“首拍日期”字段和“内容提要”两个字段设置查询条件,而“首拍日期”这个条件又是基于查询者临时输入的日期范围,因此,它必须是从输入日期数据的窗口中获得的相关日期信息;而“内容提要”字段中的数据不是固定的数据,查询条件不能固定,需要进行模糊查询。又因为是精确查找,这两个查询条件的逻辑关系应该是“与”的关系。
鉴于上述要求,在“磁带信息登记表查询”中“首拍日期”字段的“条件”栏中输入“>=[Forms]![报表日期范围]![开始日期] And <=[Forms]![报表日期范围]![终止日期]”查询条件,而在“磁带信息登记表查询”中“内容提要”字段的“条件”栏中输入“Like [输入内容提要可用通配符如:*人大*]”查询条件,且让它们在同一行中,形成逻辑与的关系。
对于其它查询表的建立可以在设计视图中逐个创建,这里不再叙述。
(六)创建窗体
主控窗体“磁带信息登记表”是整个数据库的操作平台,所有操作将在这个窗体上完成,它既有基本信息输入窗口,又有各种功能命令按钮;既有主窗体,又有子窗体,因此,创建过程比较复杂。
1.创建基本信息登记表窗体,进入窗体设计界面;
2.调整窗体大小,安排各个字段的位置,插入装饰图,使窗体美观大方;
3.设置窗体主要属性和参数:
(2)标题:影像资料信息登记;
(3)默认窗体:单个窗体;
(4)最大最小化按钮:最小化按钮;
(5)宽度:25.407厘米;
(6)打开:[事件过程],并进入代码编辑界面,输入如下代码:
Private Sub Form_Open(Cancel As Integer)
DoCmd.SelectObject acForm, ”磁带信息登记表”, True
DoCmd.Minimize ’最小化数据库
4.创建借出登记子窗体
(1)将贷出登记表拖入界面中部左侧位置;
(2)设置借出登记表 子窗体属性及参数:
名称:借出登记表 子窗体;
源对象:借出登记表 子窗体;
链接子字段:磁带编号;
链接主字段:磁带编号;
宽度:14.101厘米;
高度:3.164厘米;
特殊效果:凹陷;
边框样式:实线;
边框宽度:细线。
(4)设置子窗体表属性及参数:
记录源:借出登记表;
标题:借出登记表 子窗体;
默认视图:数据表。
5.创建归还登记子窗体
归还登记子窗体的创建方法及属性、参数的设置与借出登记子窗体相同。
6.创建总量统计子窗体
(1)先将窗体页脚向下拉开一定距离,以便放置子窗体;
(2)将总量统计查询表拖至窗体页脚处;
(3)其它方法同上述子窗体的创建方法。
7.创建报表日期范围窗体
(1)用设计视图创建两个非绑定控件,分别作为“开始日期”和“终止日期”输入窗口,并在这两个控件左侧分别使用标签工具创建两个标签,输入“开始日期”和“终止日期”;
(2)设置窗体主要属性“打开”——“事件过程”,进入代码编辑状态,输入如下代码:
Private Sub Form_Open(Cancel As Integer)
Me.Caption = Forms![报表日期范围].OpenArgs
Forms!报表日期范围!开始日期.SetFocus
(3)创建一个“预览……”命令按钮,设置主要属性“单击”——“事件过程”,进入代码编辑状态,输入如下代码:
Private Sub 预览_Click()
If IsNull([开始日期]) Or IsNull([终止日期]) Then
MsgBox ”您必须输入开始时间和终止时间。”
DoCmd.GoToControl ”开始日期”
Else
If [开始日期] > [终止日期] Then
MsgBox ”截止日期必须大于开始日期。”
DoCmd.GoToControl ”开始日期”
Else
Me.Visible = False
End If
End If
8.创建命令按钮
(1)创建“刷新”命令按钮
使用Access系统工具在适当位置创建一个命令按钮,在弹出的对话框中选择记录操作——刷新数据,系统会自动建立相关代码如下:
Private Sub 刷新_Click()
On Error GoTo Err_刷新_Click
DoCmd.DoMenuItem acFormBar, acRecordsMenu, 5, , acMenuVer70
Exit_刷新_Click:
Exit Sub
Err_刷新_Click:
MsgBox Err.Description
Resume Exit_刷新_Click
(2)创建“查找”命令按钮
方法同上。代码如下:
Private Sub 查找_Click()
On Error GoTo Err_查找_Click
Screen.PreviousControl.SetFocus
DoCmd.DoMenuItem acFormBar, acEditMenu, 10, , acMenuVer70
Exit_查找_Click:
Exit Sub
Err_查找_Click:
MsgBox Err.Description
Resume Exit_查找_Click
(3)创建“精确查找”命令按钮
方法同上,代码如下:
Private Sub 精确查找_Click()
On Error GoTo Err_精确查找_Click
Dim stDocName As String
Dim stLinkCriteria As String
DoCmd.OpenForm ”报表日期范围”, , , , , acDialog, ”影像资料统计表”
If Not IsLoaded(”报表日期范围”) Then
Cancel = True
End If
stDocName = ”资料精确查询”
DoCmd.OpenForm stDocName, , , stLinkCriteria
Exit_精确查找_Click:
Exit Sub
Err_精确查找_Click:
MsgBox Err.Description
Resume Exit_精确查找_Click
(4)创建“数据备份”命令按钮
方法同上,代码如下:
Private Sub 数据备份_Click()
On Error GoTo 11 ’如果删除文件夹出错,执行第11行
Dim fso
Set fso = CreateObject(”Scripting.FileSystemObject”)
fso.DeleteFolder (”D:mtzy”) ’删除已有的文件夹及文件
11 MkDir ”D:mtzy” ’创建文件夹
Exit_数据备份_Click:
Exit Sub
22 Err_数据备份_Click:
MsgBox Err.Description
Resume Exit_数据备份_Click
(5)创建“基本信息录入”命令按钮
方法同上,选择窗体操作——打开窗体。代码如下:
Private Sub 录入基本信息_Click()
On Error GoTo Err_录入基本信息_Click
Dim stDocName As String
Dim stLinkCriteria As String
stDocName = ”基本信息录入”
DoCmd.OpenForm stDocName, , , stLinkCriteria
Exit_录入基本信息_Click:
Exit Sub
Err_录入基本信息_Click:
MsgBox Err.Description
Resume Exit_录入基本信息_Click
(6)创建基本信息录入窗体中的各种命令按钮,
方法同上,这里不再叙述。
(7)创建报表命令按钮
关于报表系统的相关命令按钮的创建,是在报表创建完毕后进行的。这里以“资料总表”命令按钮为例加以说明,其它报表命令按钮的创建方法相同。
使用Access系统工具在适当位置创建一个命令按钮,在弹出的对话框中选择报表操作——打开预览报表,系统会自动建立相关代码如下:
Private Sub 资料总表_Click()
On Error GoTo Err_资料总表_Click
Dim stDocName As String
stDocName = ”影像资料统计表”
DoCmd.OpenReport stDocName, acPreview
Exit_资料总表_Click:
Exit Sub
Err_资料总表_Click:
MsgBox Err.Description
Resume Exit_资料总表_Click
通过上述步骤的创建,主控窗体创建完毕。其界面如下图:
(七)报表制作
数据库的数据统计靠报表来实现,报表要根据功能需求来制作,见下图:
上图为已建好的报表。报表可以通过向导来创建,但一般都不美观、不实用,还需要人工制作。报表的创建步骤大同小异,这里只对“影像资料统计表”进行说明。
1.应用报表向导创建“影像资料统计表”;
2.进行调整制作:
(1)将页面页眉下移一定空间,并将报表页眉移到页面页眉处,以便每一页都显示报表页眉;
(2)插入单位标志图;
(3)使用标签控件在页面页眉右侧制作一个报表日期范围显示,在控件中输入“=”记录期间: ” & [Forms]![报表日期范围]![开始日期] & ” 至 ” & [Forms]![报表日期范围]![终止日期]”,将来接受报表日期范围对话框的日期数据;
(4)调整主体区数据控件的位置,并用画线工具画出表格竖线和横线;
(5)将报表页脚下拖一定空间,并在此处应用标签工具和文本框工具制作数据统计框,在文本框中应用Sum和Count两种函数进行数据统计;
调整完的报表结构如下图:
3.设置报表打开事件属性为“事件过程”,并进入代码编辑状态输入如下代码:
Private Sub Report_Open(Cancel As Integer)
DoCmd.OpenForm ”报表日期范围”, , , , , acDialog, ”影像资料统计表”
If Not IsLoaded(”报表日期范围”) Then
Cancel = True
End If
4.设置报表关闭事件属性为“事件过程”,并进入代码编辑状态输入如下代码:
Private Sub Report_Close()
DoCmd.Close acForm, ”报表日期范围”
5.设置报表无数据事件属性为“事件过程”,并进入代码编辑状态输入如下代码:
Private Sub Report_NoData(Cancel As Integer)
MsgBox ”没有此报表的数据。取消报表…”
Cancel = -1
6.设置报表数据筛选,在过滤器属性中输入“([首拍日期])>=[Forms]![报表日期范围]![开始日期] and ([首拍日期])<= [Forms]![报表日期范围]![终止日期]”,并将打开过滤器属性设置为“是”,这样,报表将根据要求的日期范围统计数据。至此,本报表制作完毕;
7.进行运行调试,检查错误,修改。
(八)编译全局代码
进入模块,新建一个“全局代码”,并进入代码编辑状态,输入如下代码:
Option Compare Database
Function IsLoaded(ByVal strFormName As String) As Integer
’ Returns True if the specified form is open in Form view or Datasheet view.
Const conObjStateClosed = 0
Const conDesignView = 0
If SysCmd(acSysCmdGetObjectState, acForm, strFormName) <> conObjStateClosed Then
If Forms(strFormName).CurrentView <> conDesignView Then
IsLoaded = True
End If
End If
(九)设置数据库启动选项
1.打开数据库工具菜单下的启动选项窗口;
2.设置数据库应用程序标题;
3.设置数据库应用程序图标;
4.设置数据启动窗体为“磁带信息登记表”窗体;
5.其它选项可根据需要设置。
(十)设置数据库安全和用户账号及权限
应用Access系统的安全机制向导,设置数据库的安全机制很方便。以下是“媒体资源数据库”的安全机制:
1.组:管理员组、完全数据用户组、完全权限组、项目设计组、只读用户组五个组;
2.用户:Administrator、ccr、gly、cx共4个用户,并分别设置用户密码;
3.权限:Administrator为管理员权限,ccr为设计员权限,gly为完全数据用户权限,cx为只读用户权限。
至此,媒体资源数据库开发完毕,由于本人也是边学边用,所以难免存在这样或那样的错误,敬请朋友们多多指教!
用户评论
这个名字好像有点酷。
有14位网友表示赞同!
MT数据库?是专门做机器学习数据的吗?
有19位网友表示赞同!
9.0版本啊,估计功能很强大吧!
有8位网友表示赞同!
有没有可以体验一下的demo呢?
有7位网友表示赞同!
我很好奇它的性能怎么样。
有15位网友表示赞同!
MT数据库以前听说过吗?
有10位网友表示赞同!
感觉名字很有科技感。
有5位网友表示赞同!
期待了解更多它的信息!
有11位网友表示赞同!
MT9.0可以应用到什么领域呢?
有7位网友表示赞同!
这个名称给我的印象是专业和可靠的。
有5位网友表示赞同!
是不是比以前版本的速度更快更好用呢?
有14位网友表示赞同!
有没有发布教程或者文档,方便新手使用?
有7位网友表示赞同!
它的安全性怎么样?可以保护数据安全吗?
有15位网友表示赞同!
这个名字很独特。
有12位网友表示赞同!
MT数据库有哪些优势呢?
有14位网友表示赞同!
我想知道它是怎么工作的原理?
有5位网友表示赞同!
希望能看到更多关于MT9.0的介绍和应用案例!
有15位网友表示赞同!
请问MT数据库的使用范围比较广泛吗?
有19位网友表示赞同!
这个名字让我充满了期待!
有11位网友表示赞同!
MT9.0的功能有哪些呢?
有16位网友表示赞同!