说明:本文仅用于自我总结,无任何高端技术,大神绕行
1.概念:
- 是sun公司提供的通过java连接所有数据库的一组接口接口的实现类 由数据库的厂商来提供,用于帮助开发人员快速实现不同关系型数据库的连接!
- JDBC(Java DataBase Connectivity:java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问,它是由一组用Java语言编写的类和接口组成的。
- JDBC的作用:可以通过java代码操作数据库
2. 常见的接口和类
- Connection:数据库驱动类 ---- 指定url(主机ip+prot)+username+password
- DriverManager ---- 创建Connection对象
- Statement ---- sql发生器对象
- ResultSet ---- 结果集
- PreparedStatement: ---- 预编译对象 Statement的子接口
3.jdbc的步骤
-
导入jar包:把当前数据库的驱动导入项目
-
注册驱动:把connection驱动类加载进内存中
-
获取连接:通过DriverManager的静态方法指定url+user+pwd来创建connection连接对象
-
获取statement对象:通过connection对象创建statement(sql语句发生器对象)
-
发送sql语句:通过statement的executeXxx执行sql
-
解析结果集:如果执行的是executeQuery::对结果集进行解析:::由表行解析为java对象
-
关闭连接 释放资源
简单来说就是 创建连接+获取statement+执行sql+解析结果集+关闭连接
4 创建web项目
5 jdbc铁打步骤
1 创建连接:导入jar包+注册驱动+通过DriverManager获取connection连接 2 通过连接创建statement:通过connection连接的方法创建statement sql语句发生器对象 3 执行sql语句::执行statement的execute方法 4 解析结果集:::对resultset解析::把数据库的行解析为java对象 5 关闭连接
5.1 导入jar包
把mysql-connector-java-5.1.15-bin.jar复制到bin下
5.2 创建实体类
package com.zhiyou100.day01_jdbc;
import java.io.Serializable;
//实体类::一般一个实体类对应一个数据库表
//1 实现序列化接口
//2 属性私有化封装
//3 类型包装类类型
//4 按需求创建构造方法::重写equalse方法:::重写toString
public class Student implements Serializable {
// CREATE TABLE `student` (
// `sid` int(11) DEFAULT NULL,
// `sname` varchar(10) DEFAULT NULL,
// `sex` char(1) DEFAULT NULL,
// `sage` int(11) DEFAULT NULL,
// `score` float(4,1) DEFAULT NULL,
// `sdy` tinyint(1) DEFAULT NULL
// ) ENGINE=InnoDB DEFAULT CHARSET=utf8
private Integer id;
private String name;
private String sex;
private Integer age;
private Float score;
private Boolean dy;
//按需求创建构造方法::重写equalse方法:::重写toString 快捷键::alt+shift+s
public Integer getId() {
return id;
}
public Student() {
super();
}
public Student(Integer id, String name, String sex, Integer age, Float score, Boolean dy) {
super();
this.id = id;
this.name = name;
this.sex = sex;
this.age = age;
this.score = score;
this.dy = dy;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", sex=" + sex + ", age=" + age + ", score=" + score + ", dy="
+ dy + "]";
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Float getScore() {
return score;
}
public void setScore(Float score) {
this.score = score;
}
public Boolean getDy() {
return dy;
}
public void setDy(Boolean dy) {
this.dy = dy;
}
}
5.3 jdbc相关类的主要方法
DriverManager的方法::static Connection getConnection(url,name,pwd):::获取连接对象 Connection的方法::Statement createStatement():::获取statement对象 void close()::::::::::::::::::关闭连接 Statement的方法:::ResultSet executeQuery(sql):::执行dql语句 获取结果集 int executeUpdate(sql):::执行dml语句 获取影响的行数 void close()::::::::::::::::::关闭sql语句发生器对象 ResultSet的方法:::boolean next()::::是否还有数据可以解析 xxx getXxx(int index)::: 获取本行的index列的数据 xxx getXxx(String name)::: 获取本行的指定列名对应的数据 void close()::::::::::::::::::关闭结果集
5.4 实现jdbc的5步骤
package com.zhiyou100.day01_jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import org.omg.CORBA.Request;
public class Test01 {
public static void main(String[] args) throws Exception{
String url="jdbc:mysql://localhost:3306/db_46";
String user="root";
String pwd="root";
int sid=1848;
// 1 创建连接:导入jar包+注册驱动+通过DriverManager获取connection连接
//1.1 导入jar
//1.2 注册驱动::把驱动类com.mysql.jdbc.Drievr类加载进内存中
Class.forName("com.mysql.jdbc.Driver");
//1.3 通过DriverManager获取connection连接::指定url 用户名 密码
Connection connection=DriverManager.getConnection(url, user, pwd);
System.out.println(connection);
// 2 通过连接创建statement:通过connection连接的方法创建statement sql语句发生器对象
Statement statement=connection.createStatement();
// 3 执行sql语句::执行statement的execute方法
String sql="select * from student where sid="+sid;
ResultSet resultSet=statement.executeQuery(sql);
// 4 解析结果集:::对resultset解析::把数据库的行解析为java对象
while(resultSet.next()){//判断是否还有行可以解析
//根据列名获取列数据
// int id=resultSet.getInt("sid");
// int age=resultSet.getInt("sage");
// String name=resultSet.getString("sname");
// String sex=resultSet.getString("sex");
// float score=resultSet.getFloat("score");
// boolean dy=resultSet.getBoolean("sdy");
//根据列索引获取列数据:::列索引从1开始 需要对表结构数据
int id=resultSet.getInt(1);
int age=resultSet.getInt(4);
String name=resultSet.getString(2);
String sex=resultSet.getString(3);
float score=resultSet.getFloat(5);
boolean dy=resultSet.getBoolean(6);
Student s;
s=new Student(id, name, sex, age, score, dy);
System.out.println(s);
}
// 5 关闭连接
resultSet.close();
statement.close();
connection.close();
}
}
6 预编译对象:prparedstatement
- PreparedStatement::预编译对象
- 需要先准备sql模板::数据使用占位符?表示
- 获取预编译对象需要关联一个sql模板
- 然后给占位符赋值::调用PreparedStatement的setXxx方法
- 预编译对象好处一:省略了字符串sql语句的拼接
prparedstatement是statement的子接口
package com.zhiyou100.day01_jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class Test04 {
//注册驱动 写在静态代码块中
static String url,user,pwd,driverName;
static{
url="jdbc:mysql://localhost:3306/db_46";
user="root";
pwd="root";
driverName="com.mysql.jdbc.Driver";
}
//注册驱动
static{
try {
Class.forName(driverName);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//创建连接
static Connection getCon(){
try {
return DriverManager.getConnection(url, user,pwd);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//关闭连接
static void close(ResultSet set,Statement sta,Connection con){
try {
if(set!=null){set.close();}
if(sta!=null){sta.close();}
if(con!=null){con.close();}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args)throws Exception{
System.out.println("查询所有:"+getAllByStatement());
System.out.println("查询所有:"+getAllByPreparedStatement());
System.out.println("查询一个:"+getOneByPreparedStatement(2));
System.out.println("查询一个:"+getOneByStatement(2));
// System.out.println("添加一个:"+addOneByStatement(new Student(71, "韩梅71", "妖", 55, 11f, true,new Date())));
// System.out.println("添加一个:"+addOneByPreparedStatement(new Student(72, "韩梅72", "妖", 55, 11f, true,new Date())));
System.out.println("修改一个:"+updateOneByStatement(new Student(71, "韩梅55111", "女", 11, 11f, true,new Date(1))));
System.out.println("修改一个:"+updateOneByPreparedStatement(new Student(72, "韩梅55222", "女", 22, 22f, true,new Date(2))));
System.out.println("删除一个:"+deleteOneByStatement(71));
System.out.println("删除一个:"+deleteOneByPreparedStatement(72));
}
static List<Student> getAllByStatement()throws Exception{
List<Student> list=new ArrayList<Student>();
//获取连接
Connection con=getCon();
// 获取statemengt
Statement sta=con.createStatement();
//执行sql语句
String sql="select * from student";
ResultSet set=sta.executeQuery(sql);
while(set.next()){
//把每行进行成一个java对象
Student s=new Student();
s.setAge(set.getInt("sage"));
s.setName(set.getString("sname"));
s.setId(set.getInt("sid"));
s.setDy(set.getBoolean("sdy"));
s.setScore(set.getFloat("score"));
s.setSex(set.getString("sex"));
s.setSbirth(set.getDate("sbirth"));
list.add(s);
}
//关闭连接
close(set, sta, con);
return list;
}
static List<Student> getAllByPreparedStatement()throws Exception{
List<Student> list=new ArrayList<Student>();
//获取连接
Connection con=getCon();
// 准备sql模板::sql中的数据使用占位符?表示
String sql="select * from student";
// 由connection的prepareStatement关联sql模板 获取预编译对象
PreparedStatement pre=con.prepareStatement(sql);
// 给占位符赋值
//执行execute方法 访问数据库
ResultSet set=pre.executeQuery();
while(set.next()){
//把每行进行成一个java对象
Student s=new Student();
s.setAge(set.getInt("sage"));
s.setName(set.getString("sname"));
s.setId(set.getInt("sid"));
s.setDy(set.getBoolean("sdy"));
s.setScore(set.getFloat("score"));
s.setSex(set.getString("sex"));
s.setSbirth(set.getDate("sbirth"));
list.add(s);
}
//关闭连接
close(set, pre, con);
return list;
}
static Student getOneByStatement(int id)throws Exception{
//获取连接
Connection con=getCon();
// 获取statemengt
Statement sta=con.createStatement();
//执行sql语句
String sql="select * from student where sid="+id;
ResultSet set=sta.executeQuery(sql);
Student s=null;
if(set.next()){
//把每行进行成一个java对象
s=new Student();
s.setAge(set.getInt("sage"));
s.setName(set.getString("sname"));
s.setId(set.getInt("sid"));
s.setDy(set.getBoolean("sdy"));
s.setScore(set.getFloat("score"));
s.setSex(set.getString("sex"));
s.setSbirth(set.getDate("sbirth"));
}
//关闭连接
close(set, sta, con);
return s;
}
static Student getOneByPreparedStatement(int id)throws Exception{
Student s=null;
//获取连接
Connection con=getCon();
// 准备sql模板::sql中的数据使用占位符?表示
String sql="select * from student where sid=?";
// 由connection的prepareStatement关联sql模板 获取预编译对象
PreparedStatement pre=con.prepareStatement(sql);
// 给占位符赋值
pre.setInt(1, id);//给第一个占位符?赋值为id
//执行execute方法 访问数据库
ResultSet set=pre.executeQuery();
if(set.next()){
//把每行进行成一个java对象
s=new Student();
s.setAge(set.getInt("sage"));
s.setName(set.getString("sname"));
s.setId(set.getInt("sid"));
s.setDy(set.getBoolean("sdy"));
s.setScore(set.getFloat("score"));
s.setSex(set.getString("sex"));
s.setSbirth(set.getDate("sbirth"));
}
//关闭连接
close(set, pre, con);
return s;
}
static int addOneByStatement(Student s)throws Exception{
//获取连接
Connection con=getCon();
// 获取statemengt
Statement sta=con.createStatement();
//执行sql语句
String sql="insert into student(sid,sname,sex,score,sdy,sage,sbirth) values("+
s.getId()+","+
"\""+s.getName()+"\","+
"\""+s.getSex()+"\","+
s.getScore()+","+
s.getDy()+","+
s.getAge()+','+
"\""+date2Str(s.getSbirth())+"\""+
")";
System.out.println(sql);
int hang=sta.executeUpdate(sql);
//关闭连接
close(null, sta, con);
return hang;
}
static int addOneByPreparedStatement(Student s)throws Exception{
//获取连接
Connection con=getCon();
// 准备sql模板::sql中的数据使用占位符?表示
String sql="insert into student(sid,sname,sex,score,sage,sdy,sbirth) values(?,?,?,?,?,?,?)";
// 由connection的prepareStatement关联sql模板 获取预编译对象
PreparedStatement pre=con.prepareStatement(sql);
// 给占位符赋值
pre.setInt(1, s.getId());//给第1个占位符?赋值为id
pre.setString(2, s.getName());;//给第2个占位符?
pre.setString(3, s.getSex());//给第3个占位符?
pre.setFloat(4, s.getScore());//给第4个占位符?
pre.setInt(5, s.getAge());//给第5个占位符?d
pre.setBoolean(6, s.getDy());;//给第6个占位符?
//PreparedStatement setDate方法需要的参数是java.sql.Date::java对象提供的sbirth属性是java.util.Date
pre.setDate(7, new java.sql.Date(s.getSbirth().getTime()));//给第7个占位符?
//The method setDate(int, java.sql.Date) in the type PreparedStatement is not applicable for the arguments (int, java.util.Date)
//执行execute方法 访问数据库
int hang=pre.executeUpdate();
//关闭连接
close(null, pre, con);
return hang;
}
static int updateOneByStatement(Student s)throws Exception{
//获取连接
Connection con=getCon();
// 获取statemengt
Statement sta=con.createStatement();
//执行sql语句
String sql="update student set sname=\""+s.getName()+"\""+
",sage="+s.getAge()+
",score="+s.getScore()+
",sdy="+s.getDy()+
",sex=\""+s.getSex()+"\""+
",sbirth=\""+date2Str(s.getSbirth())+"\""+
" where sid="+s.getId();
System.out.println(sql);
int hang=sta.executeUpdate(sql);
//关闭连接
close(null, sta, con);
return hang;
}
static int updateOneByPreparedStatement(Student s)throws Exception{
//获取连接
Connection con=getCon();
// 准备sql模板::sql中的数据使用占位符?表示
String sql="update student set sname=?,sage=?,sex=?,sdy=?,score=?,sbirth=? where sid=?";
// 由connection的prepareStatement关联sql模板 获取预编译对象
PreparedStatement pre=con.prepareStatement(sql);
// 给占位符赋值
pre.setInt(7, s.getId());//给第1个占位符?赋值为id
pre.setString(1, s.getName());;//给第2个占位符?
pre.setString(3, s.getSex());//给第3个占位符?
pre.setFloat(5, s.getScore());//给第4个占位符?
pre.setInt(2, s.getAge());//给第5个占位符?d
pre.setBoolean(4, s.getDy());;//给第6个占位符?
pre.setDate(6, new java.sql.Date(s.getSbirth().getTime()));//给第7个占位符?
//执行execute方法 访问数据库
int hang=pre.executeUpdate();
//关闭连接
close(null, pre, con);
return hang;
}
static int deleteOneByStatement(int id)throws Exception{
//获取连接
Connection con=getCon();
// 获取statemengt
Statement sta=con.createStatement();
//执行sql语句
String sql="delete from student where sid="+id;
System.out.println(sql);
int hang=sta.executeUpdate(sql);
//关闭连接
close(null, sta, con);
return hang;
}
static int deleteOneByPreparedStatement(int id)throws Exception{
//获取连接
Connection con=getCon();
// 准备sql模板::sql中的数据使用占位符?表示
String sql="delete from student where sid=?";
// 由connection的prepareStatement关联sql模板 获取预编译对象
PreparedStatement pre=con.prepareStatement(sql);
// 给占位符赋值
pre.setInt(1, id);//给第1个占位符?赋值为id
//执行execute方法 访问数据库
int hang=pre.executeUpdate();
//关闭连接
close(null, pre, con);
return hang;
}
private static String date2Str(Date date){
return new SimpleDateFormat("yyyy/MM/dd").format(date);
}
}
7 预编译对象的好处
* PreparedStatement::预编译对象
* 需要先准备sql模板::数据使用占位符?表示
* 获取预编译对象需要关联一个sql模板
* 然后给占位符赋值::调用PreparedStatement的setXxx方法
*
* 预编译对象好处一:省略了字符串sql语句的拼接
* 预编译对象好处二:statement发送sql语句时 sql片段和数据破解 无法区分数据中拼凑的sql判断 不能防止sql攻击
* preparedstatement的sql模板和数据分两次编译,对数据进行过滤 对数据中的sql关键字和单引号双引号等特殊字符进行转义 可以有效防止sql攻击
package com.zhiyou100.day01_jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class Test05 {
//注册驱动 写在静态代码块中
static String url,user,pwd,driverName;
static{
url="jdbc:mysql://localhost:3306/db_46";
user="root";
pwd="root";
driverName="com.mysql.jdbc.Driver";
}
//注册驱动
static{
try {
Class.forName(driverName);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//创建连接
static Connection getCon(){
try {
return DriverManager.getConnection(url, user,pwd);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//关闭连接
static void close(ResultSet set,Statement sta,Connection con){
try {
if(set!=null){set.close();}
if(sta!=null){sta.close();}
if(con!=null){con.close();}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args)throws Exception{
System.out.println("登录:"+loginByPreparedStatement("韩梅2", "123"));
System.out.println("登录:"+loginByStatement("韩梅2", "123"));
System.out.println("-----------");
System.out.println("登录:"+loginByPreparedStatement("韩梅2' or '1'='1", "123"));
System.out.println("登录:"+loginByStatement("韩梅2' or '1'='1", "123"));
}
static Student loginByStatement(String name,String pwd)throws Exception{
//获取连接
Connection con=getCon();
// 获取statemengt
Statement sta=con.createStatement();
//执行sql语句
String sql="select * from student where sname = '"+name+"' and spwd= '"+pwd+"'";
System.out.println(sql);
ResultSet set=sta.executeQuery(sql);//sql语法检查 sql语句解析执行
Student s=null;
if(set.next()){
//把每行进行成一个java对象
s=new Student();
s.setAge(set.getInt("sage"));
s.setName(set.getString("sname"));
s.setPwd(set.getString("spwd"));
s.setId(set.getInt("sid"));
s.setDy(set.getBoolean("sdy"));
s.setScore(set.getFloat("score"));
s.setSex(set.getString("sex"));
s.setSbirth(set.getDate("sbirth"));
}
//关闭连接
close(set, sta, con);
return s;
}
static Student loginByPreparedStatement(String name,String pwd)throws Exception{
Student s=null;
//获取连接
Connection con=getCon();
// 准备sql模板::sql中的数据使用占位符?表示
String sql="select * from student where sname=? and spwd=?";
// 由connection的prepareStatement关联sql模板 获取预编译对象
PreparedStatement pre=con.prepareStatement(sql);//语法检查
// 给占位符赋值
pre.setString(1, name);//
pre.setString(2, pwd);
//执行execute方法 访问数据库
ResultSet set=pre.executeQuery();
if(set.next()){
//把每行进行成一个java对象
s=new Student();
s.setAge(set.getInt("sage"));
s.setName(set.getString("sname"));
s.setId(set.getInt("sid"));
s.setDy(set.getBoolean("sdy"));
s.setScore(set.getFloat("score"));
s.setSex(set.getString("sex"));
s.setSbirth(set.getDate("sbirth"));
s.setPwd(set.getString("spwd"));
}
//关闭连接
close(set, pre, con);
return s;
}
}