JAVA-JDBC: (2) 数据库的粗略的CRUD及SQL注入问题
来源:互联网 发布:图片上传到淘宝变模糊 编辑:程序博客网 时间:2024/06/16 19:18
1. 数据库的CRUD操作
对数据的增删改查操作变化最大的莫过于对SQL语句的改变、首先我们简单的看下ORACLE中增删改查的SQL语句的简单写法:
1.1 C (Create) 对应 oracle中的 insert语句。
(1)、所有字段都插入:
insert into student values('A001','张三','男','01-5月-05',10);
注释: oracle中默认的日期格式’DD-MON-YY’修改日期的默认格式:
alter session set nls_date_format = 'yyyy-mm-dd'
(2)、插入部分字段:
insert into student(xh,xm,sex) values('2','八路','男‘);
(3)、插入空值:
insert into student(xh,xm,sex,birthday) values('3','Jhone','男',null)
1.2 R(Read) 对应 oracle中的 select 语句。
select查询SQL格式:
select···from···where···group by···having···order by···;
SELECT子句 --指定查询结果集的列 FROM子句 --指定查询来自哪个表或者试图 [WHERE 子句] --指定查询的条件 [GROUP BY 子句] --指定查询结果集的分组的条件 [HAVING 子句] --指定分组或者集合的查询条件 [ORDERBY 子句] --对查询的排列顺序 [UNION 子句] --多个SELET语句组合,得到结果集的并集
(1)、查询所有的用户:
select * from t_user;
★: 在oracle中这里的表名用别名时不能加as关键字 如:
select * from t_user u; 正确 select * from t_user as u; 错误
(2)、查询指定的列:
select username, sex from t_user;
(3)、as给列以别名显示:
select username as 用户名 from t_user;(这里的as关键字可以省略)
(4)、去掉重复的行 distinct:
select distinct username from t_user;
(5)、使用运算符:
select age+10, sex from t_user; (给每个年龄加10岁)
(6)、连接字符串:
select '用户名:' || username from t_user;(Oracle用||做连接字符串操作符);
(7)、where 子句:
select * from t_user where username = '宝宝';
(8)、在什么之间 between….and:
select * from t_user where userid between 9 and 10;select * from t_user where userid >=9 and userid <=10;
(9)、in匹配集合中的任意值:
select * from t_user where username in('马文涛','宝宝');
(10)、like模糊查询:
select * from t_user where username like '%涛%';
注释 通配符含义:
%:包含零个或者多个任意字符的字符串 _:任意单个字符 ?:任意单个字符 (啥时候用?在LIKE子句中怎么用?) #:表示0-9的数字(啥时候用?在LIKE子句中怎么用?) []:指定范围或者集合中的任意单个字符,例如[a-f]表示a~f中的一个字符
(11)、null判断某列为空:
select * from t_user where sex is null; (这里用is,不能用=,如果要返回不为null的记录就可以用is not null)
(12)、order by排序:ASC: 升序排列(可以省略),DESC: 降序排列:
select u.userid,u.username from t_user u order by u.userid;select u.userid,u.username from t_user u order by u.userid desc;
(13)、group by分组 (分组了就不能直接返回*,经常和聚合函数count(age)一起使用)
按姓名分组,并统计每组人数:select count(*),username from t_user group by username;根据多个字段分组: select username,age,count(*) from t_user group by username,age;
注释: group by有一个原则,就是 select 后面的所有列中,没有使用聚合函数的列,必须出现在 group by 后面
(14)、having 过滤分组:
select username from t_user group by username having count(*)>2;
(15)、子查询:
<1>子查询放在select后面,作为其中的一个字段返回。
select u.username,(select d.departname from t_depart d where d.departid = u.departid) from t_user u;
<2>子查询放在from后面,作为一张临时表。
select * from (select username,sex s from t_user where departid=1) where s = '男';
<3>子查询放在where后面,作为条件的一部分。
select * from t_user where departid = (select departid from t_depart where departname = '财务部');
(16)、联合查询:
<1>等值连接(内连接):
select u.username,d.departname from t_user u,t_depart d where u.departid = d.departid;
<2>外连接:即把不满足条件的记录也返回,用个+就行了,
(+)操作符在哪边就代表另外一边不满足联合条件的记录可以被输出。这个感觉不太常用。
select b.book_id,b.book_name from book_info as b,book_click_num as c where b.book_id = c.book_id(+);
1.3 U (Update)对应oracle中的 update 语句
(1)、修改一个字段:
update student set sex ='女' where xh = '2';
(2)、修改多个字段:
update student set set ='男', birthday ='1998-09-19' where xh ='2';update student set name = '争伟',sex = '男';(更新时不加条件表中所有行记录的姓名都被修改了!)
1.4 D (Delete) 对应oracle 中的 delete 和 drop 语句
delete from student;
只删除所有记录,表结构还在,写日志可以恢复,速度慢,例如:
第一步 早上工作时候建立一个保存点 savapoint first;
第二步:不小心出错,或者用了delete from student
第三步:回滚
roolback to first;
drop table student; 删除表的结构和数据; delete from student where xh ='2'; 删除一行记录truncate table student; 删除表中的所有记录,表的结构还在 但是不写日志,无法找回数据;速度快;
2. CRUD对应JDBC语句:
增、删、改用Statement.executeUpdate来完成,返回整数(匹配的记录数),这类操作相对简单。
查询用Statement.executeQuery来完成,返回的是ResultSet对象,ResultSet中包含了查询的结果;查询相对与增、删、改要复杂一些,因为有查询结果要处理。
3. SQL注入问题:
在SQL中包含 特殊字符 或 SQL的关键字(如:’ or 1 or ‘)时Statement将出现不可预料的结果(出现异常或查询的结果不正确),可用PreparedStatement来解决。
PreperedStatement(从Statement扩展而来)相对Statement的优点:
没有SQL注入的问题。
Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。
数据库和驱动可以对PreperedStatement进行优化(只有在相关联的数据库连接没有关闭的情况下有效)。
具体示例,可参考:sql注射示例
4. CRUD相应的粗略JDBC代码
import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class JDBCCRUD { /** * 应该 int create(Stu student) throw SQLException{} * 这里简化不封装对象了; * @return * @throws SQLException */ static int create() throws SQLException{ int numOfResult =0; Connection conn = null; PreparedStatement ps = null; String sql; try{ //注册驱动建立连接 conn = JDBCUtils.getConnection(); sql = "insert into stu values('S151208', 'wangwu', 'nan', 79, null)"; ps = conn.prepareStatement(sql); numOfResult = ps.executeUpdate(); }finally{ JDBCUtils.free(null, ps, conn); } return numOfResult; } static void read(String stuId) throws SQLException{ Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; String sql; try{ //注册驱动建立连接 conn = JDBCUtils.getConnection(); sql = "select * from stu where stuid = ?"; ps = conn.prepareStatement(sql); ps.setString(1, stuId); rs = ps.executeQuery(); while(rs.next()){ System.out.println(rs.getObject("STUID")+"\t" + rs.getObject("STUNAME")+"\t" +rs.getObject("SEX")); } }finally{ JDBCUtils.free(rs, ps, conn); } } static int update(int score, String stuId) throws SQLException{ int numOfResult =0; Connection conn = null; PreparedStatement ps = null; String sql; try{ //注册驱动建立连接 conn = JDBCUtils.getConnection(); sql = "update stu set score = ? where STUID= ?"; ps = conn.prepareStatement(sql); ps.setInt(1, score); ps.setString(2, stuId); numOfResult = ps.executeUpdate(); }finally{ JDBCUtils.free(null, ps, conn); } return numOfResult; } static int delete(String stuId) throws SQLException{ int numOfResult =0; Connection conn = null; PreparedStatement ps = null; String sql; try{ //注册驱动建立连接 conn = JDBCUtils.getConnection(); sql = "delete from stu where stuid = ?"; ps = conn.prepareStatement(sql); ps.setString(1, stuId); numOfResult = ps.executeUpdate(); }finally{ JDBCUtils.free(null, ps, conn); } return numOfResult; } static void readSQLInject(String stuId) throws SQLException{ Connection conn = null; Statement st = null; ResultSet rs = null; String sql; try{ //注册驱动建立连接 conn = JDBCUtils.getConnection(); sql = "select * from stu where stuid = '"+stuId+"'"; System.out.println(sql); st = conn.createStatement(); rs = st.executeQuery(sql); while(rs.next()){ System.out.println(rs.getObject("STUID")+"\t" + rs.getObject("STUNAME")+"\t" +rs.getObject("SEX")); } }finally{ JDBCUtils.free(rs, st, conn); } } public static void main(String[] args) throws SQLException { int num = create(); System.out.println("num :"+ num); read("S151208"); int num2 = update(100,"S151201"); System.out.println("num :"+ num2); delete("S151208"); readSQLInject("' or 1=1 or stuid='"); }}
注释: 上面涉及到JDBCUtils类 见博客JAVA-JDBC:(1)中。
- JAVA-JDBC: (2) 数据库的粗略的CRUD及SQL注入问题
- JAVA-JDBC: (1) java连接数据库的粗略步骤
- JDBC访问数据库的过程,sql注入问题预总结
- mysql之jdbc连接数据库和sql注入的问题
- JDBC连数据库及对数据库的CRUD操作
- JDBC进行数据库的CRUD
- 基于Java的JDBC对数据库的CRUD
- JDBC的粗略介绍
- Sql Server 数据库的CRUD
- jdbc对数据库的CRUD操作
- 利用JDBC完成数据库的CRUD
- JAVA-JDBC完成CRUD的操作进阶
- JDBC-SQL注入问题
- JDBC的CRUD示例
- jdbc 连接SQL 2000数据库的问题
- java的UUID类型字段,如何通过jdbc进行数据库的CRUD
- java的UUID类型字段,如何通过jdbc进行数据库的CRUD
- android 数据库用sql语句的 crud
- 输入输出练习
- Date对象
- java时间格式转换
- JNDI
- class文件结构
- JAVA-JDBC: (2) 数据库的粗略的CRUD及SQL注入问题
- 基于opencv31 下的KCF 跟踪在windows 下的测试
- Dom对象
- Linux下MySQL数据库常用基本操作
- Windriver生成cpci驱动程序知识点简单讲解
- Integer,int,String相互转换
- Struts2框架自学之路——拦截器
- 解决VS2015安装后stdio.h ucrtd.lib等文件无法识别问题,即include+lib环境变量配置
- 基于DB的全局唯一id