JDBC笔记2

一,SQL攻击:
什么是SQL攻击呢?

JDBC的操作步骤分为一下几步:
1。导入数据库驱动jar包
2.加载数据库驱动类
3.创建连接数据库连接对象
4.创建SQL语句发送器语句对象

接着我们就可以编写要执行的SQL语句,然后调用语句对象的
executeUpdate(String sql)方法进行更新操作或调用executeQuery(String sql)
方法执行查询操作了。

接着我们做一个简单的登录操作,登录的时候是用户输入用户名和密码,
然后程序接收到用户输入的用户名和密码,再把用户名和密码拼接到选择
语句中再在数据库进行查询:
如:选择*来自t_user,其中u_name =?和u_pass =?;
如果查询生成的结果集有记录,即调用ResultSet对象的next()方法返回值为true,
则表示用户存在,我们让其登录;反之,如果调用结果集ResultSet对象的next()
方法返回值为false,则表示用户或密码错误,不让其登录。
注意:
1>从t_user中选择*,其中u_name ='mmy'和u_pass ='111';
2> select * from t_user,其中u_name ='mmy'或'a'='a'
和u_pass ='111'或'b'='b'; 

jdbc普通操作方式:
弊端:
1>存在sql攻击
2>执行效率低

应用程序端:
1>获取Connection连接对象
2>创建sql发送器语句对象|
3>拼接sql语句| --->黑客就可以利用sql语句的语法漏洞攻击系统  
4>语句对象发送sql语句|
  int | executeUpdate(String sql)执行更新
  ResultSet | executeQuery(String sql)执行查询
数据库端:
5>接收sql语句|
6>对sql语句进行语法检查|
7>编译sql语句| --->影响应用程序的执行效率(普通jdbc操做方式每次都会执行这个步骤)
8>执行sql语句|
9>向应用程序返回结果
应用程序端:
10>接收数据库返回的结果

jdbc预编译(预处理)操作方式:
优点:
1。避免sql攻击
2.提高了程序的执行效率
应用程序端:
1>获取到连接连接对象
2>指定sql模板语句(sql语句中的未知参数都是使用占位符?表示):
  select user from user where user =?和userPass =?;
3>创建SQL发送器的PreparedStatement(是声明的子接口)对象,给并其
  绑定SQL模板语句--->先会对SQL模板语句的语法进行一次检查
4>给SQL模板语句中的未知参数(占位符)赋值:
  PreparedStatement对象的set数据类型(?的索引,?的值)方法--->
  又会对参数值进行一次语法检查:
  pt.setString(1,“a'或'1 = 1 “); - >检查出参数值是非法表达式,不通过
  pt.setString(2,“b'或'1 = 1”); - >检查出参数值是非法表达式,不通过
  预编译方式可以防止sql攻击
5>调用PreparedStatement对象的:
  int | executeUpdate()执行更新
  ResultSet | executeQuery()执行查询
数据库端:
6> 接收sql语句|
7>检查语法|
8>编译sql语句| --->只在第一次执行sql语句的时候会完整的执行所有的步骤,
9>执行sql语句| 然后二次及二次之后再执行就无需检查语句编译语句了,
10>向应用返回结果接收到应用程序传递的参数之后直接执行(函数的性质一样)
应用程序端:
11>接收数据库返回的结果

二,解决SQL攻击------->预处理(预编译)
解决SQL攻击的办法就是不再使用声明对象去执行SQL语句,而是使用
声明接口的子接口的PreparedStatement的对象去执行SQL语句,这叫预处理。

PreparedStatement的使用:
1.给出SQL模板:用?代替SQL语句中的条件参数的SQL语句
.2。调用连接数据库连接对象的
PreparedStatement | preparedStatement(String sql模板)方法获取
PreparedStatement对象,并装配SQL语句
.3。调用PreparedStatement对象的setXxx(索引,值)方法给SQL模板中的?赋值。
参数一表示?的次序,参数二表示给对应赋的值?。
4.调用的PreparedStatement对象的的executeUpdate()方法执行更新操作,调用
的executeQuery()方法执行查询操作。
注意:方法不需要SQL语句作为参数,因为在调用连接对象的
preparedStatement时(字符串SQL模板)方法,创建的PreparedStatement对象时SQL
模板语句已经装配到的PreparedStatement对象中了。

预处理的优点:
1。防止SQL攻击
2.提高效率:
  当我们向数据库发送一条SQL语句操作数据库时,其实数据库服务器的底层执行了3个任务:
1>检查SQL语句的语法
2>编译SQL语句
3>执行SQL语句
由此可见如果使用声明对象向数据库发送并执行SQL语句时,每次它都会按照以
上3个步骤去执行,显然效率很低。
而PreparedStatement的对象它是将一个SQL模板与其绑定在一起,它是先把SQL模板
发送给数据库服务器,数据库先进行SQL语句语法检查,再然后生成compile-了一个类
似函数的东西。当执行SQL语句时只是把函数进行了调用再把参数传递过去而已。
若二次再执行时,就不用再进行语法检查和编译了,直接调用函数执行就行了。
如此就省去了语法检查和编译的耗时,大大提高了效率。
所以以后的开发中我们都使用的PreparedStatement对象向数据库发送并执行SQL语句。

四,DAO模式:
DAO(数据访问对象)模式,就是定义一个类,把访问数据库增,删,改,查
等操作的功能封装到DAO模式类的对象中.DAO处于数据库层和业务逻辑层(服务)
之间,这样就层次分明,每一层只负责自己的事情,利于代码的维护,需要即使进行
代码修改时,哪一层有问题就修改哪一层不会影响其它层的代码

具体操作:
1。定义实体域,即操作的对象(实体域对象)。
  实体类----表
  属性----列
  实体对象---行
例如:我们操作的表是用户表,那么就定义一个
用户类,类中定义的属性就是表中的所有字段,用用户类的对象用于临时存
放从用户表中查询到的记录行数据或者也可以将要往用户表中插入的记录行
数据临时的存储在用户对象中
。2.定义DAO接口(dao模式类的接口):接口中定义操作数据库增,删,改,查等
  的抽象方法
.3。定义DAO接口实现类(dao模式类) :在定
类一个业务类:主要负责具体的业务功能的实现(依赖dao对象,一般将dao对象
  定义为业务类的成员变量)

定义DAO工厂类:服务通过工厂类获取DAO模式类对象,并调用DAO模式类对象
。的功能进行业务逻辑操作(工厂设计模式,专门创建DAO对象的)

项目层次的划分(包):
1。实体域:beans entitys(entities)domain
2.业务类:service
3.dao接口:dao
4.dao模式类:dao.impl
5.其他类:utils

五,时间类型的转换:
在前面的DAO模式中我们提到一个实体域,是说在数据库中的每张表都会对应的Java
中的一个实体类,在该类中定义的所有属性就是表中的所有字段,该类而对象的
就持有这些属性,进而用该类的对象来临时存放从表中查询到的数据
那么就牵扯到一个数据库中字段的数据类型和java的中变量的数据类型的对应问题。对应
关系如下:
varchar -----> String
char ---------> String
int -----------> int
double ------> double
......
而需要强调的就是时间类型
在数据库中时间类型主要有3种,分别和java是如下对应的关系:
1>日期-----> java.sql.Date表示日期,只有年月日,没有时分秒。会丢失时间部分。
>时间----> java.sql.Time表示时间,只有时分秒,没有年月日。会丢失日期部分
.3>时间戳---> java.sql。时间戳表示时间戳,有年月日时分秒,以及毫秒。
而java.sql.Date类,为java.sql.Time类,java.s ql.Timestamp都是类
java.util.Date中的类的子类(java.util.Date类的对象代表日期,年月所有游戏
日时分秒以及毫秒)。所以无论是对于数据库的日期类型日期,
时间类型时间,时间戳类型时间戳的数据,我们往往在实体
域中都定义成java.util.Date类型的变量,而在DAO类模式中具体
的操作数据库的增,删,改,查时,根据再具体的数据库的时间类
型数据对应状语从句:java的的的时间类型数据进行对应的类型转换就行。而
Java的时间类型数据和数据库的时间类型的转换无非就是:
1。把数据库中的时间类型数据拿出来转成java对应的时间类型再存放到实体域
对象中的java.util.Date型变量中:
   从数据库中查询的数据到时是在结果集ResultSet对象中,然后可以调用
   ResultSet对象的getDate(int列数)或getDate(String列名)方法获取
   从数据库中查询到的Date类型的字段的数据,此方法的返回值就是
   java.sql.Date类型;或调用ResultSet对象的getTime(int列数)或
   getTime(String列名)方法获取从数据库中查询到的时间的类型字段的
   数据,此方法的返回值就是为java.sql.Time类型;或调用结果集对象的
   getTimestamp(INT列数)或getTimestamp(字符串 名)电子杂志方法从数据库
   中查询到的时间戳类型的字段的数据,此方法的返回值就是
   的java.sql.Timestamp类型。而因为java.sql.Date,java.sql.Time中,
   java.sql.Timestamp中类都是java.util.Date的子类,所以从结果集
   对象中获取到的java.sql.Date,java.sql.Time,java.sql.Timestamp
   类型的数据都能直接设置到实体域对象的java.util.Date类型的变量中。例如
  :java.sql。生日日期= rs.getDate(“sushiirthday”);
         Stu stu = new Stu();
         stu.setBirthday(生日);

      java.sql.Timestamp hiredate = rs.getTimestamp(“e_hiredate”);
      Emp emp = new Emp();
      emp.setHiredate(HIREDATE);

2.实体域对象的java.util.Date类型的数据转成和数据库的时间类型Date,Time,
Timestamp对应的java的时间类型java.sql.Date,java.sql.Time,
java.sql.Timestamp again存到数据库中。
步骤都是先把实体域对象的java.util.Date类型的数据,调用其的getTime()方法
转分类中翻译毫秒值,再分别使用java.sql.Date,java.sql.Time中,JAVA .sql.Timestamp
类各自的参数是毫秒值的构造器创建其对象,将达到类型java.util.Date中的转数据
分类中翻译的java.sql.Date,java.sql.Time中,的java.sql.Timestamp类型的数据,再求最后存
入数据库中。
例:java.util.Date生日= stu.getBirthday();
Java.sql.Dateweirthday = new java.sql.Date(birthday.getTime());

Java.util.Date hiredate = emp.getHiredate();
Java.sql.Timestamp e_hiredate =
new java.sql.Timestamp(hiredate.getTime());

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值