JDBC连接数据库
使用jdbc提供的接口来连接数据库,实现对数据库的增删改查的普通操作和批处理操作
jar包:mysql-connector-java-8.0.16.jar
一、使用可视化工具Heidisql来连接jdbc
MyEsclipse里面建名为jdbc的Java Project ->
window->show view->other…->DB Browser->
右击MyEclipse Derby->New…(创建一个数据库驱动)->
Driver template: MySQL Connector->
Driver name: wxd->
Connection URL: jdbc:mysql://localhost:3306/mybase1->
//localhost为mysql的IP,3306为mysql的端口号,mybase1是在Heidisql里面创建好的数据库名
User name:root->Password:*******->
Driver JARs->Add JARs->
添加Mysgl-connector-java-5.1.39-bin.jar包->
Driver classname: com.mysql.jdbc.Driver->Test Driver->
出现Database connection successfully establithed就是成功了
创建的wxd就是一个会话(和数据库的连接)
src->创建File文件(mybase1.sql)
Connection: wxd Catalog: mybase1
写入select * from emp; 然后按绿色的三角形执行,就相当于的heidisql里面来连接数据库,对数据库进行操作,查询它的结果
二、使用java纯语言来连接、操作数据库的一般步骤
创建名为jdbc的java项目->src->创建lib的Folder文件夹->
将mysql-connector-java-5.1.39-bin.jar包复制进去->右击jar包->
Bulid path->Add to Bulid path引入到项目库当中->
创建一个jdbc包->创建testConnection类->
编写代码步骤
①.Class.forName(“com.mysql.jdbc.Driver[驱动名称]”)加载驱动
②.通过DriverManager获取连接
③.通过Connection对象的create方法创建statement对象,编译静态sql语句
④.执行sql语句(执行查询语句,有一个ResultSet结果集,要对这个结果集进行下一步结果处理,执行增删改语句,不用进行第⑤步)
⑤.处理结果
⑥.关闭连接
1.使用Statement操作数据库
package jdbc;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class testStatement {
public static void main(String[] args) {
Connection conn=null;
try {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
String url="jdbc:mysql://localhost:3306/mybase1?useUnicode=true&characterEncoding=utf-8";
String username="root";
String password="root123";
conn = DriverManager.getConnection(url,username,password);
//System.out.println("数据库连接"+conn);
//3.创建Statement对象
Statement stm = conn.createStatement();
//4.执行sql语句
/*操作数据库 statement.excuteUpdate(增删改sql)
String sql1="insert into emp(ename,job,deptno) values('小花花','manager',10)";
String sql2="delete from emp where ename='小花花'";
String sql3="update emp set job='clerk' where ename='嫦娥'";
int lines=stm.executeUpdate(sql1);
System.out.println("影响行数"+lines);*/
/*查询*/
String sql="select * from emp";
ResultSet rs = stm.executeQuery(sql);
//5.处理结果集
while(rs.next()){
int empno=rs.getInt(1);
String ename=rs.getString(2);
String job=rs.getString(3);
int mgr=rs.getInt(4);
Date hiredate=rs.getDate(5);
//double sal=rs.getDouble(6);
double sal=rs.getDouble("sal");
double comm=rs.getDouble(7);
//int deptno=rs.getInt(8);
int deptno=rs.getInt("deptno");
System.out.println(empno+" "+ename+" "+job+" "+mgr+" "+"hiredate"+" "+sal+" "+comm+" "+deptno);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//6.关闭连接
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
2.使用PreparedStatement操作数据库
1.创建通过连接获得PreparedStatement对象
String sgl = "select * from emp where usename=? and password=?;
PreparedStatment pstm = conn.prepareStatement(sql);
创建sql时将sql语句发生变化的位置使用占位符?来代替
2.给?赋值(也称参数绑定)
set+?的数据类型。参数1:?的位置,从1开始。参数2:具体取值(具体取值只能用双引号,不能用单引号)
pstm. setstring(1, username);
pstm. setstring(2, password);
3.执行SQL
pstm. executeQuery();//查询
pstm.executeUpdate ();//增删改
此时JDBC将所有?对应的参数发送至数据库服务器,调用在共享池中由第一步创建的预编译的sQL并执行。
package jdbc;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class testPreparedStatement {
public static void main(String[] args){
/*三种资源都需要关闭*/
Connection conn=null;
PreparedStatement pstm=null;
ResultSet rs=null;
try {
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://localhost:3306/mybase1?useUnicode=true&characterEncoding=utf-8";
String user="root";
String password="root123";
conn=DriverManager.getConnection(url, user, password);
/*插入String sql="insert into emp(ename,job,deptno) values(?,?,?)";
pstm = conn.prepareStatement(sql);
pstm.setString(1, "大白");
pstm.setString(2, "leader");
pstm.setInt(3, 20);
int lines=pstm.executeUpdate();*/
/*更改String sql="update emp set job=? where ename=?";
pstm=conn.prepareStatement(sql);
pstm.setString(1,"clerk");
pstm.setString(2, "大白");
int lines=pstm.executeUpdate();*/
/*删除
String sql="delete from emp where ename=?";
pstm=conn.prepareStatement(sql);
pstm.setString(1,"大白");
int lines=pstm.executeUpdate();*/
//System.out.println("影响行数"+lines);
/*查询*/
String sql="select * from emp where job=?";
pstm=conn.prepareStatement(sql);
pstm.setString(1, "clerk");
rs= pstm.executeQuery();
while(rs.next()){
int empno=rs.getInt("empno");
String ename=rs.getString("ename");
String job=rs.getString("job");
int mgr=rs.getInt(4);
Date hiredate=rs.getDate(5);
double sal=rs.getDouble("sal");
double comm=rs.getDouble("comm");
int deptno=rs.getInt(8);
System.out.println(empno+" "+ename+" "+job+" "+mgr+" "+hiredate+" "+sal+" "+comm+" "+deptno);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
rs.close();
pstm.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
3.使用Statement 和PreparedStatement的区别
PreparedStatement可以预编译sql,也可以执行完整是sql,Statement 只能执行完整的sql
Statement :不能防止sql注入问题:例如String sql2=“delete from emp where ename=‘小花花’ and 1=1”;会导致全表删除。
PreparedStatement:由于是预编译的,不会出现sql注入的情况。
Statement :执行stm.executeUpdate(sql)不管执行增删改查哪种语句都需要做以下1,2,3,4步,都需要10s时间,就算是前后都执行的是delete语句,只是改变了一个ename,任然需要花费10s来重复1,2,3,4步
PreparedStatement:需要花费2s(创建pstm与用setString设置?的值),再调用executeUpdate方法花费10s执行sql(先编译后执行)。执行第一次sql需要花费12s,执行第二次同构的sql只需要花费2s来(创建pstm与用setString设置?的值),但如果第二次执行的是与第一次异构的sql,则需要再花费12s。
编译:检查当前使用用户是否有执行sql语句的权限,如果有执行权限就检查sql语法有没有错误。
批处理:批量的同时来执行一些sql语句
4.使用Statement批处理操作数据库
1、使用Statement对象添加要批量执行SQL语句:Statement.addBatch(sql)
2、执行批处理SQL语句: Statement.executeBatch()
3、清除批处理命令: Statement.clearBatch();
4、优缺点
优点:可以向数据库发送多条不同的SQL语句。
缺点: ①SQL语句没有预编译。
②当向数据库发送多条语句相同,但仅参数不同的SQL语句时,需重复写上很多条SQL语句。
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class TestStatementBatch {
public static void main(String[] args) throws Exception {
Connection conn=null;
Statement stm=null;
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
String url="jdbc:mysql://localhost:3306/mybase1?useUnicode=true&characterEncoding=utf-8";
String user="root";
String password="root123";
conn=DriverManager.getConnection(url, user, password);
//创建Statement对象
stm = conn.createStatement();
String sql1="insert into emp(ename,job,deptno) values('大佬','manager',20)";
String sql2="update emp set deptno='30' where ename='嫦娥'";
String sql3="delete from emp where ename='夏雪儿'";
//添加批处理
stm.addBatch(sql1);
stm.addBatch(sql2);
stm.addBatch(sql3);
//执行批处理
stm.executeBatch();
//清除批处理
stm.clearBatch();
stm.close();
conn.close();
}
}
5.使用PreparedStatement批处理操作数据库
1、采用PreparedStatement.addBatch()实现批处理
2、执行批处理SQL语句: PreparedStatement.executeBatch()
3、清除批处理命令: PreparedStatement.clearBatch();
4、优缺点
优点:发送的是预编译后的SQL语句,执行效率高。
缺点:只能应用在SQL语句相同,但参数不同的批处理中。因此此种形式的批处理经常用于在同一个表中批量插入数据,或批量更新表的数据。
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class TestPreparedStatementBatch {
public static void main(String[] args) throws Exception {
Connection conn=null;
PreparedStatement pstm=null;
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
String url="jdbc:mysql://localhost:3306/mybase1?useUnicode=true&characterEncoding=utf-8";
String user="root";
String password="root123";
conn=DriverManager.getConnection(url, user, password);
//创建PreparedStatement对象
String sql="insert into emp(empno,ename,deptno) values(?,?,?)";
pstm=conn.prepareStatement(sql);
//pstm绑定数据
for(int i=3008;i<4008;i++){
pstm.setInt(1, i);
pstm.setString(2, "小龙人"+i);
pstm.setInt(3, 20);
//添加批处理
pstm.addBatch();
//执行批处理,当i是100的倍数时执行一次批处理,然后将批处理清除,这样会使执行的效率更高,也会减少内存使用率,减少cpu的使用率
if(i%100==0){
pstm.executeBatch();
pstm.clearBatch();
}
}
//将余下的批处理语句执行完毕
pstm.executeBatch();
//反方向释放资源
pstm.close();
conn.close();
}
}