JDBC的基本介绍
1、概述:jdbc是使用Java访问各种数据库的一种技术
(1)jdbc工作原理
2、jdbc核心Java类(API)
(1)DriverManager类
作用:管理各种数据库的驱动(JDBC的驱动),可以用它来获取数据库连接。根据所给的驱动去获取对应数据库的链接
(2)Connection接口
负责连接数据库,并担任传输数据的任务
(3)Statement接口
由Connection产生,负责执行SQL语句
(4)ResultSet接口
负责保存Statement执行后所产生的查询结果(数据库中查询出来的数据保存在ResultSet中)
3、使用JDBC的步骤
(1)建立Java与数据库之间的链接,将数据库的驱动包,复制到项目的lib目录中,复制完毕以后鼠标右键jar包,选择build path ,再选择 add to build path
(2)新建一个专门负责连接数据库的工具类DBUtil,并准备连接数据库的数据
连接数据库需要知道数据库的地址url,用户名 user,密码 password,以及数据库对应的驱动。如果需要连接数据库需要先将这些数据准备好。参考代码如下:
/**
* 连接数据库的工具类
*/
public class DBUtil {
//1.准备连接数据库的数据
// 数据库服务器的地址
// jdbc:mysql://数据服务器ip地址:端口号/需要访问的数据库
// localhost: 本机的ip地址 可以写成 127.0.0.1
// 3306 : mysql 的默认端口号
static String url = "jdbc:mysql://localhost:3306/myschool";
// 数据库的用户名 :mysql的默认用户名是root
static String user = "root";
// 数据库的密码: 填写自己的mysql 密码
static String password = "root";
// 数据库的驱动
static String driver = "com.mysql.jdbc.Driver"; }
(3)在DBUtil类中,添加获取数据库的工具方法
在一个项目中,会频繁使用,所以将它封装成一个工具方法,参考代码如下:
/**
* 负责获取数据库连接的工具方法
* @return Connection :数据库连接的对象 (桥梁,可以通过此对象访问数据库)
*/
public static Connection getCon(){
//1.安装数据库驱动(加载驱动类)
try {
Class.forName(driver);
//2.根据url,user,password获取数据库连接
Connection con =
DriverManager.getConnection(url, user, password);
return con;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
(4)添加main方法测连接,参考代码如下:
public static void main(String[] args) {
System.out.println(getCon());
}
运行结果:
(5)DBUtil完整代码
package jdbc; import java.sql.Connection;
import java.sql.DriverManager; /**
* 连接数据库的工具类
*/
public class DBUtil {
//1.准备连接数据库的数据
// 数据库服务器的地址
// jdbc:mysql://数据服务器ip地址:端口号/需要访问的数据库
// localhost: 本机的ip地址 可以写成 127.0.0.1
// 3306 : mysql 的默认端口号
static String url = "jdbc:mysql://localhost:3306/myschool";
// 数据库的用户名 :mysql的默认用户名是root
static String user = "root";
// 数据库的密码: 填写自己的mysql 密码
static String password = "root";
// 数据库的驱动
static String driver = "com.mysql.jdbc.Driver"; /**
* 负责获取数据库连接的工具方法
* @return Connection :数据库连接的对象 (桥梁,可以通过此对象访问数据库)
*/
public static Connection getCon(){
//1.安装数据库驱动(加载驱动类)
try {
Class.forName(driver);
//2.根据url,user,password获取数据库连接
Connection con =
DriverManager.getConnection(url, user, password);
return con;
} catch (Exception e) {
e.printStackTrace();
}
return null;
} public static void main(String[] args) {
System.out.println(getCon());
} }
3、使用JDBC实现对数据库表的增删改查
(1)向指定数据库表中插入数据
案例:使用jdbc向subject表中插入数据,参考代码如下:
① 创建一个实体类与数据库中中的表对应起来
package jdbc;
/**
* 创建一个实体类 与数据库中中的表对应起来
* 实体类:Subjet 对应 数据库表 subject
* 实体类的属性 对应 数据库表中的字段
* @author xp
*
*/
public class Subject {
private int subjectNo;// 对应subject表中的subjectNo 字段
private String subjectName;//对应subject表中的subjectName字段
private int classHour;//对应subject表中的classHour字段
private int gradeId;//对应subject表中的gradeId字段
public int getSubjectNo() {
return subjectNo;
}
public void setSubjectNo(int subjectNo) {
this.subjectNo = subjectNo;
}
public String getSubjectName() {
return subjectName;
}
public void setSubjectName(String subjectName) {
this.subjectName = subjectName;
}
public int getClassHour() {
return classHour;
}
public void setClassHour(int classHour) {
this.classHour = classHour;
}
public int getGradeId() {
return gradeId;
}
public void setGradeId(int gradeId) {
this.gradeId = gradeId;
} }
② 新建一个Dao类,来操作数据库表,参考代码如下:
package jdbc; import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement; /**
* 操作数据库表 subject
*
*/
public class SubjectDao {
/**
*向数据库表subject中插入数据的方法
*/
public static void insert(Subject sub){
//获取数据库连接
Connection con = DBUtil.getCon();
//2.编写sql语句
// id是自增涨的,所以这里不需要插入id,插入数据时会自动生成id
String sql = "insert into subject("
+ "subjectName,classHour,gradeId)"
+ " values('"+sub.getSubjectName()
+ "',"+sub.getClassHour()
+ ","+sub.getGradeId()+")";
System.out.println(sql); //3.构建sql语句
Statement st = null;
try {
st = con.createStatement();
//4.执行sql语句
st.execute(sql);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//5.关闭连接
try {
st.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
} }
} public static void main(String[] args) {
//测试插入方法
Subject sub = new Subject();
//只设置课程名称,表示只向数据库表中插入课程名称
sub.setSubjectName("布丁制作");
insert(sub);
}
}
(2)查询指定表中的数据
例如:查询某一个表中的所有数据, 在dao中添加查询所有数据的方法
public static List<Subject> findAll(){
//1.获取数据库连接
Connection con = DBUtil.getCon();
//2.编写sql语句
String sql = "select * from subject";
//3.构建sql语句
Statement st = null;
try {
st = con.createStatement();
//4.执行sql语句
//ResultSet 用来封装查询出的结果集 类似于集合中的iterator迭代器
ResultSet rs = st.executeQuery(sql);
List<Subject> subs = new ArrayList<Subject>();
// rs.next()判断结果集中是否有下一个元素,如果有就取出
while(rs.next()){
//创建课程对象
Subject sb = new Subject();
//取出结果中subjectNo,并存入到课程中
// rs.get字段类型(字段名) 获取字段中对应的值
sb.setSubjectNo(rs.getInt("subjectNo"));
sb.setSubjectName(rs.getString("subjectName"));
sb.setClassHour(rs.getInt("classHour"));
sb.setGradeId(rs.getInt("gradeID")); //将封装好的课程对象加入到集合中
subs.add(sb);
}
//将封装好的课程集合返回
return subs;
} catch (SQLException e) {
e.printStackTrace();
}finally{
try {
st.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
(3)execute,executeUpdate,executeQuery的区别
4、修改数据表中的数据
(1)根据subjectNo查询出数据,参考代码如下:
/**
*根据subjectNo查询出数据
*/
public static Subject findSubjectByNo(int subjectNo){
//1.获取数据库连接
Connection con = DBUtil.getCon();
//2.编写sql语句
String sql = "select * from subject where subjectNo="+subjectNo;
//3.构建sql语句
Statement st = null;
try {
st = con.createStatement();
//4.执行sql语句
ResultSet rs = st.executeQuery(sql);
//Subject sb = new Subject();
Subject sb = null;
while(rs.next()){
sb = new Subject();
sb.setSubjectNo(rs.getInt("subjectNo"));
sb.setSubjectName(rs.getString("subjectName"));
sb.setClassHour(rs.getInt("classHour"));
sb.setGradeId(rs.getInt("gradeID"));
}
return sb;
} catch (SQLException e) {
e.printStackTrace();
}finally{
try {
st.close();
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null; }
(2)修改数据的方法
/**
* 修改数据
**/
public static void update(Subject sub){
//1.获取数据库连接
Connection con = DBUtil.getCon();
//2.编写sql语句
String sql = "update subject set "
+ " subjectName='"+sub.getSubjectName()+"' ,"
+ " classHour="+sub.getClassHour()+" ,"
+ " gradeID="+sub.getGradeId()
+ " where subjectNo="+sub.getSubjectNo();
System.out.println(sql);
//3.构建sql语句
Statement st = null;
try {
st = con.createStatement();
st.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
}finally{
try {
st.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
(3)测试方法
//根据subjectNO 修改数据
//1. 根据subjectNO 查询出数据
Subject sub = findSubjectByNo(10);
//sub.setSubjectNo(10);
//2. 设置想要修改的数据
sub.setSubjectName("如何养生");
update(sub);
5、sql注入:使用拼接字符串的形式,向sql语句中注入代码片段
现有代码如下:
public static Master findMasterByNameAndPwd(String name ,String pwd ){
//1.获取数据库连接
Connection con = DBUtil.getCon();
//2.编写sql语句
String sql = "select * from master where name='"+name+"' and password='"+pwd+"'";
//3.构建sql语句
Statement st = null;
try {
st = con.createStatement();
ResultSet rs = st.executeQuery(sql);
Master master = null;
while(rs.next()){
master = new Master();
master.setId(rs.getInt("id"));
master.setName(rs.getString("name"));
master.setPassword(rs.getString("password"));
master.setMoney(rs.getInt("money"));
}
return master;
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
st.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
} return null;
}
如果这种方式登录,那么我们可以采用sql注入的形式,就算不知道用户名和密码,我们同样可以登录成功具体操作如下:
注意:Statement 构建sql语句需要用+拼接值,容易造成SQL。
(1)避免sql注入,使用PreparedStatement
概述:预编译的sql语句,继承Statement接口,比Statement更加灵活,效率更高,提高了sql语句的可读性,提高了sql语句的执行性能,提高了安全性
例如:
public static void insert(Dog dog){
//1.获取数据库连接
Connection con = DBUtil.getCon();
//2.编写sql语句
// ? 问号,占位符,表示此处需要设置一个值
String sql = "insert into dog (name,health,love,strain) values (?,?,?,?)";
//3.编译sql语句
PreparedStatement pst = null;
try {
pst = con.prepareStatement(sql);
//4.如果sql语句中有? ,就需要给?设置值
//pst.set类型(第几个问号,要设置给?号的值)
pst.setString(1, dog.getName());
pst.setInt(2, dog.getHealth());
pst.setInt(3, dog.getLove());
pst.setString(4, dog.getStrain()); //5.执行sql语句
int num = pst.executeUpdate();
if(num!=0){
System.out.println("数据插入成功");
} } catch (SQLException e) {
e.printStackTrace();
} }
注意:使用PreparedStatement时在sql语句中需要设置值时,用?,有几个?,就设置几个值
例如:setString(1,name);
表示给第一个?,设置name值
(2)将Statement替换成PrepareStatemen
public static Master findMasterByNameAndPwd(String name ,String pwd ){
//1.获取数据库连接
Connection con = DBUtil.getCon();
//2.编写sql语句
//String sql = "select * from master where name='"+name+"' and password='"+pwd+"'";
String sql = "select * from master where name=? and password=? ";
System.out.println(sql);
//3.构建sql语句
//Statement st = null;
PreparedStatement pst = null;
try {
//st = con.createStatement();
pst = con.prepareStatement(sql);
pst.setString(1, name);
pst.setString(2, pwd);
//ResultSet rs = st.executeQuery(sql);
ResultSet rs = pst.executeQuery();
Master master = null;
while(rs.next()){
master = new Master(); }
return master;
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
pst.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
运行结果: