zoukankan      html  css  js  c++  java
  • 第四章节 JDBC的基本应用

    目录 

    一、连接数据库 

    二、数据库的高级应用(连接池)

    三、使用tomcat连接池

    下载并配置好JDBC驱动后,我们可以来使用。

    一、连接数据库

    注意,如果项目中用到了mysql数据库,还要添加mysql驱动程序Connector/J到这个项目中才行。

    使用JDBC连接数据库存取数据时,要执行三个步骤

    • 加载及注册适当的JDBC驱动程序

    加载使用

    Class.forName();

    加载完成后,驱动程序会建立一个Driver对象,并且会让DriverManager.rigisterDriver()自动注册这个对象。

    在JDBC中用URL来标识数据库,

    jdbc:<子协议>:<子名称>

    使用MySQL时,语法如下

    jdbc:mysql://hostname:port/databasename?param=value1

    子协议:mysql

    子名称://hostname:port/databasename?param=value1,其中param可以有多个。

    实例如:

    jdbc:mysql://localhost:3306/sample?user=root&password=root;

    • 建立到指定的数据库的连接对象

    有两种方法:

    1.

    String url = "jdbc:mysql://localhost:3306/sample?user=root&password=root";

    Connection con = DriverManager.getConnection(url);

    2.

    String url = "jdbc:mysql://localhost:3306/sample";

    String user ="root";

    String password="root";

    Connection con = DriverManager.getConnection(url,user,password);

    • 提交数据库查询和取得查询对象

    在取得数据库的连接对象后,就可以由它来创建一个陈述对象,其主要用来 传送 SQL语句到数据库服务器和执行Sql语句。

    如下:

    Statement stmt= con.createStatement();

    Statement对象有有三种执行语句的方法:

    executeQuery():执行查询。

    executeUpdate():执行更新。

    execute():不知道正要执行的是什么时。

    执行后数据库会返回一个ResultSet集合对象到JDBC中。原理如下:

    Connection ------>PreparedStatement-------->ResultSet

           |------>Statement----------------->ResultSet

           |-------->CallableStatement------>ResultSet 

    • 使用代码连接数据库

    我们先建立一个testmysql的数据库,里面有一个student表。

    //建立 
    create databse testmysql;
    //查看 
    show databases;
    //建立表
    user testmysql;
    create table student( id int(3), name char(20), sex boolean);
    //加入数据 
    insert into student ('1', 'lishengjing','1');
    //查看数据 
    select * from student ;

    然后我们在本项目中加载 jdbc,右键项目,选择build path 里面的user library中的MySQL.

    最后是编码。如下

    package chuiyuan;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    
    public class JDBCExample {
    	public static void main(String args[]){
    		try {
    			Class.forName("com.mysql.jdbc.Driver") ;
    			String url = "jdbc:mysql://localhost:3306/testmysql?user=root&password=chuiyuan" ;
    			Connection connection = DriverManager.getConnection(url) ;
    			
    			Statement stmt = connection.createStatement() ;
    			ResultSet rs = stmt.executeQuery("select * from student");
    			
    			while (rs.next()) {
    				System.out.println("student number:"+rs.getInt(1));
    				System.out.println("student name:"+rs.getString(2));
    				System.out.println("stutent sex:"+ rs.getBoolean(3)+"
    ");
    			}
    			rs.close(); 
    			stmt.close(); 
    			connection.close();
    		} catch (ClassNotFoundException e) {
    			e.printStackTrace();
    		}catch (SQLException e) {
    			e.printStackTrace(); 
    		}
    		
    		
    	}
    }
    
    • 用户界面连接数据库

     要在MyEclipse的DatabaseExplore中连接到数据库。

    参考

    http://jingyan.baidu.com/article/4e5b3e196758ad91901e24a0.html

    二、数据库的高级应用(连接池)

    如果对数据库的访问不是很频繁,我们可以在简单的在访问数据库时创建一个连接,用完后关闭,但是如果是一个复杂的频率的数据库应用,就不行了。

    • 数据库连接池

    为避免频繁地建立和关闭数据库,我们可以建立一个数据库连接池以共享连接资源。这就是共享资源里面的很出名的设计模式:资源池。

    数据库连接池的基本原理:

    在内部对象池中,维护一定数量的数据库连接,并对外暴露数据库连接获取和返回的方法,当要建立一个数据库连接时,只要从内存中取得一个,而不是新建一个。

    用完后,只用放回到内存中,对于连接的打开和建立都由连接池自己管理 。

    数据库连接池有以下特点:

    资源重用。

    高效的系统响应。

    统一的资源管理。

    • 数据库连接池的例子

    先查看工程lib中是否加入了Mysql 连接驱动Connector/J,如果没有,在工程,右键的Build libs中加入。

    在工程中加入 Pooling.properties文件如下

    driverClassName=com.mysql.jdbc.Driver
    username=root
    password=chuiyuan
    url=jdbc:mysql://localhost:3306/testmysql
    poolSize=10

    注意要写对,properties文件是用来对工程进行简单的配置的。详细相关的内容参考 

    http://www.open-open.com/lib/view/open1426130993279.html

    http://blog.csdn.net/haiyangzhibing/article/details/6699119

    然后是数据库连接池

    注意下面的对数据库的操作,除了在init中的,其它的几个都进行了线程同步。

    package chuiyuan;
    
    import java.io.FileInputStream;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.Properties;
    import java.util.Vector;
    
    public class ConnectionPool {
    	//实现List接口之一,与ArrayList相比,也是数组实现,
    	//但支持线程同步,所以访问速度慢于ArrayList
    	//但是大多数情况下不使用Vector,因为线程安全需要更大的系统开销
    	private Vector<Connection>  pool; 
    	private String url ;
    	private String username ;
    	private String password ;
    	private String drivderClassName ;
    	private int poolSize =1;//连接池大小,也就是连接池中有多少个数据库连接
    	private static ConnectionPool instance = null;
    	
    	private ConnectionPool(){
    		init();
    	}
    	/**
    	 * 返回当前连接池的一个对象
    	 * @return
    	 */
    	public static ConnectionPool getInstance (){
    		if (instance==null){
    			instance = new ConnectionPool() ;
    		}
    		return instance ;
    	}
    	/**
    	 * 初始化连接池,读取属性
    	 */
    	private void init() {
    		pool = new Vector<Connection>(poolSize) ;
    		readConfig();
    		addConnection();
    	}
    	/**
    	 * 在连接池中创建初始设置的数据库连接
    	 * 注意里面的循环做的工作
    	 */
    	private void addConnection() {
    		Connection connection = null ;
    		for (int i=0;i<poolSize; i++){
    			try {
    				Class.forName(drivderClassName) ;
    				connection= java.sql.DriverManager.
    						getConnection(url, username, password) ;
    				pool.add(connection) ;
    			} catch (ClassNotFoundException e) {
    				e.printStackTrace(); 
    			}catch (SQLException e) {
    				e.printStackTrace(); 
    			}
    		}
    		
    	}
    
    	private void readConfig() {
    		try {
    			String path = System.getProperty("user.dir")+"\Pooling.properties";
    			FileInputStream fis = new FileInputStream(path) ;
    			Properties properties = new Properties() ;
    			properties.load(fis); 
    			drivderClassName = properties.getProperty("driverClassName" );
    			username= properties.getProperty("username");
    			password = properties.getProperty("password");
    			url = properties.getProperty("url");
    			poolSize = Integer.parseInt(properties.getProperty("poolSize")) ;
    		} catch (Exception e) {
    			e.printStackTrace();
    			System.err.print("读取属性文件出错");
    		}
    		
    	}
    	/**
    	 * 用完后立即返回连接到连接池中
    	 * @param conn
    	 */
    	public synchronized void release(Connection conn){
    		pool.add(conn) ;
    	}
    	/**
    	 * 有所更改
    	 */
    	public synchronized void closePool(){
    		for (int i=0;i<pool.size();i++){
    			try {
    				pool.get(i).close(); 
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    			//先close 再remove 
    			//pool.remove(i) ;	
    		}
    		pool.clear(); 
    	}
    	
    	/**
    	 * 返回数据库中的一个连接
    	 * 下面的原来是pool.get(0),再进行remove
    	 * 如果用pool.size()-1会更快些
    	 * @return
    	 */
    	public synchronized Connection getConnection(){
    		if (pool.size()>0){
    			Connection conn = pool.get(pool.size()-1);
    			pool.remove(conn);
    			return conn ;
    		}else {
    			return null ;
    		}
    	}
    
    }
    

    里面的 getProperty("user.dir")为MyEclipse的安装目录。

    测试文件

    package chuiyuan;
    
    import java.security.Policy;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    public class Test {
    	public static void main(String args[]) throws SQLException, ClassNotFoundException{
    		String sql ="select * from student" ;
    		long start = System.currentTimeMillis() ;
    		ConnectionPool pool = null;
    		
    		for (int i=0;i<100;i++){
    			pool = ConnectionPool.getInstance() ;
    			Connection connection = pool.getConnection() ;
    			Statement stmt = connection.createStatement() ;
    			ResultSet rSet =stmt.executeQuery(sql) ;
    			while (rSet.next()) {
    				
    			}
    			rSet.close(); 
    			stmt.close(); 
    			pool.release(connection);
    		}
    		pool.closePool(); 
    		System.out.println("用连接池时:"+(System.currentTimeMillis() - start)+"ms");
    		
    		String hostname = "127.0.0.1";
    		String driverClass = "com.mysql.jdbc.Driver" ;
    		String url ="jdbc:mysql://localhost:3306/testmysql";
    		String username = "root" ;
    		String password = "chuiyuan";
    		start = System.currentTimeMillis() ;
    		
    		for (int i=0;i<100;i++){
    			Class.forName(driverClass) ;
    			Connection connection = DriverManager.getConnection(url,username, password) ;
    			Statement stmt = connection.createStatement() ;
    			ResultSet rs = stmt.executeQuery(sql) ;
    			while (rs.next()) {
    				
    			}
    			rs.close();
    			stmt.close(); 
    			connection.close();
    		}
    		System.out.println("不用连接池时:"+(System.currentTimeMillis() - start)+"ms");
    	}
    }
    

     三、使用tomcat连接池

    这个项目中好像没有加入 Connector/J。

    在开发项目时,编写连接池是没有必要的,因为已经存在很多数据库连接池现成了组件,只要配置一下就可以使用。而且现在很多服务器也已经内置了连接池,如tomcat.

    • 配置tomcat

    在tomcat的根目录conf中的context.xml文件中进行配置,使支持数据库连接池。

    <!--设置数据库连接池的核心-->
    <!-- name表示数据源的名字,auth表示验证方式 -->
    <!-- Type设置了资源的类型 -->
    <Resources name="jdbc/DBWater" auth="Container"
    Type="javax.sql.DataSource"
    maxActive="100" maxIdle="30" maxWait="1000"
    username="root" password="chuiyuan"
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/testmysql" />

    • 配置项目

    新建一个DBWater的web项目,配置DBWater/WebRoot/WEB-INF/web.xml,在<web-app>中加入如下

    <resource-ref>
    <description> Connection Pool</description>
    <res-ref-name>"java/DBWater</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Shareable</res-sharing-scope>
    </resource-ref>

    • 测试文件
    package com.chuiyuan;
    
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.Statement;
    
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.sql.DataSource;
    
    public class DBWater {
    	String name ;
    	int number ;
    	boolean sex ;
    	public String getName (){
    		return name ;
    	}
    	public int getNumber(){
    		return number ;
    	}
    	public boolean isSex (){
    		return sex ;
    	}
    	public void init (){
    		try {
    			InitialContext initialContext = new InitialContext() ;
    			if (initialContext== null)
    				throw new Exception("no context");
    			//创建数据源ds 
    			Context  context = (Context) initialContext.lookup("java:comp/env");
    			DataSource ds = (DataSource)context.lookup("jdbc/DBWater");
    			
    			if (ds!=null){
    				Connection connection = ds.getConnection() ;
    				if (connection!= null){
    					Statement stmt = connection.createStatement() ;
    					ResultSet rs = stmt.executeQuery("select * from student");
    					while (rs.next()) {
    						number = rs.getInt(1);
    						name = rs.getString(2);
    						sex = rs.getBoolean(3) ;
    					}
    					connection.close();
    				}
    			}
    		} catch (Exception e) {
    			// TODO: handle exception
    		}
    	}
    }
    
    • 修改WebRoot/index.jsp代码如下
    <%@ page contentType ="text/html; charset=UTF-8" %>
    <%@ page import="java.sql.*" %>
    <%@ page import="javax.sql.*" %>
    <%@ page import="javax.naming.*" %>
    <%@ page import="com.chuiyuan.*" %>
    <html>
    <head>
    <title>连接池测试</title>
    </head>
    <body>
    <%
    DBWater rs = new DBWater();
    rs.init() ;
     %>
     学生的学号:<%=rs.getNumber() %>
      学生的姓名:<%=rs.getName() %> 
      学生的性别:<%=rs.isSex() %>
    </body>
    </html>
    

    将这个项目发布到服务器,并启动tomcat服务器,在浏览器中输入 localhost:8080/DBWater/index.jsp。  

     

     

  • 相关阅读:
    git 删除远程文件、文件夹
    pod install太慢 可以使用代理的方式
    flutter Container()最小宽度 最小高度
    flutter common init 常用Widget初始化
    xcode 嵌入flutter_module后编译报错 This app could not be installed at this time.
    Spring AOP
    Spring @Value 配置项解析 vs Spring @ConfigurationProperties 配置项解析
    Spring Bean 的实例化过程
    SpringBoot 配置项解析
    Spring IOC 自动注入流程
  • 原文地址:https://www.cnblogs.com/chuiyuan/p/4547596.html
Copyright © 2011-2022 走看看