三种方法:分离与附加(分离会删掉原有数据库)、界面操作的备份与还原、sql语句操作的备份与还原(备份是不会删掉原有数据库)
备份与还原中可以实现数据库的备份,和复制到其他机器中
sql语句操作的备份与还原:
--如何备份数据库.语法:backup database 数据库名 to disk='磁盘地址'
backup database liangshanhaohan to disk='F:/sp.bak'
--还原数据库,语法:restore database 数据库名 from disk='需要还原的文件的地址'
restore database liangshanhaohan from disk='F:/sp.bak'
表的备份与还原与之相似!
statement与preparedstatement对象的区别:
注入漏洞的分析:
Statement:
select *from user where name=’zhangsan’ and ‘1’ or 1=’1’
语句分析:sql语句中and的优先级高于or的优先级,
因此 select *from user where name=’zhangsan’ and ‘1’ or 1=’1’ 等价于: select *from user where (name=’zhangsan’ and ‘1’) or 1=’1’
因此name=’zhangsan’ and ‘1’ or 1=’1’的最终结果都是为真,where条件就失去作用,
整条sql的功能等价于:select *from user
①:使用PrepareStatement类的set方法,它在sql预编译的时候对sql语句完成,
PreparedStatement是通过?来传递参数的,避免了拼sql而出现sql注入的问题
select *from user where name=’(zhangsan’ and ‘1’ or 1=’1)’ 数据库将(zhangsan’ and ‘1’ or 1=’1)作为一个整体的字符串,
查询name的值不等于(zhangsan’ and ‘1’ or 1=’1)防止了注入漏洞!
从上面分析可以看出statement不能防止注入漏洞的主要原因是sql中的语句拼接问题;而statement是不支持?传递参数的,
多以存在注入漏洞,而preparestatement可以使用?传递参数,直接将字符串作为整体传入解决了注入漏洞!
jdbc-odbc桥接方式访问数据库
win10操作系统的ODBC数据源配置sqlserver数据库
示例:
/**
* 演示JdbcOdbc桥连方式下,使用statement方式发送sql语句的操作
* ①配置数据源--控制面板、管理工具、数据源、用户DNS、添加、sql server、测试
* (该过程是在计算机界面操作完成的)--实际上就是将数据库的文件配置为可访问的文件
* ②在程序中去连接数据源
*/
package com.JdbcOdbc;
import java.sql.*;
public class JdbcOdbc {
public static void main(String[] args) {
// TODO Auto-generated method stub
//定义需要的对象
Connection connection=null;
Statement statement=null;
ResultSet resultSet=null;
try {
//②连接数据源(四步曲):
//1、加载驱动(作用是吧需要的驱动加入内存)
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
//2、得到连接[指定连接的数据源,用户名,密码]
//如果在配置数据源时,选择的是windows nt验证,则不需要用户名和密码
connection=DriverManager.getConnection("jdbc:odbc:mytest","sa","sql@2018");
//3、创建statement或者preparestatement
//statement主要作用:发送sql语句到数据库
statement=connection.createStatement();
//4、执行(crud,操作,对数据库的增删改查)
//4.1、演示添加一条数据到数据库的表中,当插入一条是i=1
// int i=statement.executeUpdate("insert into goods values('3','dad',12,'日用品','dadds')");
// if (i==1) {
// System.out.println("添加成功");
//
// }else {
// System.out.println("添加失败");
// }
//4.2演示从表中删除一条记录
// int i=statement.executeUpdate("delete from goods where goodsId='3'");
// if (i==1) {
// System.out.println("删除成功");
//
// }else {
// System.out.println("删除失败");
// }
//4.3修改内容
// int i=statement.executeUpdate("update goods set goodsname='旺仔' where goodsId='3'");
// if (i==1) {
// System.out.println("修改成功");
//
// }else {
// System.out.println("修改失败");
// }
//4.4查询,显示goods表中所有的商品信息
//ResultSet结果集(可以看成一个表型集合),resultSet是一个游标指向表的标题行(类似数组代表首地址)----即列名的那行,并不是商品表内容的第一行
//将表读入内存
// resultSet=statement.executeQuery("select * from goods");
//试图取出(第一条商品信息的第一列)
// resultSet.next();//游标下移,从目录行指向表的第一行
// int a=resultSet.getInt(1);//选择第一列,使用getInt是因为我们已经知道表第一列的类型是int
// System.out.println(a);
// //取出第一行第二列
// String s=resultSet.getString(2);
// System.out.println(s);
//所以调用resultSet.next(),会使游标下移一行.循环下移取出所有行的查询结果(不能取出目录行,取目录行会出错,提示空指针,所以使用该集合时必须先下移指向第一行)
//每次返回一行的内容,循环整张表,
// while (resultSet.next()) {
// int a=resultSet.getInt(1);//取出第一行第一列的值
// String s=resultSet.getString(2);//第一行第二列
// String s2=resultSet.getString(3);//...
// String s3= resultSet.getString(4);//...
// String s4=resultSet.getString(5);//...
// System.out.println(a+" "+s+ " "+s2+ " "+s3+" "+s4 );
// }
} catch (ClassNotFoundException | SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//关闭资源!!!!!!!后建先关
try {
if (resultSet!=null) {
resultSet.close();
}
if (statement!=null) {
statement.close();
}
if (connection!=null) {
connection.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
/**
* 演示JdbcOdbc桥连方式下,使用preparestatement方式发送sql语句的操作
* ①配置数据源--控制面板、管理工具、数据源、用户DNS、添加、sql server、测试
* (该过程是在计算机界面操作完成的)--实际上就是将数据库的文件配置为可访问的文件
* ②在程序中去连接数据源
*/
package com.JdbcOdbc;
import java.sql.*;
public class Demo2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//定义需要的对象
Connection connection=null;
PreparedStatement preparedStatement=null;
ResultSet resultSet=null;
try {
//②连接数据源(四步曲):
//1、加载驱动(作用是吧需要的驱动加入内存)
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
//2、得到连接[指定连接的数据源,用户名,密码]
//如果在配置数据源时,选择的是windows nt验证,则不需要用户名和密码
connection=DriverManager.getConnection("jdbc:odbc:mytest","sa","sql@2018");
//3、创建statement或者preparestatement
//两者的区别:
//statement主要作用:发送sql语句到数据库,数据库处理sql语句
//preparedStatement是在客户端进行对sql语句的预处理,节省数据库服务器的压力
//另外,preparedStatement在创建时就需要把sql语句写入,其中的参数可用'?'代替,防止了sql语句的直接注入,提高了程序的安全
//4、preparedStatement的创建与执行是同时的(crud,操作,对数据库的增删改查)
//4.1、演示添加一条数据到数据库的表中,当插入一条是i=1
// preparedStatement=connection.prepareStatement("insert into goods values(?,?,?,?,?)");
// //4.1.1给sql语句(问号)赋值
// preparedStatement.setInt(1, 24);//给第一个问号赋值
// preparedStatement.setString(2, "雀巢");//区别直接在sql语句注入时,字符参数采用单引号,这里使用双引号
// preparedStatement.setString(3, "50.0");
// preparedStatement.setString(4, "日用品");
// preparedStatement.setString(5, "jiajia");
// //4.1.2执行
// int i=preparedStatement.executeUpdate();
// if (i==1) {
// System.out.println("添加成功");
//
// }else {
// System.out.println("添加失败");
// }
//。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
//同样preparedStatement也可以实现其他操作
} catch (ClassNotFoundException | SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//关闭资源!!!!!!!后建先关
try {
if (resultSet!=null) {
resultSet.close();
}
if (preparedStatement!=null) {
preparedStatement.close();
}
if (connection!=null) {
connection.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
jdbc的使用示例:
/**
* jdbc方式操作数据库
* jdbc不需要配置数据源(区别于jdbc-odbc桥式连接)
* 需要引用sqljdbc4.jar包
*/
package com.jdbc;
import java.sql.*;
public class Demo1 {
public static void main(String []args) {
//定义所需的对象
Connection connection=null;
PreparedStatement preparedStatement=null;
ResultSet resultSet=null;
try {
//初始化对象
//1、加载驱动
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
//2、得到连接
connection=DriverManager.getConnection
("jdbc:sqlserver://127.0.0.1:1433;databaseName=TX","sa","sql@2018");
//3、创建preparestatement对象,进行数据库的crub操作
preparedStatement=connection.prepareStatement("select goodsId,goodsName from goods");
//4、执行【如果是增删改--executeUpdate();如果是查询--executeQuery()】
resultSet=preparedStatement.executeQuery();
//循环取出商品的编号和名称
while (resultSet.next()) {
int Id=resultSet.getInt(1);
//int Id=resultSet.getInt(goodsId);以列名取也是可以的
String name=resultSet.getString(2);
System.out.println("ID="+Id+" name="+name);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
/**
* java使用jdbc连接进行ddl操作
*/
package com.jdbc;
import java.sql.*;
public class Demo2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//定义需要的对象
PreparedStatement preparedStatement=null;
Connection connection=null;
ResultSet resultSet=null;
try {
//加载驱动
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
//连接数据库
//127.0.0.1表示你要连接的数据库的IP; 1433表示sqlserver的默认端口(端口不能重复)
connection=DriverManager.getConnection
("jdbc:sqlserver://127.0.0.1:1433;databaseName=TX","sa","sql@2018");
//创建preparestatement,创建数据库
//preparedStatement=connection.prepareStatement("create database vvv");
//创建preparestatement,创建表
//preparedStatement=connection.prepareStatement("create table aab(aa int, bb nvarchar)");
//备份数据库
//preparedStatement=connection.prepareStatement("backup database liangshanhaohan to disk='f:/122.bak'");
//执行ddl语句,采用.excute()
boolean b=preparedStatement.execute();
if (!b) {
System.out.println("ok");
}else {
System.out.println("失败");
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally {
try {
if (resultSet!=null) {
resultSet.close();
}
if (preparedStatement!=null) {
preparedStatement.close();
}
if (connection!=null) {
connection.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}