内容:
1.sql server数据库的备份和恢复
2.java程序如何操作数据库
目标:
1.掌握sql sever数据库的备份和恢复技巧
2.掌握java对表的 crud 操作
3.掌握Statement和PreparedSatement
4.能完成一般的java数据库编程任务
分离/附加:影响原数据库
备份/恢复:不影响原数据库
java程序操作数据库
crud(增删改查):增加(Create)、查询(Retrieve)、更新(Update)和删除(delete),主要描述软件系统中数据库的基本操作功能。
jdbc
JDBC(Java Data Base Connectivity,java数据库连接)是一种执行SQL语句的javaAPI,可以为多种关系数据库提供统一的访问。它由一组由java语言编写的类和接口组成。JDBC为工具/数据库开发人员提供了一个标准的API,据此可以构建更高级的工具和接口,使数据库开发人员能够用纯java API编写数据库应用程序。
常见的两种jdbc驱动方式图
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还能有效的防止危险字符的注入。
使用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
{
}
}
}