内容:
1.sql server数据库的备份和恢复
2.java程序如何操作数据库
目标:
1.掌握sql sever数据库的备份和恢复技巧
2.掌握java对表的 crud 操作
3.掌握Statement和PreparedSatement
4.能完成一般的java数据库编程任务
分离/附加:影响原数据库
备份/恢复:不影响原数据库
--如何备份数据库 backup database liang to disk = 'f:/sp.bak' --删除数据库 drop database liang --恢复数据库 restore database Liang from disk = 'f:/sp.bak' --有时,可能不需备份整个数据库,只备份表
java程序操作数据库
crud(增删改查):增加(Create)、查询(Retrieve)、更新(Update)和删除(delete),主要描述软件系统中数据库的基本操作功能。
jdbc
JDBC(Java Data Base Connectivity,java数据库连接)是一种执行SQL语句的javaAPI,可以为多种关系数据库提供统一的访问。它由一组由java语言编写的类和接口组成。JDBC为工具/数据库开发人员提供了一个标准的API,据此可以构建更高级的工具和接口,使数据库开发人员能够用纯java API编写数据库应用程序。
jdbc驱动分类
目前常见的JDBC驱动程序可以分为四个种类:
(1)jdbc-odbc桥连接
(2)本地协议纯java驱动程序
(3)网络协议纯java驱动程序
(4)本地api
jdbc的不足
JDBC在java语言层面实现了统一,但在不同数据库之间存在许多差异,为了更好的实现跨数据库操作,诞生了Hibernate(orm技术)
,实现了JDBC的再封装,实现了对数据库操作更为广泛的统一和更好的移植性。
案例:
1.使用jdbc-odbc(open data base connectivity)桥接的方式操作sql server数据库。
需要配置数据源:
打开 管理工具-> 数据源(ODBC);在用户DSN项中添加一个数据源“mytest”,其中服务器 写/选 local 或写 . ,然后...;配置完后可测试数据源状态


jdbc-odbc案例代码/* * 演示使用jdbc-odbc桥接方式操作的数据库 spdb1 (emp,dept) * 1.配置数据库 * 2.在程序中连接数据库 * * */ package test1; import java.sql.*; public class Test1 { public static void main(String[] args) { Connection ct = null; Statement sm = null; try{ //1.加载驱动(把需要的驱动程序加入内存) Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); //2.得到连接(引入包sql) connect to a data source //指定连接到哪个数据源,若是window nt验证,则不需要用户名与密码 ct = DriverManager.getConnection("jdbc:odbc:mytest"); //3.创建Statement或者PreparedStatement【区别?】 //Statement用处是:主要用于发送SQL语句 到数据库 sm = ct.createStatement(); //4.执行(crud,创建数据库,备份数据库,删除数据库) //1.添加一条数据到dept表 // executeUpdate可以执行cud操作 // int i = sm.executeUpdate("insert into dept values(50,'保安部','深圳')"); // int i = sm.executeUpdate("delete from detp where DeptNO=50"); /* int i = sm.executeUpdate("update dept set loc='北京' where deptNo=50 "); if (i==1) { System.out.println("修改成功!"); } else { System.out.println("修改失败"); } */ //查询,显示所有的部门 //ResultSet结果集,可以理解成一个表行的结果集 ResultSet rs = sm.executeQuery("select * from dept"); /* rs.next(); int deptNo = rs.getInt(1); String dName = rs.getString(2); String loc = rs.getString(3); System.out.println(deptNo+"\n"+dName+"\n"+loc); */ // 取出查询的所有结果 while(rs.next()) { int deptNo = rs.getInt(1); String dName = rs.getString(2); String loc = rs.getString(3); System.out.println(deptNo+""+dName+""+loc); } }catch(Exception e) { e.printStackTrace(); }finally{ //资源关闭!!!! //关闭顺序是:谁后创建,谁先关闭 try { if(sm!=null) { sm.close(); } if(ct!=null) { ct.close(); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
注:此时的jdbc-odbc桥接驱动为:sun.jdbc.odbc.JdbcOdbcDriver
在cmd中使用 netstat –an 可查看连接状态。
注:资源 ResultSet 也要删除!
Statement和PreparedStatement的区别:
Statement和PreparedStatement都可以用于把sql语句从java程序中发送到指定的数据库,并执行sql语句,但存在如下区别:
(1)直接使用Statement,驱动程序一般不会对sql语句做处理而直接交给数据库;使用PreparedStatement,形成预编译的过程(在客户端程序中预先编译成数据库能直接执行的二进制代码),并能对语句做字符集的转换(至少在sql server)中如此。
好处:对于多次重复执行的语句,使用PreparedStatement效率会更高一些(提供小部分缓存),并且在此种情况下也较适合使用batch(批处理);另外可以比较好的解决系统本地化问题。
PreparedStatement将数据库的压力分散到客户端。
(2)PreparedStatement还能有效的防止危险字符的注入。
--演示sql注入漏洞 create table users( username varchar(30), passwd varchar(30) ) insert into users values('baiweiguo','baiweiguo') select * from users where username = 'dekjg' and passwd='gasdj' or 1='1'
使用PreparedStatement编码:


preparedStatement代码javapackage test1; import java.sql.*; public class Test2 { public static void main(String[] args) { //定义需要的对象 PreparedStatement ps = null; Connection ct = null; ResultSet rs = null; try{ //1.加载驱动 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); //2.得到连接 ct = DriverManager.getConnection("jdbc:odbc:mytest"); //3.创建ps ps = ct.prepareStatement("select * from dept where deptNo=? and loc=?"); //可以给?赋值 ps.setInt(1, 20); //第一个参数表示第几个问号 ps.setString(2, "dallas"); //preparedStatement通过使用?机制可放置注入漏洞 //如果不用 ? 机制,达不到注入密码 rs = ps.executeQuery(); while(rs.next()) { int deptNo = rs.getInt("deptNO"); String Dname = rs.getString(2); String loc = rs.getString(3); System.out.println(deptNo+""+Dname+""+loc); } }catch(Exception e) { e.printStackTrace(); }finally{ //关闭资源!!! try{ if(rs!=null) { rs.close(); } if(ps!=null) { ps.close(); } if(ct!=null) { ct.close(); } } catch(Exception e) { e.printStackTrace(); } } } }
注:
PreparedStatement中使用 ? 机制才能防止注入漏洞,否则不能防止。
如下代码同样能获取用户姓名与密码:
ps = ct.prepareStatement("select * from users " + "where username = 'ba' and passwd = 'gjk' or 1=1"); rs = ps.executeQuery(); while(rs.next()) { System.out.println(rs.getString("username")+""+rs.getString("passwd")); }
总结:
1.PreparedStatement可以提供执行的效率(它有预编译的功能)
2.PreparedStatement可以防止sql注入,但是要求用?赋值的方式才行。
2.使用 jdbc 驱动程序直接操作sql server数据库。
注意:
1.sql server 2008的驱动名字(记):com.microsoft.sqlserver.jdbc.SQLServerDriver
2.不需要创建数据源,但需要加载包 sqljdbc4.jar
127.0.0.1表示要连接的数据库的ip,此处为本地ip,可以是 localhost
1433表示sql server的默认端口


jdbc方式操作数据库/* * jdbc方式操作数据库 * 1.把java.sql.*引入 * 2.SQL server 2008需要引入包 sqljdbc4.jar * * */ package com.test2; import java.sql.*; public class Test1 { public static void main(String[] args) { //PreparedStatement 【火箭车】 //定义所需要的对象 PreparedStatement ps = null; Connection ct = null; ResultSet rs = null; try{ //初始化对象: //1.加载驱动 Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); //2.得到连接 ct = DriverManager.getConnection ("jdbc:sqlserver://localhost:1433;databaseName=spdb1","sa","119035"); //创建火箭车 /* ps = ct.prepareStatement("select * from dept"); //执行(增删改查) rs = ps.executeQuery(); while(rs.next()) { System.out.println(rs.getInt("deptNo")+" "+rs.getString("Dname")+" "+rs.getString("loc")); } */ //多表查询 ps = ct.prepareStatement("select eName,sal,dName from emp,dept where emp.deptNo=dept.deptNo"); rs = ps.executeQuery(); while(rs.next()) { String eName = rs.getString(1);//eName = rs.getString("eName"); float sal = rs.getFloat(2); String dName = rs.getString(3); System.out.println(eName+""+sal+""+dName); } //添加、删除和修改 ps = ct.prepareStatement("update dept set dName = ?, loc = ? where deptNo=60 "); //给?赋值 ps.setString(1, "销售"); ps.setString(2, "北京"); int i = ps.executeUpdate(); if(i==1) System.out.println("修改成功!"); }catch(Exception e) { e.printStackTrace(); }finally { } } }