好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

详解Java基础知识——JDBC

jdbc

java database connectivity,java数据库连接,为了降低操作数据的难度,java提供jdbc,按照java面向对象特点,对操作进行了很多封装。

jdbc提供了很多接口,然后不同数据库厂商去实现这个接口,到底底层如何去实现,不同的数据库不一样,不同的数据库厂商需要提供接口实现类(驱动类、驱动程序 driver、驱动)

我们连接不同的数据库,我们只需要使用不同的驱动即可。

j:java:提供访问数据库的规范(接口),

dbc:接口的实现,厂商去实现这个接口。

jdbc是一种用于执行sql语句的java api.

版本号

1.1.1 major. minor. build

major:项目由架构、大规模的变化

minor:有新功能的时候

build:编译版本

jdbc开发

java程序使用第三方提供工具框架,都需要导入jar包

可以通过以下网址搜索找到mysql的相关jar包

https://mvnrepository测试数据/

下载好jar包后,在于src同级的目录下,建立一个lib文件夹,添加jar包,并添加依赖

代码实现

通过一个简单的案例来实现jdbc的使用

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

import java.sql.*;

 

public class demo02 {

   public static void main(string[] args) throws classnotfoundexception, sqlexception {

     //1注册驱动

     class .forname( "com.mysql.jdbc.driver" );

     //2建立连接

     string url = "jdbc:mysql://localhost:3306/mydb01" ;

     string usernname = "xxx" ; //登录数据库的账号

     string password = "xxxx" ; //登录数据库的密码

     connection conn = drivermanager.getconnection(url, usernname, password);

     //3获取执行sql语句的对象

     statement statement = conn.createstatement();

     //4获取数据库返回的结果

     string sql = "delete from emp where empno = " + "7499" ;

     string sqlupdate = "update emp set sal = " + 10000 + " where empno = " + "7369" ;

  

     string sqlinsert = "insert into emp values( 2018 ,\"boss\",\"king\", null ,\" 2018 - 8 -

               8 \ ",15000,10000,10);" ;

 

     //5处理数据集

     int i = statement.executeupdate(sql);

     int s = statement.executeupdate(sqlupdate);

     int ins = statement.executeupdate(sqlinsert);

     system.out.println(i + "行受到影响----删除" );

     system.out.println(s + "行受到影响----更新" );

     system.out.println(ins + "行受到影响----插入" );

     //6关闭连接

 

     statement.close();

     conn.close();

 

 

   }

}

使用jdbc的顺序

(1)注册数据库驱动 (2)和数据库建立连接 (3)获取执行sql语句的对象 (4)获取数据库返回的结果 (5)处理数据集(逻辑代码) (6)释放资源,关闭连接

常用类

connection

通过配置文件可以创建一个connect对象

statement

通过connect对象获取操作数据库的statement对象, 通过它来实现对数据库增删改查操作。 executequery():查,返回数据集 executeupdate():增删改,返回int的数据,影响的行数

resultset

数据集,可以理解就是一个集合。

取出数据:

通过下标:从1开始 通过字段名:sql语句中select后面跟的字段,有可能和数据库一样,也可能不一样

jdbc的优化

平时开发和项目上线之后使用的数据库是不一样的,不是同一个

这也就是我们说的,开发环境不一样

开发环境不一样,使用的数据库也就不一样,那么上面的数据库中配置的三要素就要进行修改

而这种修改是人工操作的,人工操作就有存在了失误,而修改之后的.java文件,也要重新编译,这也可能出现错误

假设项目上线,需要以下四个步骤:

测试环境-->修改配置 -->重新编译-->生产环境

如果想要避免上述出现的失误的情况,就要绕开中间的两个步骤

解决的方法就是,配置文件,添加配置文件,将要修改的配置信息存放到配置文件中,每次读取信息从配置文件中读取

而配置文件的位置是固定的,也不会重新编译,这样就可以降低风险

java中用io流也可以读取配置文件,通过一个专有的类properties也可以读写配置文件

io读取配置文件

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

import java.io.bufferedreader;

import java.io.filereader;

import java.io.ioexception;

import java.sql.*;

import java.util.properties;

 

public class ioreadprop {

   public static void main(string[] args) throws classnotfoundexception, sqlexception, ioexception {

     //1注册驱动

     class .forname( "com.mysql.jdbc.driver" );

     string[] para = read();

    

     //2建立连接

     string url = para[ 0 ];

     string usernname = para[ 1 ];

     string password = para[ 2 ];

     connection conn = drivermanager.getconnection(url,usernname,password);

    

     //3获取执行sql语句的对象

     statement statement = conn.createstatement();

    

     //4获取数据库返回的结果

     string sql = "select * from emp" ;

     resultset resultset = statement.executequery(sql);

 

     //5处理数据集

     try {

       while (resultset.next()){

         //.getxxx方法中的参数 1,字段名 2.字段的下标

         int empno = resultset.getint( "empno" );

         string ename = resultset.getstring( "ename" );

         string job = resultset.getstring( 3 );

         date date = resultset.getdate( 5 );

         system.out.println( "empno:" +empno+ ", ename:" +ename+ ", job:" +job+ ", date:" +date);

       }

     }

     catch (exception e){

       e.printstacktrace();

     }

     finally {

       //6关闭连接

       resultset.close();

       statement.close();

       conn.close();

     }

   }

 

   public static string [] read() throws ioexception {

     filereader fr = new filereader( "e:\\javalearning\\src\\jdbc\\jdbc.properties" );

     //创建 写入 缓冲区

     bufferedreader bufferedreader = new bufferedreader( fr );

     string [] str = new string[ 3 ];

     for ( int i = 0 ;i < 3 ;i++){

       str[i] = bufferedreader.readline().split( "=" )[ 1 ].replace( ";" , "" ).trim();

     }

     bufferedreader.close();

     fr.close();

     return str;

   }

}

properties读取配置文件

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

import java.io.*;

import java.sql.*;

import java.util.iterator;

import java.util.properties;

 

public class propreadprop {

   public static void main(string[] args) throws classnotfoundexception, sqlexception, ioexception {

     //1注册驱动

     class .forname( "com.mysql.jdbc.driver" );

     //用户数组存放数据库信息

     string[] para = new string[ 3 ];

 

 

     //读取配置文件

     int i = 0 ;

     properties prop = new properties();

     fileinputstream fileinputstream = new fileinputstream( "e:\\javalearning\\src\\jdbc\\jdbc.properties" );

     inputstream in = new bufferedinputstream(fileinputstream);

     prop.load(in);

     iterator<string> it = prop.stringpropertynames().iterator();

     while (it.hasnext()) {

       para[i] = prop.getproperty(it.next());

       i++;

     }

     in.close();

     //2建立连接

     string url = para[ 0 ];

     string usernname = para[ 1 ];

     string password = para[ 2 ];

     connection conn = drivermanager.getconnection(url, usernname, password);

 

     //3获取执行sql语句的对象

     statement statement = conn.createstatement();

 

     //4获取数据库返回的结果

     string sql = "select * from emp" ;

     resultset resultset = statement.executequery(sql);

 

     //5处理数据集

     try {

       while (resultset.next()) {

         //.getxxx方法中的参数 1,字段名 2.字段的下标

         int empno = resultset.getint( "empno" );

         string ename = resultset.getstring( "ename" );

         string job = resultset.getstring( 3 );

         date date = resultset.getdate( 5 );

         system.out.println( "empno:" + empno + ", ename:" + ename + ", job:" + job + ", date:" + date);

       }

     } catch (exception e) {

       e.printstacktrace();

     } finally {

       //6关闭连接

       resultset.close();

       statement.close();

       conn.close();

     }

   }

}

分层dao

data access object数据访问对象是一个面向对象的数据库接口

会建立一个包:dao,里面的类都是用来操作数据库的。

通常情况下,有几张表,就有几个dao

分层entity、bean、pojo

实体,也就是一个一个类,该类里面只有属性,和对应set.get方法

往往一个表一个实体,实体的属性和表的字段有没有关系,名字一般一样,类型相对应

使用逆向工程,通过表导出实体。

utils 工具类

代替我们去操作一系列的连接关闭等操作

案例:

目录结构如下,

empdao代码如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

package jdbc.dao;

 

 

import jdbc.entity.emp;

import jdbc.utils.jdbcutils;

 

import java.sql.connection;

import java.sql.resultset;

import java.sql.sqlexception;

import java.sql.statement;

 

public class empdao {

 

   /**

    * 根据员工id获取员工信息

    */

   public emp getempbyid(integer id){

     connection connection = null ;

     statement statement = null ;

     resultset rs = null ;

     emp emp = null ;

 

     try {

       connection = jdbcutils.getconnection();

       statement = connection.createstatement();

       rs = statement.executequery( "select * from emp where empno='" +id+ "'" );

 

       while (rs.next()){

         emp = new emp();

         int empno = rs.getint( "empno" );

         emp.setempno(empno);

 

         string ename = rs.getstring( "ename" );

         emp.setename(ename);

 

         string job = rs.getstring( 3 );

         emp.setjob(job);

 

         string hiredate = rs.getstring( 5 );

         emp.sethiredate(hiredate);

       }

 

     } catch (sqlexception e) {

       e.printstacktrace();

     }

     finally {

       jdbcutils.close(connection,statement,rs);

     }

     return emp;

   }

 

   public emp getempbyid(string id){

     connection connection = null ;

     statement statement = null ;

     resultset rs = null ;

     emp emp = null ;

 

     try {

       connection = jdbcutils.getconnection();

       statement = connection.createstatement();

       rs = statement.executequery( "select * from emp where empno=" +id);

 

       while (rs.next()){

         emp = new emp();

         int empno = rs.getint( "empno" );

         emp.setempno(empno);

 

         string ename = rs.getstring( "ename" );

         emp.setename(ename);

 

         string job = rs.getstring( 3 );

         emp.setjob(job);

 

         string hiredate = rs.getstring( 5 );

         emp.sethiredate(hiredate);

       }

 

     } catch (sqlexception e) {

       e.printstacktrace();

     }

     finally {

       jdbcutils.close(connection,statement,rs);

     }

     return emp;

   }

}

entity中的emp代码如下

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

package jdbc.entity;

 

public class emp {

   //emp表中的相关属性

   private integer empno;

   private string ename;

   private string job;

   private string mgr;

   private string hiredate ;

   private double sal;

   private double comm;

   private integer deptno;

 

   public integer getempno() {

     return empno;

   }

 

   public void setempno(integer empno) {

     this .empno = empno;

   }

 

   public string getename() {

     return ename;

   }

 

   public void setename(string ename) {

     this .ename = ename;

   }

 

   public string getjob() {

     return job;

   }

 

   public void setjob(string job) {

     this .job = job;

   }

 

   public string getmgr() {

     return mgr;

   }

 

   public void setmgr(string mgr) {

     this .mgr = mgr;

   }

 

   public string gethiredate() {

     return hiredate;

   }

 

   public void sethiredate(string hiredate) {

     this .hiredate = hiredate;

   }

 

   public double getsal() {

     return sal;

   }

 

   public void setsal( double sal) {

     this .sal = sal;

   }

 

   public double getcomm() {

     return comm;

   }

 

   public void setcomm( double comm) {

     this 测试数据m = comm;

   }

 

   public integer getdeptno() {

     return deptno;

   }

 

   public void setdeptno(integer deptno) {

     this .deptno = deptno;

   }

 

   //默认输出方法

 

   @override

   public string tostring() {

     return "emp{" +

         "empno=" + empno +

         ", ename='" + ename + '\ '' +

         ", job='" + job + '\ '' +

         ", mgr='" + mgr + '\ '' +

         ", hiredate='" + hiredate + '\ '' +

         ", sal=" + sal +

         ", comm=" + comm +

         ", deptno=" + deptno +

         '}' ;

   }

}

utils中的jdbcutils代码如下

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

package jdbc.utils;

 

import java.io.bufferedinputstream;

import java.io.fileinputstream;

import java.io.ioexception;

import java.io.inputstream;

import java.sql.*;

import java.util.iterator;

import java.util.properties;

 

public class jdbcutils {

 

   private static final string url ;

   private static final string username ;

   private static final string password ;

 

   static {

     string [] parp = null ;

     try {

       parp = propread();

     } catch (ioexception e) {

       e.printstacktrace();

     }

     url = parp[ 0 ];

     username = parp[ 1 ];

     password=parp[ 2 ];

     try {

       class .forname( "com.mysql.jdbc.driver" );

     } catch (classnotfoundexception e) {

       e.printstacktrace();

     }

   }

 

 

   /**

    * 创建连接

    */

 

   public static connection getconnection() throws sqlexception {

     connection conn = drivermanager.getconnection(url, username, password);

     return conn;

   }

 

   public static void close(connection co , statement state, resultset rs){

     if (rs != null ){

       try {

         rs.close();

       } catch (sqlexception e) {

         e.printstacktrace();

       }

     }

 

     if (state != null ){

       try {

         state.close();

       } catch (sqlexception e) {

         e.printstacktrace();

       }

     }

 

     if (co != null ){

       try {

         co.close();

       } catch (sqlexception e) {

         e.printstacktrace();

       }

     }

   }

 

 

   public static void close(connection co , statement state){

 

 

     if (state != null ){

       try {

         state.close();

       } catch (sqlexception e) {

         e.printstacktrace();

       }

     }

 

     if (co != null ){

       try {

         co.close();

       } catch (sqlexception e) {

         e.printstacktrace();

       }

     }

   }

 

   /**

    * 读取配置文件

    * @return

    * @throws ioexception

    */

   public static string [] propread() throws ioexception {

     string[] para = new string[ 3 ];

     int i = 0 ;

     properties prop = new properties();

     fileinputstream fileinputstream = new fileinputstream( "e:\\javalearning\\src\\jdbc\\jdbc.properties" );

     inputstream in = new bufferedinputstream(fileinputstream);

     prop.load(in);

     iterator<string> it = prop.stringpropertynames().iterator();

     while (it.hasnext()) {

       para[i] = prop.getproperty(it.next());

       i++;

     }

     in.close();

     return para;

   }

 

}

测试代码如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

package jdbc;

 

import jdbc.dao.empdao;

import jdbc.entity.emp;

 

import java.util.scanner;

 

public class main {

   public static void main(string[] args) {

     empdao empdao = new empdao();

     system.out.println( "请输入id" );

     scanner scanner = new scanner( system.in );

     string value = scanner.nextline();

     emp emp = empdao.getempbyid (value);

     emp emp1 = empdao.getempbyid ( 7900 );

     system.out.println(emp);

     system.out.println(emp1);

   }

}

这样就简单实现了一个分层的使用jdbc的案例

sql注入攻击

根据上述案例,我们可以输入一个员工的id来查找该员工

但是有一个问题,你如何去规定用户的输入,下面给大家看一个现象

我的数据库在中并没有123456789这个id的人,那么为什么还会有结果呢?

就是因为我们的sql语句是根据字符串拼接生成的,当你输入的数据中包含sql关键字时,会被当成sql语句去执行

注意:这是很危险的!

不友好的用户可以根据这个漏洞对你的数据库进行修改,甚至删除你的数据库!

解决方法:preparedstatement类

preparedstatement是statement的子类

解决原理:

sql语句不在拼接,而是通过预处理,也就是说,用户输入的任何内容,都只能作为值,不解析特殊字符。

修改之后打代码如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

public emp getempbyid2(string id){

     connection connection = null ;

     preparedstatement statement = null ;

     resultset rs = null ;

     emp emp = null ;

 

     try {

       connection = jdbcutils.getconnection();

       string sql = "select * from emp where empno=?" ;

       statement = connection.preparestatement(sql);

       statement.setstring( 1 ,id);

       rs = statement.executequery();

       while (rs.next()){

         emp = new emp();

         int empno = rs.getint( "empno" );

         emp.setempno(empno);

 

         string ename = rs.getstring( "ename" );

         emp.setename(ename);

 

         string job = rs.getstring( 3 );

         emp.setjob(job);

 

         string hiredate = rs.getstring( 5 );

         emp.sethiredate(hiredate);

       }

 

     } catch (sqlexception e) {

       e.printstacktrace();

     }

     finally {

       jdbcutils.close(connection,statement,rs);

     }

     return emp;

   }

再次测试:结果如图

总结:并不是意味着statement不能用,或者不能sql拼接

但是如果是前端穿过的来的值需要直接放到sql语句中,就需要注意。

以上所述是小编给大家介绍的java 基础知识 ——jdbc详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!

原文链接:https://blog.csdn.net/h1025372645/article/details/89191301

查看更多关于详解Java基础知识——JDBC的详细内容...

  阅读:12次