JAVA WEB---JDBC

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>

猜你喜欢

转载自blog.csdn.net/WuYunCode/article/details/81570801