package a07JavaWebJDBC;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.gjt.mm.mysql.Driver;
//简单的数据库查询
/*
*
* 1.注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
2.获取数据库连接 (url,username,password)
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/bigdata","root","root");
第二步:建立路。第三步:拿到车
3.获取传输器对象
Statement stat=conn.createStatement();
4.传输sql语句到数据库中执行,获取结果集对象
ResultSet rs=stat.executeQuery("select * from stu");
5.遍历结果集获取需要的数据
while(rs.next()) {
int id=rs.getInt("id");
String name=rs.getString("name");
System.out.println("id:"+id+",name="+name);
}
6.关闭资源 注意:在增删改查的时候没有结果集对象ResultSet,无需释放
rs.close()
stat.close()
conn.close()
*/
public class JavaWebJDBC01 {
public static void main(String[] args) {
Connection conn=null; //数据库连接对象
Statement stat=null; //传输器对象
ResultSet rs=null; //结果集对象
try {
//1.注册数据库驱动
//缺点1:mysql的中Driver接口的实现类发现在静态代码块中注册驱动的逻辑,所以这种方式会造成驱动被注册两次。
//缺点2:这种方式导致了程序和具体的数据库驱动绑死在了一起,程序的灵活性比较低。
//DriverManager.registerDriver(new Driver()); //写死了类,产生了耦合。
//反射的方式注册数据库驱动
//优点1.只会注册一次
//优点2.只和一个代表驱动的类的全路径名字符串绑死,可以提取到配置文件中,不会和具体的驱动绑死在一起
Class.forName("com.mysql.jdbc.Driver"); //写死了字符串,可以提取到配置文件中
//2.获取数据库连接 (url,user,password)
//url简写: jdbc:mysql:///bigdata 默认使用localhost:3306 整个简写为"jdbc:mysql:///bigdate?user=root&password=root"
//注意:导入的Connection是java.sql.connection 导入接口 防止和具体数据库绑死
conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/bigdata","root","root");
//3.获取传输器对象
//第二步:建立路。第三步:拿到车
//注意:导入的是import java.sql.Statement;
stat=conn.createStatement();
//4.传输sql语句到数据库中执行,获取结果集对象
//boolean execute=stat.execute(""); //判断是否执行成功
//int n=stat.executeUpdate(""); //增删改查,返回的是执行后影响的行数
//ResultSet rs= stat.executeQuery("");//查,返回的是查询后的结果集
rs=stat.executeQuery("select * from stu");
//5.遍历结果集获取需要的数据
while(rs.next()) {
int id=rs.getInt("id");
String name=rs.getString("name");
System.out.println("id:"+id+",name="+name);
}
}catch(Exception e) {
}finally {
//6.关闭资源
//关闭顺序,后获取的先关,先获取的最后关
//rs.close;
//stat.close;
//conn.close;
if(rs!=null) {
try {
rs.close(); //null.close()会空指针异常
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
rs=null;
}
}
if(stat!=null) {
try {
stat.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
stat=null;
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
conn=null;
}
}
}
}
}
package a07JavaWebJDBC;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
//简单的数据库增删改查
/*
* 1.注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
2.获取数据库连接 (url,username,password)
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/bigdata","root","root");
第二步:建立路。第三步:拿到车
3.获取传输器对象
Statement stat=conn.createStatement();
4.传输sql语句到数据库中执行,获取结果集对象
int row=stat.executeUpdate("insert into stu values(null,'tencent')");
5.判断影响行数
if(row>0) {
System.out.println("增加成功,影响的行数是"+row);
}
6.关闭资源 注意:在增删改查的时候没有结果集对象ResultSet,无需释放
stat.close()
conn.close()
*/
public class JavaWebJDBC02 {
public static void main(String[] args) {
Connection conn=null;
Statement stat=null;
try {
//1.注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接 (url,username,password)
//注意:导入的Connection是java.sql.connection
conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/bigdata","root","root");
//3.获取传输器对象
//注意:导入的是import java.sql.Statement;
stat=conn.createStatement();
//4.传输sql语句到数据库中执行,获取结果集对象
//boolean execute=stat.execute(""); //任何sql都可以执行,判断是否执行成功
//int n=stat.executeUpdate(""); //增删改查,返回的是执行后影响的行数
//ResultSet rs= stat.executeQuery("");//查,返回的是查询后的结果集
int row=stat.executeUpdate("insert into stu values(null,'tencent')"); //注意""里面只能用''不能内嵌""
//5.遍历结果集获取需要的数据
if(row>0) {
System.out.println("增加成功,影响的行数是"+row);
}
}catch(Exception e) {
}finally {
//6.关闭资源 注意:在增删改查的时候没有结果集对象ResultSet,无需释放
if(stat!=null) {
try {
stat.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
stat=null;
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
conn=null;
}
}
}
}
}
package a07JavaWebJDBC;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
public class JavaWebJDBC03 {
public static void main(String[] args) {
/*
*sql注入攻击
*
* 由于jdbc程序在执行的过程中sql语句在拼装时使用了由页面传入参数,
* 如果用户,恶意传入一些sql中的特殊关键字,会导致sql语句意义发生变化,这种攻击方式就叫做sql注入。
*
*
* 如果输入用户名 szh'# 或者 szh' or '1=1
* 密码随便输入都可以执行成功
*
* select * from users where username=' (szh'#) ' and password='asadasdsadsdf' #代表后面都是注释,所以登录成功
* select * from users where username=' (szh' or '1=1) ' and password='asadasdsadsdf' or只要前面成功,后面不管所以登录成功
*/
Scanner scan=null;
Connection conn=null; //数据库连接对象
Statement stat=null; //传输器对象
ResultSet rs=null; //结果集对象
try {
scan=new Scanner(System.in);
System.out.println("请输入你的用户名");
String name=scan.nextLine();
System.out.println("请输入密码");
String pwd=scan.nextLine();
//1.注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接 (url,username,password)
conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/bigdata","root","root");
//3.获取传输器对象
stat=conn.createStatement();
//4.传输sql语句到数据库中执行,获取结果集对象
rs=stat.executeQuery("select * from login where username='"+name+"' and password ='"+pwd+"'");
//5.遍历结果集获取需要的数据
if(rs.next()) {
System.out.println("允许登录");
}else {
System.out.println("禁止登录");
}
}catch(Exception e) {
}finally {
//6.关闭资源
//关闭顺序,先获取的最后关,后获取的先关
//rs.close;
//stat.close;
//conn.close;
if(rs!=null) {
try {
rs.close(); //null.close()会空指针异常
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
rs=null;
}
}
if(stat!=null) {
try {
stat.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
stat=null;
}
}
if(conn!=null) {
try {
conn.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
conn=null;
}
}
if(scan!=null) {
try {
scan.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
scan=null;
}
}
}
}
}
package a07JavaWebJDBC;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;
public class JavaWebJDBC04 {
public static void main(String[] args) {
/*
* 防止sql注入攻击
*
* PreparedStatement对象 具有预编译的机制 将sql语句的主干优先传递 进行预编译 之后再传递参数
优点1:参数中再有特殊关键词 也不会作为sql关键字处理 自然防止了sql注入的可能
优点2: 经过预编译 效率更高
优点3:参数不是通过拼接 而是通过方法设置 代码更加优雅
*/
Scanner scan=null;
Connection conn=null; //数据库连接对象
Statement stat=null; //传输器对象
ResultSet rs=null; //结果集对象
PreparedStatement pst=null;
try {
scan=new Scanner(System.in);
System.out.println("请输入你的用户名");
String name=scan.nextLine();
System.out.println("请输入密码");
String pwd=scan.nextLine();
//1.注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接 (url,username,password)
conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/bigdata","root","root");
//--------------------------PreparedStatment仅这两步与之前的Statement不同------------------------------------------
//PreparedStatement好处
//--防止sql注入攻击
//--经过预编译 执行效率会更高
//--通过?替代了sql语句拼接参数的过程 代码更加优雅
//3.获取传输器对象
String sql="select * from login where username=? and password=? ";
pst = conn.prepareStatement(sql);// 1.先发一部分 这个就是预编译已经将sql传入
//Statement是conn.createStatement();
// PreparedStatement是conn.prepareStatement(sql)
// 这部分是 PreparedStatement独有的
//设置参数(将值传入ps)
//ps.set类型(?的序号,?的值)
pst.setString(1, name);
pst.setString(2, pwd);
//4.向数据库发送参数值,促使数据库执行sql语句 2. 再发一部分
rs=pst.executeQuery(); //Statement是stat.executeQuery(sql);
//PreparedStatement是pst.prepareQuery()
//-----------------------------------------------------------------------
//5.遍历结果集获取需要的数据
if(rs.next()) {
System.out.println("允许登录");
}else {
System.out.println("禁止登录");
}
}catch(Exception e) {
}finally {
//6.关闭资源
//关闭顺序,先获取的最后关,后获取的先关
//rs.close;
//stat.close;
//conn.close;
if(rs!=null) {
try {
rs.close(); //null.close()会空指针异常
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
rs=null;
}
}
if(stat!=null) {
try {
stat.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
stat=null;
}
}
if(conn!=null) {
try {
conn.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
conn=null;
}
}
if(scan!=null) {
try {
scan.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
scan=null;
}
}
}
}
}
package a07JavaWebJDBC;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class JavaWebJDBC05 {
public static void main(String[] args) throws Exception {
//批量处理第一种 Statement.addBatch(sql)
/*
把SQL语句加入到批命令中
Statement.addBatch(sql)
执行批处理SQL语句
Statement.executeBatch()方法:执行批处理命令
Statement.clearBatch()方法:清除批处理命令
example:
st.addBatch(sql1); //把SQL语句加入到批命令中
st.addBatch(sql2); //把SQL语句加入到批命令中
st.executeBatch(); //执行批处理
采用Statement.addBatch(sql)方式实现批处理:
优点:可以向数据库发送多条不同的sql语句。
缺点:
SQL语句没有预编译。
当向数据库发送多条语句相同,但仅参数不同的SQL语句时,需重复写上很多条SQL语句
*/
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql:///bigdata","root","root");
Statement stat = conn.createStatement();
//把SQL语句加入到批命令中 Statement.addBatch(sql)
stat.addBatch("create database parkdb2;");
stat.addBatch("use parkdb2;");
stat.addBatch("create table teacher (id int,name varchar(255));");
stat.addBatch("insert into teacher values (1,'zs');");
stat.addBatch("insert into teacher values (2,'ls');");
stat.addBatch("insert into teacher values (3,'ww');");
//执行批处理命令 Statement.executeBatch()
stat.executeBatch();
stat.close();
conn.close();
}
}
package a07JavaWebJDBC;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class JavaWebJDBC06 {
public static void main(String[] args) throws Exception {
//批量处理第二种 PreparedStatement.addBatch()
/*
把SQL语句加入到批命令中
PreparedStatement.addBath()
执行批处理SQL语句
PreparedStatement.executeBatch()
PreparedStatement.clearBatch()
采用PreparedStatement.addBatch()实现批处理:
优点:发送的是预编译后的SQL语句,执行效率高。
缺点:只能应用在SQL语句相同,但参数不同的批处理中。
因此此种形式的批处理经常用于在同一个表中批量插入数据,或批量更新表的数据。
*/
long begin = System.currentTimeMillis();
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql:///bigdata","root","root");
//默认自动提交事务,这里设置connection.setautocommit(false);sql命令的提交由应用程序负责,而不是驱动程序
//只有程序调用connection.commit()的时候才会将先前执行的语句一起提交到数据库,这样就实现了数据库的事务。
conn.setAutoCommit(false);
PreparedStatement ps = conn.prepareStatement("insert into teacher values (?,?)");
for(int i=1;i<=3000;i++){
ps.setInt(1, i);
ps.setString(2, "name"+i);
ps.addBatch(); //把SQL语句加入到批命令中 PreparedStatement.addBatch()
if(i%1000==0){
ps.executeBatch(); //执行批处理SQL语句 PreparedStatement.executeBatch()
ps.clearBatch(); //不清除,存放内存溢出 PreparedStatement.clearBatch()
}
}
ps.executeBatch(); //最后执行批处理SQL语句 防止遗漏的数据未执行
//事务提交 Connection.commit()
conn.commit();
conn.close();
long end = System.currentTimeMillis();
System.out.println(end - begin);
}
}
package a07JavaWebJDBC;
import java.io.FileInputStream;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;
import javax.sql.DataSource;
/*
* 数据库连接池
概述:用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长
所以设置一个连接池,在程序启动时就初始化一批连接,在程序中共享,需要连接时从池中获取,用完再还回池中,通过池共享连接,减少开关连接的次数,提高程序的效率。
Sun公司为连接池提供 javax.sql.DataSource接口,要求连接池去实现,所以连接池也叫数据源。
我们可以自己实现这个几口实现一个连接池。 implements DataSource
如下代码写的连接池,还需要在使用完连接后记得不能关闭连接,而是要调用retuConn方法将连接还回池中。
我们想能不能想办法改造conn的close方法,使close方法不会真的关闭连接而是将连接还回池中。
想要改造不喜欢的方法有 继承 装饰 动态代理三种方式实现。
*/
public class JavaWebJDBC07dbPool implements DataSource{
private static List<Connection> list = new LinkedList<>(); //提供连接对象列表List<Connection> list
//读取配置文件config.properties
//drivername=com.mysql.jdbc.Driver
//jdbcurl=jdbc:mysql:///bigdata
//uname=root
//password=root
private static Properties prop = new Properties();
static{
try {
prop.load(new FileInputStream("config.properties"));
//1.注册数据库驱动
Class.forName(prop.getProperty("drivername"));
//获取连接池,里面有5个连接对象
for(int i = 0;i<5;i++){
//2..获取数据库连接 (url,username,password)
Connection conn = DriverManager.getConnection(prop.getProperty("jdbcurl"),prop.getProperty("uname"),prop.getProperty("password"));
list.add(conn); //将conn对象添加到连接池
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
//得到连接对象getConnection()
@Override
public Connection getConnection() throws SQLException {
//如果连接池中没有连接对象,添加连接对象
if(list.size()==0){
for(int i = 0;i<3;i++){
Connection conn = DriverManager.getConnection(prop.getProperty("jdbcurl"),prop.getProperty("uname"),prop.getProperty("password"));
list.add(conn);
}
}
return list.remove(0); //getConnection()得到连接池对象,即使用连接池其中一个对象,将其从连接池移除
}
//归还连接对象retuConn()
public void retuConn(Connection conn){
try {
//retuConn()归还连接对象,即如果这个连接对象不是空的也不是关闭的,就将其归还给连接池
if(conn!=null && !conn.isClosed()){
list.add(conn);
}
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
}
@Override
public int getLoginTimeout() throws SQLException {
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return null;
}
}
config.properties
drivername=com.mysql.jdbc.Driver
jdbcurl=jdbc:mysql:///bigdata
uname=root
password=root
package a07JavaWebJDBC;
import java.beans.PropertyVetoException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Connection;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/*
c3po连接池
使用C30P0:
(1)导入jar包
(2)写配置文件,放置到类加载目录下 放在src下,不能放src的package下
<?xml version="1.0"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///day16</property>
<property name="user">root</property>
<property name="password">root</property>
</default-config>
</c3p0-config>
(3)程序中获取连接池对象
ComboPooledDataSource pool = new ComboPooledDataSource();
*/
public class JavaWebJDBC08DBUtil {
public static void main(String[] args) throws Exception {
//如果不写配置文件,不放置到类加载目录下,就需要向下面一样还要set
//ComboPooledDataSource source = new ComboPooledDataSource();
//source.setDriverClass("com.mysql.jdbc.Driver");
//source.setJdbcUrl("jdbc:mysql:///bigdata");
//source.setUser("root");
//source.setPassword("root");
//1.
//如果写配置文件,放置到类加载目录下,只需要这样一句话,其他c3po已经默认设置好
ComboPooledDataSource source = new ComboPooledDataSource();
//2.
Connection conn = source.getConnection();
//3.
PreparedStatement ps = conn.prepareStatement("select * from stu");
//4.
ResultSet rs = ps.executeQuery();
//5.
while(rs.next()){
System.out.println(rs.getString("name"));
}
//6.
rs.close();
ps.close();
conn.close();
}
}
c3p0-config.xml
<?xml version="1.0"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///parkdb2</property>
<property name="user">root</property>
<property name="password">root</property>
</default-config>
</c3p0-config>