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

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

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

时间: 2024-10-19 10:22:51

Java年度总复习基础部分(五)的相关文章

Java面向对象总复习-QuickHit

1.创建玩家级别类Level.java 1 package com.bdqn; 2 /** 3 * 1.玩家级别类 4 * @author pc 5 * 6 */ 7 public class Level { 8 /** 9 * 级别号 10 */ 11 private int levelNo; 12 /** 13 * 各级别一次输出字符串的长度 14 */ 15 private int strLength; 16 /** 17 * 各级别输出字符串的次数 18 */ 19 private in

EF6 在原有数据库中使用 CodeFirst 总复习(五、生成发帖页面)

有点与在原有数据库中使用 CodeFirst 远了,不过是总复习吗,总得全面点. 一.在用户表(Users)中插入两个用户 二.生成发帖界面 MVC生成的界面很多,也没使用Ajax,实际开发中很少会使用,这里只是为了演示. 但无论用什么生成,特性.实体对象等都是要用到的. 生成之前要编译一下. 三.先试试看能不能运行 空空如也 应该显示用户名,显示成登陆名了(其实预想的是不在新增和修改时显示,未考虑到列表),删除标记怎么也显示出来了,还有内容,能显示的下吗... 四.列显示问题 让列表显示用户,

Java web基础总结五之—— HttpServletRequest与HttpServletResponse

Java web基础总结五之-- HttpServletRequest与HttpServletResponse 在前面总结过,每当客户端给Web服务器发送一个http请求,web服务器就会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象.request和response对象就代表请求和响应,所以我们可以通过request对象获得请求相关的数据和操作.通过response对象进行对响应相关的数据封装和一些其他的操作. 一.HttpServletRequ

Android核心基础第五天

一.学习目标及要求 课程目标 课程内容(必须讲的内容,就是讲课的知识点的顺序) * 掌握Activity 配置 * 掌握 Intent 显示意图 * 掌握 Intent 隐式意图 * 掌握两种意图的使用场景 * 掌握 activity 开启的数据传递 * 掌握activity的生命周期 * 掌握横竖屏切换的生命周期 * 掌握不同android版本 生命周期的细微差别 * 掌握开启activity获取返回值 * 掌握请求码 结果码的作用 * 掌握程序入口activity配置参数 * 掌握显示意图 

Java多线程完整版基础知识

Java多线程完整版基础知识 (翟开顺由厚到薄系列) 1.前言 线程是现代操作系统中一个很重要的概念,多线程功能很强大,java语言对线程提供了很好的支持,我们可以使用java提供的thread类很容易的创建多个线程.线程很不难,我对之前学习过的基础,在这做了一个整理,本文主要参考的是Java研究组织出版的j2se进阶和张孝祥-java就业培训教材这两本书 2.概述 2.1线程是什么 主要是线程与进程的区别,这里不再阐述,自行网上搜索 为什么使用线程:操作系统切换多个线程要比调度进程在速度上快很

平面设计 计算机基础知识教程 Excel2010基础教程 Word2010基础教程 PPT2010基础教程 五笔打字视频教程

热门推荐电脑办公计算机基础知识教程 Excel2010基础教程 Word2010基础教程 PPT2010基础教程 五笔打字视频教程 Excel函数应用教程 Excel VBA基础教程 WPS2013表格教程 更多>平面设计PhotoshopCS5教程 CorelDRAW X5视频教程 Photoshop商业修图教程 Illustrator CS6视频教程 更多>室内设计3Dsmax2012教程 效果图实例提高教程 室内设计实战教程 欧式效果图制作实例教程 AutoCAD2014室内设计 Aut

Java回顾之Spring基础

第一篇:Java回顾之I/O 第二篇:Java回顾之网络通信 第三篇:Java回顾之多线程 第四篇:Java回顾之多线程同步 第五篇:Java回顾之集合 第六篇:Java回顾之序列化 第七篇:Java回顾之反射 第八篇:Java回顾之一些基础概念 第九篇:Java回顾之JDBC 第十篇:Java回顾之ORM框架 我计划分两到三篇文章来描述Spring,这一篇主要讲Spring一些基础的内容. 概述 我印象4.5年前,我还做java开发的时候,Spring是一个非常火的框架,尤其是在Web开发领域

java集合框架复习(一)

数组类Array是java中最基本的一个存储结构,它用于存储 一组连续的对象或一组类型相同的基本类型的数据. Array特点:效率高,但容量固定且无法动态改变, 缺点:无法判断其中存有多少元素,length只是告诉我们Array的容量. Arrays类: 专门用来操作Array,提供搜索,排序,复制等 静态方法. Arrays中equals():比较两个Array是否相等,Array拥有相同元素个数,且所有对应元素两两相等. fill():将值填入Array中. sort():用来对Array进

java集合框架复习

数组类Array是java中最基本的一个存储结构,它用于存储 一组连续的对象或一组类型相同的基本类型的数据. Array特点:效率高,但容量固定且无法动态改变, 缺点:无法判断其中存有多少元素,length只是告诉我们Array的容量. Arrays类: 专门用来操作Array,提供搜索,排序,复制等 静态方法. Arrays中equals():比较两个Array是否相等,Array拥有相同元素个数,且所有对应元素两两相等. fill():将值填入Array中. sort():用来对Array进