您的位置:首页 > 编程语言 > Java开发

java数据引擎(三):详细使用

2015-04-23 21:00 148 查看
A.查询

数据引擎的传递参数可分为三类,map对象、实体对象和Param对象,其中Param是引擎的条件参数类,它可以构建灵活多样的条件。下面分别举例演示。

a.获取单条记录

以map对象作参数

Map map=new HashMap();

map.put(“sid”,1);//查询字段sid值为1的记录

//获取Map对象的结果

Map  student = DataCenter.getMap(“student”,map);

//获取实体对象的结果

Student student = DataCenter.getObject(“student”, map, Student.class);

 

以实体对象作参数

Student st=new Student();

st.setSid(1);

//获取Map对象的结果

Map  student = DataCenter.getMap(“student”,st);

//获取实体对象的结果

Student student = DataCenter.getObject(“student”, st, Student.class);

 

 

以Param对象作参数

//获取Map对象的结果。查询student表(单主键)中主键为1的记录,以下三种方式等效

Map  student = DataCenter.getMap(“student”,1);//直接以具体的值当参数

Map  student = DataCenter.getMap(“student”,new Param(“sid”,1));

Map  student = DataCenter.getMap(“student”,new Param().add(“sid”,1));

 

//获取实体对象的结果。查询student表中主键为1的记录,以下三种方式等效

Student student = DataCenter.getObject(“student”,1, Student.class);

Student student = DataCenter.getObject(“student”,new Param(“sid”,1), Student.class);

Student student = DataCenter.getObject(“student”,new Param().add(“sid”,1), Student.class)

 

 

//如果不是按主键查询,可能有多条符合条件的记录,但只会返回第一条

Param  pm=new Param();

pm.add(“name”,”李伟”);//查询name为李伟的记录

//pm.add(“name”,”=“,”李伟”);//与上句的写法完全等效

Map  student = DataCenter.getMap(“student”,pm);//返回Map

Student student = DataCenter.getObject(“student”,pm, Student.class);//返回实体

 

b.查询多条记录

获取多条记录的参数设置与单条记录完全一样,只是调用的方法名不一样。

//获取name是李伟,并且age大于20的所有记录

Param  pm=new Param();

pm.add(“name”,”李伟”);

pm.add(“age”,”>“,20);

List<Map> list= DataCenter.getMapList(“student”,pm);//返回map结果集

List<Student> list= DataCenter.getObjectList(“student”,pm, Student.class);//返回实体结果集

 

//获取name是李伟,或者age为20的所有记录

Param  pm=new Param();

pm.add(“name”,”李伟”);

pm.addOr(“age”,20);

List<Map> list= DataCenter.getMapList(“student”,pm);//返回map结果集

List<Student> list= DataCenter.getObjectList(“student”,pm, Student.class);//返回实体结果集

 

//获取birthday不在2000-4-1到2000-4-30之间的所有记录

SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");

java.util.Date da1=df.parse("2000-04-01");

java.util.Date da2=df.parse("2000-04-30");

pm.addNotBetween("birthday", da1, da2);

List list = DataCenter.getMapList("student", pm);

 

//对于mysql来说,可以直接传递日期串,即可以这样设置条件:

pm.addNotBetween("birthday", "2000-04-01", "2000-04-30");

 

//如果是查询某范围内的值,使用下句,生成的sql为between ..and ..

pm.addBetween("birthday", da1, da2);//与上句正相反,

 

 

如果不传参数,获取的是全部记录

List<Map> list= DataCenter.getMapList(“student”);//返回map结果集

List<Student> list= DataCenter.getObjectList(“student” , Student.class);//返回实体结果集

 

 

c.参数类Param详解

Param是参数类,通过它可构建多种sql 的where条件,列举如下:

pm.add(“age”,”<>“,30);//age不等于30

pm.addOr(“age”,”>=“,30);//或者(or) age大于等于30

pm.addBetween(“age”,20,30);//年龄在20和30间,包含20和30

pm.addNotBetween(“age”,20,30);//年龄不在20和30间,即<20并且>30

pm.add(“name”,”like”,”%张%”);//name含’张’

pm.add(“name”,”like”,”张%”);//name以’张’开头

pm.add(“name”,”not like”,”%张%”);//name不含’张’

pm.add(“name”,”is”,null);//name 的值为null

pm.add(“name”,”is not”,null);//name 的值不为null

pm.add(“name”, “in”, “'张三','李四','王五'”);//name为所列的三个值

pm.add(“name”, “not in”,“'张三','李四','王五'”);//name不是所列的三个值

pm.add(“age”, “not in”,“20,30,40”);//age不等于所列的三个值中的任意一个

如果in 或not in后所列的值很多,可以用list:

List list=new ArrayList();

list.add(“张三”);

list.add(“李四”);

list.add(“王五”);

pm.add(“name”, “in”,list);

 

参数条件最终会生成sql,先加的会出现在sql的靠左边。其中涉及的关系符与sql是一样的,包括:>,=,<=,<>,(not)like,(not)in,is(not),含not时,与邻词间有空格。

在一次查询请求中,不能对同一个字段进行一次以上的定义,否则只有最后添加的条件有效。例如,如果想查询age在20-30间或大于40的所有记录,以下不行:

pm.addBetween(“age”,20,30);

pm.addOr(“age”,”>“,40);

这种情况下,可以这样使用:

pm.addAsItIs(“age between 20 and 30 or age >40”);//标准的sql语法

 

在上面所列的各个查询中,默认查询的是所有字段,如果一张表字段很多,或者有大对象字段,并且实际上只需要用到其中很少的字段,这种做法从性能上看就不合理了,需要作限制:

Param  pm=newParam();

pm.addField(“name,age”);//只查询name和age字段的值

如果需要查询大多数字段,只有少数不需要,可以采用排除法

pm. setExcludeColumn(“photo, birthday”);//排除photo和birthday两个字段,查询所有其它的字段

可以看到,多个字段间是以英文逗号分隔的。

如果上下文中已经有了待查询的指定字段的数组,可以set进param中,

假如有了数组:String[] fields={“name,age”};

pm. setFields(fields);//与pm.addField(“name,age”)等效

 

如果查询时,想去除重复:

pm. addDistinctField(“name”);

生成的sql类似这样:select distinct name from table where..

 

如果想对结果集排序:

pm. addOrderby(“sid desc,age asc”);//按sid降序,age升序排列

 

如果只想取部分记录,即所谓的分页查询:

pm. setPage(1,10);//从第一条记录开始,取10条

需要注意的是,如果是mysql数据库,分页查询返回的是map对象的结果集,则list最后一个元素map的key为'_total_',值为本次符合查询条件的记录总数。

 

构建Param时可以连写,例如下面查询条件是取name和age字段,age小于30,取第10到第60条记录,按age升序排列。

Param  pm=new Param().add(“age”,“<“,30).

addField(“name,age”).setPage(10,50).addOrderby(“age”);

 

也可直接用条件作参数生成Param对象:

Param  pm=new Param(“name”,“<>“,”张三”);

pm.addBetween(“birthday”,”1980-01-01”,”1980-12-31”);

生成的条件是:name不为张三,并且是在1980-01-01到1980-12-31期间出生的。

 

在实际应用中,如果上下文中已经有了实体对象或map对象,可以用之直接构建Param对象,然后就可以充分利用param的其它功能了:

Param  pm=new Param(map);//map对象

Student st=...//来自其它地方生成的实体对象

Param  pm=new Param(st);//实体对象

pm.setPage(..);//进一步作其它需要的设置

 

如果构建一个Param对象完成查询后,想重复使用该对象,而条件稍有不同,可以这样:

pm.remove(“name”);//移除name的限制条件

pm. removeField(“name”);//移除name的限制查询字段,即移除setField的设置

pm. removeAllField();//移除全部的限制查询字段

pm.reset();//重置,所有的条件或设置全清除

 

d.获取记录数

//获取符合条件的记录数

Param  pm=new Param(“class_id”,5);

int count= DataCenter .getRecordCount(“student”,pm); //统计所有在5班的学生数

int count= DataCenter .getRecordCount(“student”);//无条件参数类时,获取全部记录数

 

 

e.迭代取数

如果要取的记录数很多,但又不必全部放在内存,引擎采取只将主键放内存,需要具体内容时再次读取。(当然如果是海量数据,主键也会占大量内存,需控制条件。)

下面pm是Param对象,构建方式与上面相同,如果不传pm,则获取的是全部记录。

Iterator<Map<String, Object>> iter=DataCenter.getMapListIterator("student", pm);

//Iterator< Student > iter=DataCenter.getObjectListIterator("student ",pm, Student.class);

while (iter.hasNext()) {

Map  stu=iter.next();

String name=(String)stu.get(“name”);

//Student  stu=iter.next();

// String name=stu.getName();

. . .

}

 

 

f.获取其它形式的数据

获取xml格式的数据:

String  data= DataCenter.fetchXmlData("student", pm);

 

获取指定字段与记录映射的数据

在实际应用中,有时获取到了记录集后,想取其中的一条记录,通过循环结果集当然可以,但更简单的方式如下:(参数中sid为表的主键名)

Map<String, Map> data=DataCenter .getMapListMap("student", pm,”sid”);

Map  student=data.get(10);//取主键值为10的记录

String name=( String)student.get(“name”);//获取具体的各字段值

 

获取大对象的流数据

// photo大字段,如果符合pm条件的记录超过一个,取第一个

InputStream  is= DataCenter .getLobStream("student",”photo”, pm);

g.判断记录否存在

  虽然按上面的查询,根据是否有数据可以判断记录的存在,但性能更好的方式如下:

//判断是否有符合条件的记录(pm为Param对象,构建方式可参考前文)

boolean  flag= DataCenter.isExist(“student”,pm);

 

h关联查询

前面都只涉及单一的表,有主从关系时,稍微复杂些,引擎提供两种方式实现关联查询,一种就是通过Param实现,下面就介绍,一种通过xml配置实现,类似hibernate做法,在后边的SQL操作中有介绍。

假如student与班级表school_class是一对一的关联,与课程表lesson是一对多的关联,为简单起见,school_class只有两个字段,一个是主键cid,一个是名称name,通过主键关联。lesson有三个字段,主键lid、关联字段sid和name,通过sid与student的sid进行关联。三张表都是单主键。在Student实体类中增加两个复合属性:

private SchoolClassschoolClass;
  private List<Lesson>lessonList;

 进行关联查询的关键就在Param中设置条件,例如:

 Param pm=new Param();

pm.add("sid", 5);

//设置通过主表student的外键class_id关联到从表school_class的主键

pm.setLinkOne("class_id","school_class",SchoolClass.class);//one-one

//设置通过主表student的sid关联到从表lession的sid

pm.setLinkMany("sid", "lesson", "sid", Lesson.class);//one-many

Student sd=DataCenter.getObject("student",pm, Student.class);

SchoolClass schoolClass = sd.getSchoolClass();//获取关联属性

List<Lesson> lessonList = sd.getLessonList();//获取关联属性

 

//如果将上述各调用的最后一个参数Class去掉,将获得Map类型的结果

Map  map=DataCenter.getObject("student",pm);

//获取复合属性的方式有点特别,是通过以表名_Map、表名_List作key来获取的

Map school=(Map)map.get("school_class_Map");

List lessionList=(List)map.get("student_lesson_List");

如果Param设置了延迟加载(后面有详述),那么主记录将不会加载复合属性,只有在真正去获取从表属性的值时,才会再次从库中读取。

如果是多对多的情况,需要用到中间表,有下面的方法可设置:

setLinkMany(String
linkTable,StringmiddleTable,StringmiddleFromField,
StringmiddleToField)
linkTable :关联的目标表名
middleTable 中间表名,中间表一般含两个字段
middleFromField 中间表中与主表主键进行关联的字段名
middleToField 中间表中与目标主键进行关联的字段名
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: