码迷,mamicode.com
首页 > 编程语言 > 详细

Java年度总复习基础部分(五)

时间:2018-01-06 14:28:55      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:object   print   tms   for   try   set   boolean   false   输入密码   

              JDBC数据库连接

 

1.Jdbc是什么?

我们之前提到了数据库,如何使用java代码来操作数据库呢,程序要通过sql语句来操作数据库库,而必须拥有一个类库,类库提供sql语句的执行方法 jdbc就是因此而产生的,jdbc是java中提供的一个接口 允许程序员通过这个接口来操作数据库。

2.如何使用jdbc来完成数据的增删该查

Jdbc拥有自己的驱动使用前需要加载

  • Jdbc加载驱动获得连接
  • Jdbc执行sql语句
  • Jdbc关闭连接

从连接数据库到操作数据库的详细步骤如下

首先加载驱动程序 class.forname(“com.mysql.jdbc.driver”)加载mysql数据库驱动  需要导入相应的jar包

mysql-connector-java-5.1.7-bin.jar

这里可能会抛出一个异常 就是classnotfoundexception 找不到这个类,我们可以打印出错误信息堆栈。

加载好驱动程序后,就是获得与数据库的连接

Connection conn=null;

conn=DriverManager.getConnection(“jdbc:mysql://localhost/javaweb1?seUnicode=true&characterEncoding=UTF-8”,”root”,”root”);//填入你的数据库的信息,后两个参数为账号和密码

通过PrepareStatement Statement这两个类执行sql语句

PrepareStatement stat=null;

stat=conn.preparestatment(“sql语句”);

 

ResultSet这个类来获取sql语句执行后的结果

ResultSet rs= stat.executequery(“”);//执行

 

如果是更新语句 update等

则务必使用

stat.executeUpdate();

来进行结果的提交 否则无效

最后 在使用完jdbc后 一定要关闭资源!!! 否则数据库的连接过多造成数据库的崩溃

stat.close();

conn.close();

 

相关的代码

获取study1中所有信息 人的姓名 年龄 性别等信息。

技术分享图片
 1 package abc;
 2 import java.sql.Connection;
 3 import java.sql.DriverManager;
 4 import java.sql.PreparedStatement;
 5 import java.sql.ResultSet;
 6 import java.sql.SQLException;
 7 
 8 public class main
 9 {
10 
11     public static void main(String[] args)
12     {
13          try
14          {
15             
16              Class.forName("com.mysql.jdbc.Driver");
17         } 
18         catch (ClassNotFoundException e)
19         {
20             System.out.println("mysql jdbc错误"+e.getMessage());
21             return ;
22         }
23         
24         Connection conn= null;
25         PreparedStatement stmt =null;
26         ResultSet resultSet = null;
27         
28         
29         //DriverManager
30          try
31         {
32            conn=DriverManager.getConnection("jdbc:mysql://localhost/study1?seUnicode=true&characterEncoding=UTF-8","root","root");
33           System.out.println(conn.getClass());
34           stmt = conn.prepareStatement("select * from t_person");
35           resultSet = stmt.executeQuery();
36           while(resultSet.next())
37           {
38               String name = resultSet.getString("Name");
39               int age=resultSet.getInt("Age");
40               boolean gender = resultSet.getBoolean("Gender");
41               System.out.println("名字:"+name+"年龄"+age+"性别"+(gender?"男":"女"));
42           }
43           int i=stmt.executeUpdate();
44 
45         
46         } 
47          catch (SQLException e)
48         {
49             System.out.println(""+e.getMessage());
50         }
51          finally
52          {
53         
54                 JDBCGB.closeQuiety(conn);
55                 JDBCGB.closeQuiety(stmt);
56              
57          }
58             
59         }
60     
61 }
查看代码

 

3.SQL注入漏洞防范

所谓SQL注入,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力

首先来简单演示一下:假设我们通过scanner来模拟用户的登陆

技术分享图片
 1 package zr;
 2 import java.sql.Connection;
 3 import java.sql.DriverManager;
 4 import java.sql.PreparedStatement;
 5 import java.sql.ResultSet;
 6 import java.sql.SQLException;
 7 import java.util.Scanner;
 8  
 9 public class main2
10 {
11  
12 public static void main(String[] args)
13 {
14     Scanner sc = new Scanner(System.in);
15     System.out.println("请输入用户名");
16     String username = sc.nextLine();
17     System.out.println("请输入密码");
18     String password = sc.nextLine();
19     try
20     {
21         Class.forName("com.mysql.jdbc.Driver");
22     } catch (ClassNotFoundException e)
23     {
24         System.out.println("加载驱动失败"+e.getMessage());
25          
26     }
27     Connection conn = null;
28     PreparedStatement ps = null;
29     ResultSet rs = null;
30     try{
31         conn = DriverManager.getConnection("jdbc:mysql://localhost/study1?seUnicode=true&characterEncoding=UTF8", "root", "root");
32         String sql = "select count(*) c from T_Users where UserName=‘"+username+"‘ and PassWord = ‘"+password+"‘";
33         ps = conn.prepareStatement(sql);  
34      /*
35       * 存在注入漏洞   a‘ or ‘a‘=‘a
36       * 需要对其过滤
37       */
38             /*String sql ="select count(*) c from T_Users where UserName=? and PassWord =?";
39          
40         ps = conn.prepareStatement(sql);
41         ps.setString(1, username);
42         ps.setString(2, password);*/
43         rs = ps.executeQuery();
44        rs.next();
45        int c = rs.getInt("c"); 
46        System.out.println(c);         
47         if(c<=0){
48            System.out.println("登录失败");
49             
50        }
51        else{
52           System.out.println("登陆成功");
53        }
54     }catch(SQLException ex){
55         System.out.println("执行数据库出错"+ ex);
56         }
57     finally{
58             JDBCGB.closeQuiety(ps);
59             JDBCGB.closeQuiety(conn);
60             JDBCGB.closeQuiety(rs);
61         }
62         }
63     }
查看代码

技术分享图片

账号随意输入

密码为

a’ or  ‘a’ =’a

都可以登陆成功

其原因是

password的结果永远为true 整个sql语句 也会为true

这样就成功的执行到了sql语句

技术分享图片

3.1如何防范 

上面代码中其实已经注释标记出来了

ps = conn.prepareStatement(sql);

ps.setString(1, username);

ps.setString(2, password);

我们需要对sql语句进行简单的过滤操作

采用 setstring来进行预编译处理

最终实现了系统的安全性

4. JDBC如何取出数据库中的null

5.	Integer iAge = (Integer)rs.getObject("Age");
6.	if(objI==null)
7.	{
8.	    System.out.println("布吉岛呀");
9.	}
10.	else
11.	{
12.	   int age = iAge;

将查询结果包装为一个integer的包装类型,这样integer可以为null

就可以通过程序来进行判断了

5.JDBCUtils工具类

5.1JDBCGB资源关闭

使用该类对资源进行统一的关闭回收。

技术分享图片
 1 package abc;
 2 import java.sql.Connection;
 3 import java.sql.PreparedStatement;
 4 import java.sql.ResultSet;
 5 import java.sql.SQLException;
 6 
 7 //安静的关闭
 8 public class JDBCGB
 9 {
10     public static void closeQuiety(PreparedStatement stmt)
11     {
12         if(stmt!=null)
13         {
14              try
15             {
16                 stmt.close();
17             }
18              
19              catch (SQLException e)
20             {
21             //System.out.println("无法关闭数据流");
22             }
23              }
24              
25         }
26  public static void closeQuiety(Connection conn)
27      { 
28      if(conn!=null)
29      {
30      try
31     {
32         conn.close();
33     } 
34      catch (SQLException e)
35     {
36         // TODO 自动生成的 catch 块
37     //    e.printStackTrace();
38     }
39      }        
40      }        
41 public static void closeQuiety(ResultSet rs)
42 {
43     
44      { 
45      if(rs!=null)
46      {
47      try
48     {
49     rs.close();
50      }
51      
52      catch (SQLException e)
53     {
54     //System.out.println("无法关闭数据流");
55     }
56      
57      }
58 }
59 }
60 
61 }
查看代码

5.2JDBCUtils可变长参数的运用

为什么要使用可变长参数?

如果在数据库的操作中

  String sql  = "select * from admin where username= "+name;

直接使用sql语句来拼接的话

在数据库中会查询出这样一个结果

技术分享图片

由于我们需要将admin加上单引号而 字符串的拼接过程中没有加上单引号造成查询结果出错

抛出sql异常

解决方法有

String sql="select * from admin where username =‘"+name+"‘";

这样来实现数据库的拼接,但是如果每次都这样拼接是不是特别麻烦

所以才需要使用一个参数 为可变长参数,可变长参数可以优化查询使查询传递的参数更多。

技术分享图片
 1 public static ResultSet executeQuery(Connection conn, String sql,
 2         Object... parameters) throws SQLException
 3 {
 4     PreparedStatement ps = null;
 5     try
 6     {
 7         ResultSet rs = null;
 8         ps = conn.prepareStatement(sql);
 9         for (int i = 0; i < parameters.length; i++)
10         {
11             ps.setObject(i + 1, parameters[i]);
12         }
13         rs = ps.executeQuery();
14         return rs;
15     } catch (SQLException ex)
16     {
17         close(ps);
18         throw ex;
19     }
20 }
查看代码

5.3JDBCUtils 通过读取配置文件来获得连接

首先还是定义一个配置文件,名称为config.pro

放在src目录下面

配置文件中定义数据库的详细信息

  • drivername=com.mysql.jdbc.Driver
  • dburl=jdbc:mysql://localhost/study1?seUnicode=true&&characterEcoding=UTF8
  • dbusername=root
  • dbpassword=root

JDBC完整代码,在程序中通过class.forname 来加载到数据库的配置信息

技术分享图片
  1 package com.scetc;
  2 import java.io.IOException;
  3 import java.io.InputStream;
  4 import java.sql.Connection;
  5 import java.sql.DriverManager;
  6 import java.sql.PreparedStatement;
  7 import java.sql.ResultSet;
  8 import java.sql.SQLException;
  9 import java.sql.Statement;
 10 import java.util.Properties;
 11 
 12 public class JDBCGB
 13 {
 14     private static final String drivername;
 15     private static final String dburl;
 16     private static final String dbusername;
 17     private static final String dbpassword;
 18     static 
 19     {    
 20         InputStream instream=null;
 21         
 22         try{
 23         instream = JDBCGB.class.getResourceAsStream("config.pro");
 24         Properties prop = new Properties();
 25      //加载配置文件
 26         prop.load(instream);
 27         drivername=prop.getProperty("drivername");
 28         dburl=prop.getProperty("dburl");
 29         dbusername=prop.getProperty("dbusername");
 30         dbpassword = prop.getProperty("dbpassword");
 31         }
 32         
 33         catch(IOException ex)
 34         {
 35             throw new RuntimeException("config",ex);
 36             
 37         }
 38         finally
 39         {
 40             if(instream!=null)
 41             {
 42                 try
 43                 {
 44                     instream.close();
 45                     
 46                 }catch(IOException e)
 47                 {
 48                     //
 49                     
 50                 }
 51                 
 52             }
 53             
 54             
 55             
 56         }
 57         try
 58         {
 59             Class.forName(drivername);
 60         }
 61         catch (ClassNotFoundException e)
 62         {
 63             throw new RuntimeException("mysql jdbc",e);
 64         }
 65     
 66     }
 67     /**
 68      * 创建数据库的连接
 69      * @return
 70      * @throws SQLException
 71      */
 72     public static Connection createConnection() throws SQLException
 73     {
 74         return DriverManager.getConnection(dburl,dbusername,dbpassword);
 75 
 76     }
 77     public static int executeUpdate(Connection conn,String sql,Object ...parameters)throws SQLException
 78     {
 79         PreparedStatement ps=null;
 80         try
 81         {
 82             ps=conn.prepareStatement(sql);
 83             for(int i=0;i<parameters.length;i++)
 84        {
 85         ps.setObject(i+1, parameters[i]); 
 86 
 87       }
 88      return ps.executeUpdate();
 89         }
 90  finally
 91  {
 92         closeQuiety(ps);    
 93  }    
 94     }
 95     /**执行sql语句并且
 96      * 获得数据库的返回值
 97      * @param conn
 98      * @param sql
 99      * @param parameters
100      * @return
101      * @throws SQLException
102      */
103     public static ResultSet executeQuery(Connection conn,String sql,Object...parameters)throws SQLException
104     {
105         PreparedStatement ps=conn.prepareStatement(sql);
106      for(int i=0;i<parameters.length;i++)
107      {
108          ps.setObject(i+1, parameters[i]);
109          
110      }
111         
112         
113         return ps.executeQuery();
114         
115         
116     }
117     /**
118      * 执行sql语句更新操作
119      * @param sql
120      * @param parameters
121      * @return
122      * @throws SQLException
123      */
124     public static int executeUpdate(String sql,Object...parameters)throws  SQLException
125     {
126         Connection conn=null;
127         try
128         {
129             conn = createConnection();
130             return executeUpdate(conn,sql,parameters);
131         }
132         finally
133         {
134             closeQuiety(conn);
135         }
136         
137     }
138     public static ResultSet executeQuery(String sql,Object...parameters)throws  SQLException
139     {
140         Connection conn =createConnection();
141         
142         return executeQuery(sql, parameters);
143         
144         
145         
146     }
147     /**
148      * 关闭操作
149      * @param rs
150      */
151    public static void closeAll(ResultSet rs)
152    {
153        Statement stmt =null;
154        Connection conn =null;
155        try
156        {
157            stmt=rs.getStatement();
158            conn=stmt.getConnection();
159        }
160        catch (SQLException e)
161     {
162     }
163        finally
164        {
165            JDBCGB.closeQuiety(rs);
166            JDBCGB.closeQuiety(stmt);
167            JDBCGB.closeQuiety(conn);
168            
169        }
170        
171    }
172     public static void closeQuiety(Statement stmt)
173     {
174         if(stmt!=null)
175         {
176              try
177             {
178                 stmt.close();
179             }
180              
181              catch (SQLException e)
182             {
183             }
184              }
185              
186         }
187   public static void closeQuiety(Connection conn)
188      { 
189      if(conn!=null)
190      {
191      try
192     {
193         conn.close();
194     } 
195      catch (SQLException e)
196     {
197     }
198      }        
199      }
200 
201 public static void closeQuiety(ResultSet rs)
202 {
203     
204      { 
205      if(rs!=null)
206      {
207      try
208     {
209     rs.close();
210      }
211      
212      catch (SQLException e)
213     {
214     }
215      
216      }
217 }
218 }
219 
220 }
查看代码

5.4JDBCUtils事务

事务有四大特性:原子性,隔离性,一致性,持久性

在这里只说到事务的原子性

原子性:要么全部提交成功 , 要么全部失败

Jdbc中需要用到的就是事务的原子性commit 和 rollback

提交和回滚操作

事务相关测试代码

技术分享图片
 1 public static void main(String [] args)
 2  {
 3      Connection conn = null;
 4      ResultSet rs=null;
 5      try
 6      {
 7          conn=JDBCGB.createConnection();
 8          conn.setAutoCommit(false);
 9          JDBCGB.executeUpdate(conn, "Update t_abc set Amout=Amount-1000, where  Number=‘0001");
10         /* String s=null;
11          System.out.println(s.length());*/
12          //如果在这里报错 则不会执行下一段代码
13          //这样整个就会出错
14          /*
15           * 原子性,一致性,隔离性,持久性
16           */
17     JDBCGB.executeUpdate(conn, "Update t_abc set Amout=Amount+1000, where  Number=‘0002");
18          conn.commit();         
19      }
20      catch(SQLException e)
21      {
22          e.printStackTrace();
23          conn.rollback();
24      }
25      
26      finally
27      {
28          JDBCGB.closeQuiety(conn);
29          
30          
31      }
32 }
查看代码

如果抛出异常,一些常见的错误,则提交失败 事务回滚 。更新的数据也会从其中消失。常用于数据敏感的地方,比如银行系统等交易地方。

5.4addBatch批量提交

如果在事务中,想要一次性提交多组数据,则可以使用addBatch批量提交,它配合于事务的基本条件,一旦其中一步出现异常则数据全部回滚,不会修改数据库。

一次性向数据库提交多组数据 通常都是上千条数据一起插入

技术分享图片
 1 package com.scetc;
 2 
 3 import java.sql.Connection;
 4 import java.sql.PreparedStatement;
 5 import java.sql.ResultSet;
 6 import java.sql.SQLException;
 7 import java.sql.Statement;
 8 
 9 import javax.naming.spi.DirStateFactory.Result;
10 
11 public class TEST5
12 {
13  public static void main(String [] args)
14  {
15      Connection conn = null;
16      ResultSet rs=null;
17      PreparedStatement ps=null;
18      try
19      {
20          ps = conn.prepareStatement("Insert into              T _Persons(Name,Age,Gender) values(?,?,?)");
21          long startMS = System.currentTimeMillis();
22          for (int i = 0; i < 10000; i++)
23          {
24              ps.clearParameters();
25              ps.setString(1, "xyf" + i);
26              ps.setInt(2, i);
27              ps.setBoolean(3, true);
28              ps.executeUpdate();
29          }
30          long endMS = System.currentTimeMillis();
31          System.out.println("耗时:" + (endMS - startMS));
32      
33 
34          conn.commit();         
35      }
36      catch(SQLException e)
37      {
38          e.printStackTrace();
39          
40      }
41      
42      finally
43      {
44          JDBCGB.closeQuiety(conn);
45          
46          
47      }
48      
49      
50      
51  }
52 }
查看代码

5.5last_insert获取刚插入的自增字段

技术分享图片
 1 Connection conn = null;
 2 ResultSet rs = null;
 3 try
 4 {
 5 conn = JdbcUtils.createConnection();
 6 JdbcUtils.executeUpdate(conn, "insert into t_users(UserName,Password) values(‘1‘,‘1‘)");
 7 rs = JdbcUtils.executeQuery(conn, "select last_insert_id() id");
 8 rs.next();
 9 long id = rs.getLong("id");
10 System.out.println(id);
11 }
12 catch(SQLException ex)
13 {
14 
15 }
16 finally
17 {
18 JdbcUtils.closeAll(rs);
19 }
查看代码

                

 

                                                                                                                                                                                             2018-01-06  11:30:02 

Java年度总复习基础部分(五)

标签:object   print   tms   for   try   set   boolean   false   输入密码   

原文地址:https://www.cnblogs.com/a986771570/p/8213729.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!