发表于: 2017-10-16 21:20:07

1 891


今日完成的事情:


1;预编译preparestatement执行sql语句,这个用起来更方便,虽然原理看不是很透彻,不过用起来没问题;

String sql = "insert into student (id,name,study_id,qq)values(null,?,?,?)";
try (Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/task1?characterEncoding=UTF-8", "root", "1234");
    
//创建预编译对象ps
    
PreparedStatement ps  = c.prepareStatement(sql))
{  
//设置参数,
   
ps.setString(1,"理查德");
   
ps.setInt(2,2691);
   
ps.setInt(3,3658);
   
ps.execute();


优点1;就是Statement 需要进行字符串拼接,可读性和维护性比较差;昨天是试的确实很差。。。使用参数设置,可读性好,不易犯错,很棒。

优点2;就是预编译有预编译机制,性能比Statement更快,比如说Statement执行10次,需要10次把SQL语句传输到数据库端,而数据库要对每一次来的SQL语句进行编译处理;换到预编译的PreparedStatement 执行10次,只需要1次把SQL语句传输到数据库端,数据库对?????SQL进行预编译,每次执行,只需要传输参数到数据库端,这样传送量小,编译次数少,反应快。

优点3;防止sql注入风险,这个比较难理解,不是很透彻,大致原理是还涉及到sql语句的执行机制,简单理解记一下就是,假如说写了一段SQL 用来表示查找密码是a的,用户名是b的所有用户的数量。那么,通过注入SQL,就是加上1=1这种恒成立的,那么SQL表示的含义是就变成,查找(密码是a的,并且用户名是b的,) 或者1=1 的所有用户的数量。那么语意就发生跟变化了,而在预编译机制里,多了一个重用执行计划的机制,这个不理解了,就是这个功能会重新编译sql语句,进行解析过滤最终保持语意不变,这样执行后的sql就是,最初设计好的而不是注入后的。

找教程对比一下看看;

// 假设name是提交来的数据
String name = "'杜大大' OR 1=1";
String sql1 = "select * from student where name = " + name;
// 拼接出来的就是select * from hero where name = '杜大大' OR 1=1恒成立,所以数据都会被查出来
// 这就是注入攻击,改变了sql语意,数据多的话会让数据库负载变高,占内存,响应慢
System.out.println(sql1);
ResultSet rs1 = s.executeQuery(sql1);
while (rs1.next()) {
   
String myName = rs1.getString("name");
   
System.out.println("这是statement的:" + myName);
}
s.execute(sql1);
//用预编译preparestatement来做对比
ps.setString(1, name);
ResultSet rs2 = ps.executeQuery();
// 有个重新编译机制,过虑掉注入,查不出数据出来
System.out.println(sql2);//SQL语句没变化,
while (rs2.next()) {
   
String myName = rs2.getString("name");
   
System.out.println("这是preparestatement" + myName);
}

这是拼接的sql语句,传入之后直接执行,语意是被注入的,数据会全部出来

这是预编译的,有个重新编译过程,不符合语意的被过滤掉,这里有个问题就是,我改成正常的,也查不到数据。。。。百度说是预编译会对字符进行转译的样子,暂时不深究了,先mark

 


2;学习事物机制,简单学习,也算是sql的延伸吧,那天听大佬讲课,用的多,具体概念就不水了,简单理解就是,处于同一个事物内的操作,要么同时成功,要么同时失败;这也很好理解,就像银行转账,假如说没有事物机制,那么转账给别人,就会出现钱扣除了,但是没有转账成功。有事物的话,不管扣除还是转到其他账户,这两步操作有一个出现问题就会失败。再举一个栗子,一个是 结账,一个是打印账单。这两个事情必须都要成功,才算是结账成功,否则认为失败。

反应到代码的话就是,对同一条数据进行加减操作来对比看,有无事物操作的结果;这里有一个前提就是数据库里的表必须是innodb类型

下面就是神奇的事情;同时给字段qq加减1,但是减1的语法写错误,看一下结果

     Statement s = c.createStatement())
{  
//qq1
   
String sql1 = "update student set qq = qq+1 where id = 50";
   
s.execute(sql1);
   
//qq-1,这里的update写错了写成updata。。。。
   
String sql2 = "updata student set qq = qq-1 where id = 50";
   
s.execute(sql2);

即使语法报错,但是第一条执行的sql已经成功加1

我想着看一下如果前面的sql语句写错,那后面减一的会不会出错?果然不行,看来不仅与事物机制有关,前面的语法错误也会直接导致后续中断,是映到转账上,运气好的话也相当与准事物机制了。。。

下面验证事物机制,在上面加1成功的基础上来,添加事物机制对比;通过 c.setAutoCommit(false);关闭自动提交,和使用 c.commit();进行手动提交,加上事物机制,没毛病,数据没变。(这里还应该牵涉到提交失败的事物回滚,暂时放一放,大概就是有一个环节没有完成,就必须回滚掉之前的数据库操作);另一方面就是手动提交与自动提交,也是简单理解吧,前者负责逻辑操作,以及整体完成状况;后者只管数据库操作,走一步算一步。因此加上手动提交事物的话整个任务完成,就完成,中间任何一个环节出错 就等于什么都没做。

总结的话就一句话吧:事务的一致性原则保证了要么都成功,要么都失败,所以在同一个事务里的任何操作失败,其他操作都不会生效。


3;学习理解orm,然后思考封装原理编写DAO

ORM这里解释学习一下,后续的学习似乎给这个关联很大,Object Relationship Database Mapping对象和关系数据库的映射,简单说,一个对象,对应数据库里的一条记录;代码的话几乎也是jdbc的,主要增加一个student类附上属性信息,再在方法里import;还有就是返回的是对象,因此循环while换成if;百度了一下简单理解,while是用来做循环的,也就是说只要条件满足,就会执行一次循环体,执行完以后会再判断一次条件,如果满足条件,还会再执行一次,终而复始;而if只做一次判断,条件不满足就不执行,满足就执行一次,执行完就往下执行,不会再回过头来继续执行。

    {
       
String sql = "select *from student Where id = " + id;
       
ResultSet rs = s.executeQuery(sql);
       
if (rs.next()) {
            st
= new Student();
           
String name = rs.getString(2);
           
int study_id = rs.getInt(3);
           
int qq = rs.getInt(4);
            
st.id = id;
           
st.name = name;
           
st.qq = qq;
           
st.study_id = study_id;
       
}
    }
catch (SQLException e) {
       
e.printStackTrace();
   
}
   
return st;
}
public static void main(String[] args)
{
   
Student w = get(50);
   
System.out.println(w.id + " " + w.name + " " + w.study_id + " " + w.qq);

 

这里注意的话就是,写好的student不能放在同一包里,不然会报错。。。


4;Dao的编写,dao的接口有方法,然后去实现,具体比较麻烦,没有完全解决,明天继续




明日计划的事情:

1;学习并完成mybatis的相关内容

2;完成今天遗留问题dao

2;做师兄的jdbc小例子


遇到的问题及解决方法:

1;概念虽然看了一遍,但是理解不到位,往往用到的时候还需要再百度

2;操作的话,都能跑通,只是某些点get不到,还是基础薄弱的弱,循环都要百度一下。。。


收获:

1jdbc的操作基本上了解了,可以根据自己的students表跑通代码,理解流程

2初步接触dao的编写,感觉抽象,再磨一下


 

 



返回列表 返回列表
评论

    分享到