数据库三范式
1NF:每一列不可再分。
2NF:非主属性非部分依赖于主关键字。(针对单个表来说的)
3NF:属性不依赖于其他非主属性。(针对多个表来说的)
分页查询
Oracle:
startNum = (pageNow-1)*pagesize+1; endNum = pageNow*pageSize;
select * from (select t.*, rownum rn from (select * from table) t where rownum <= endNum) where rn > =startNum;
Mysql:
start = (pageNow-1)*pageSize;
select * from table where id limit start,pagesize; 或者:
select * from table limit start,pageSize;
hq查询:
Query query = getSessionFactory().getCurrentSession().createQuery(hql);
query.setFirstResult((pageNo - 1) * pageSize);
query.setMaxResults(pageSize);
使用子查询创建新的表
acid(数据库事务正确执行的四个基本要素的缩写)
原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。
数据库事务隔离级别
1幻读:重点是插入和删除,前后纪录数不一致。
2不可重复读:重点是修改了刚才查询的语句。
3脏读:事务T1更新了一行数据,还未提交,事务T2读取了更新后的数据。然后T1又由于回滚,没有跟新数据,所以T2读取的行就无效。也就是脏读。
为了处理这些问题,SQL标准定义了以下几种事务隔离级别
READ UNCOMMITTED 幻想读、不可重复读和脏读都允许。
READ COMMITTED 允许幻想读、不可重复读,不允许脏读
REPEATABLE READ 允许幻想读,不允许不可重复读和脏读
SERIALIZABLE 幻想读、不可重复读和脏读都不允许
Oracle数据库支持READ COMMITTED 和 SERIALIZABLE这两种事务隔离级别。所以Oracle不支持脏读
也就是两个事务,并发执行,事务T2看不到事务T1的跟新操作,读到的数据还是未修改前的数据。
SQL标准所定义的默认事务隔离级别是SERIALIZABLE,但是Oracle 默认使用的是READ COMMITTED
设置隔离级别使用 SET TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]
Oracle中rownum,rowid的区别
rownum是在得到结果集时产生的,用于标记结果集中结果顺序的一个字段,他是逻辑上的伪列,而rowid是对应每一行数据的,是物理上的伪列。rownum从1开始,而rowid是一个长度为18的字符串,一般不会改变。
比较Statement与PreparedStatement
1、PreparedStatement预编译好sql,只需通过ps.set(1,String)将参数传给预编译好的sql,这样对于批量处理相同的sql效率就会高一些,因为如果再次执行同样的sql语句,数据库不会再从新编译sql,而是调用在数据库中缓存了的sql。PreparedStatement还专门提供了addBatch(),executeBatch()处理批量操作。
2、使用PreparedStatement不会让你传入的语句和原有的语句发生任何匹配,防止了sql注入。
什么是sql injection
就是把sql写入表单提交或域名请求查询的字符串
怎么防止sql injection
对用户输入进行校验,如使用正则表达式,限制长度,对单引号和双引号进行转换
不要使用动态拼装的sql,使用参数化的sql或调用存储过程
不要使用管理员权限连接数据库
不要把机密信息明文存放
异常信息尽可能少的提示,最好使用自定义的错误信息对原错误信息进行包装,并把异常信息存放在独立的表中