JAVAWEB Dao模式之增删改和查询通用方法

来源:互联网 发布:erp软件实施顾问 编辑:程序博客网 时间:2024/05/29 03:09

三.Dao模式

这个是非常重要的模式。主要是运用分层,分为实体层,Dao,Util层,DaoIml层和测试层。

实体层:主要封装了数据库一些字段。

Dao层主要是接口,定义各种方法,做什么。

DaoIml层主要是实现接口层的各种方法

Util层主要写了一些通用方法和数据库的开启和关闭

测试层顾名思义就是测试

 

下面我们通过对数据库的操作来对Dao模式进行一个了解。首先,敲代码之前要考虑吧代码的复用性

一 一个增加的方法

1,连接数据库的两种方法在上面已经提到过,放到Util包下即可,这里不在说明。

2,在实体类封装数据库字段,首先,你要保证你有这张即将操作的表,其次,字段名和你封装的名一致。

 

3,在接口中定义插入方法,即Dao层下

这个方法有一个整形返回值,主要是利用返回值来判断是否插入成功,并且该方法一个类对象参数,主要是把要插入的字段存入这个类对象中,这个类对象中的属性正好又和数据库的字段对应,这就是我们在实体类封装的时候做的。

4 创建实现接口类,并且实现插入方法

 

 

 

这里插入的值便从类对象里面获取,操作和正常插入操作没有什么不同

5在测试类中添加数据

 

红线是接口引用具体子类,调用子类的具体方法

这样便以Dao模式的方式实现了数据的插入,查询,删除,修改和此类似。

写到这里,我们可以思考一下,每次修改,插入,删除的过程都差不多,只是SQL语句和参数的不同,我们可不可以定义一个方法来增强代码的复用性呢?通过一个方法,其他类来调用或重写?当然可以,SQ语句和参数不同,我们可以把这两个作为参数来传递,谁调用,谁来传参数来决定是增加或者删除,SQL语句的参数决定了是什么类型,即删除还是增加,另一个参数束腰是SQL语句里面的条件什么的。这里你肯定该想为什么是增删改,而没有查询呢,因为查询会返回一个结果集对象,还需要进行遍历,与增删改不同,不过我们在后面也可以定义一个查询的通用方法。

一,增删改通用方法

 1考虑到代码的复用性,我们把这个方法写在Util包中开启和关闭数据库连接的类中,其他需要这个方法的继承这个类就好。

 

2主要是参数那里,在上面,相信我已经说的很详细了,然后我们在接口中定义一个查询方法吧。

 

这个方法名和前面那个Util类方法并没有多大的关系,那个方法只需要在最后调用,注意体会方法的参数和返回值

3然后再实现类中实现这个方法

 

只需要在实现类的实现方法中定义SQKL语句和需要传的SQL参数就可,如果SQL参数为空,可以传一个NULL过去,这样就实现了增删改的通用。

4最后在测试类通过set方法添加上数据即可,和上面一样

JDBC总结

一:主要是JDBC链接

格式主要为:加载驱动:Class.forName(oracle:jdbc:OracleDrivaer);

创建链接Connection con = DriverManager(jdbc:orcale:thin:@localhost:1521:orcl2);

然后通过PreparedStatement  pstmt = con.prepareStatement(sql),创建执行SQL语句,最后执行

pstmt.executeUpdate()或者pstmt.executeQuery();

使用PreparedStatementStatement的好处主要是能够防止SQLde注入,在安全性要好的多,建议使用前者。

JDBC的链接可以考虑一下代码的复用性:1创建一个类,把链接的代码封装成一个方法,需要用的时候在调用,但这种方法每次调用都需要加载驱动,关闭后还得重新开启链接

2创建Properties文件(在项目根目录下创建),把需要用的属性加载进去,通过第三方软件进行读取,获得链接,好处是 每次申请不需要再进行加载驱动,关闭链接后会被回收,下面介绍如何使用这种方法。

1, 填写配置文件:

2, 导入第三方包

 

利用链接池来进行JDBC的链接主要需要导入三个包,加上JDBC本身的链接还需要导入一个包,一共需要导入4个包。

3, 编写代码

Properties po = new Propertier();

po.load(new FileInputStream(Properties文件名));

DataSource  da = BasicDataFactory.createDataSource(po);

//这里主要是运用工厂模式来创建对象,不需要通过New,回去可以复习一下工厂模式。

con = da.getConnection();

好了,这样一个通过连接池链接数据库的工作就完成了。

二:JDBC大数据操作

     大数据操作这里,主要是分为cblobblob两种类型数据的文件,前者主要存储一下长的字符串,后者主要通过二进制来存储一些图片、音频之类的,不过,在数据库中通常存的是图片或者视频的路径,很少存源文件。

1 clob介绍

  链接数据库的操作上面已经介绍过,下面不在重复

PreperdStatement pstmt = con.preparestatement(insert into table  values(?,?));

String str=要存入长字符串;

StringReader reader = new StringReader(str);

//StringReader这里运用这个方法主要是为了下面setCharacterStream方法服务,它的参数要求需要用到reader对象,StringReader方法主要是通过字符流的方式读取字符串

pstmt.setCharacterStream(index,reader,length),//1个参数主要是对应sql语句中的第几个问号,第二个参数就是前面创建的

StringReader对象,第三个参数是reader的长度。

 

2  blob介绍

主要存储一些图片之类的文件,前提别忘了在数据库创建该类型的字段。

思想主要是:先创建一个字段用来存入图片,先把这个字段存入一个空数据(empty_blob()),然后更新它,更新为图片或者音频。

1, String sql  = (insert into table values(empty_blob()));

2, pstmt =con.preparedstatement(sql);

3,   pstmt.executeUpdate();

这就成功的向里面插入了一个空值。然后查询这个空值并且更新它

1 sql=(select * (blob字段名)  from table  where  id=(对应的ID值)for update(尤其重要))

2 pstmt = con.preparedstatement(sql);

3 ResultSet  rs = pstmt.executeQuery();

4 if(rs.next()){

5   Bolob b = (Bolob)rs.getBlob(大数据字段名);

6   OutPutStream os = b.setBinaryStream(1L);

7   InPutStream is  = (当前类名).class.getResourceAsStream(图片路径或者音频路径);

8 Int len =0;

9 Byte [] temp = new Byte[1024];

10 while((len = is.read(temp))!=-1){

   os.write(temp,0,len);

os.flush();

11 }

12 con.commit();

13 

14 }

查询通用方法:

先说一下思路,增删改查方法,方法参数通常由一个SQL语句和SQL语句里面的参数组成,由于SQL语句参数的数量是不定的,我们首先要对这个SQL语句参数数量进行判断,其次,得到的结果集列的数量也是不定的,我们需要动态的获取SQL查询的列。

这里需要用到getMetaData()getColumnCount()这两个方法。解决了这两个问题,便可以开始写查询通用方法了。

1:声明一个public List executeQuery(String sql,Object[]params)方法

2con = getConnect()  //把链接数据库的方法封装到父类的getConunt()中,这里直接调用就好了

3:Lsit table = new ArrayList();//用来装载查询出来的每一行数据

3: PreparedStatement ps = con.preparedStatement(sql)//这里的SQL不需要再定义,而是通过调用的时候传参数过来,这样来实现SQL的通用,SQL语句的定制化解决,下面便开始来考虑SQL语句中参数,当然,是如果有的话

4: for(inti=0;i<params.length;i++){

pstmt.setObject(i+1,paramsp[i]);//这里可能会抛出异常,为什么要用setObject呢,因为考虑到兼容性的问题,使用Object可以涵盖大部分数据类型,包装数据类型的插入成功。

}

5ResultSet rs = ps.executeQuery();

ResultSetMetaData meta = rs.getMetaData();

Int num = meta.getColumnCount //这几行代码是执行查询语句,和获得每一行对应的有几列,拿到这个数据之后,我们可以遍历出这个查询语句中有几个字段。

6while(rs.next()){

  List row = new ArrayList() //遍历出每一行数据,每一行对应一个rowList;

for(int i=0;i<num;i++){

 row.add(I,res.getObject(i+1));//把每一行的数据存入row里面

}

table.add(row);//内层循环结束一次,代表一行的数据已经存储完毕,然后把这一行的数据装入table里面

}

return table;

} 

使用连接池链接数据库不需要关闭connection

 

最后还有两步,在接口中定义一个查询方法,返回一个List实现类中重写,定义完SQL语句和数组参数之后返回调用一下我们刚刚写过的方法就好,值得注意的是,在最后遍历数据的时候,也是需要两次循环的,外层循环遍历出的每一行的数据,内层循环遍历出的是每一个字段的值。

 

 

测试方法遍历出数据到控制台

 



0 0
原创粉丝点击