JDBC以及数据库连接池基本使用

?serverTimezone=UTC//设置时区<The server time zone value 'ä¸­å›½æ ‡å‡†æ—¶é—´' is unrecognized or represents more than one time zone>
net stop mysql//mysql关闭指令
net start mysql//mysql开启数据库指令

java连接数据库使用JDBC
java.sql.*,javax.sql.*这两个包只是接口类

java连接数据库:

  • 构建连接

    • 注册驱动

    • 确定对岸目标

try {
			Class.forName("com.mysql.cj.jdbc.Driver");
			System.out.println("注册驱动成功!");
		} catch (ClassNotFoundException e1) {
			System.out.println("注册驱动失败!");
			e1.printStackTrace();
		}

        String url="jdbc:mysql://localhost:3306/test?serverTimezone=UTC";
        Connection conn = null;
        //构建Java和数据库之间的桥梁:URL,用户名,密码
            conn = DriverManager.getConnection(url, "root", "1234567");
  • 执行操作

  • Statement(执行者):

    • 1.executeQuery()执行select语句,返回结果放在ResultSet

    • 2.使用executeUpdate()执行insert/update/delete,返回修改的行数

    • 3.一个statement对象一次只能执行一个命令

    • Result(返回结果集)

Statement stmt = conn.createStatement(); 
System.out.println("创建Statement成功!"); 
ResultSet rs = stmt.executeQuery("select bookname from t_book order by bookid");

Statement stmt = conn.createStatement(); 
            System.out.println("创建Statement成功!");      
            
            //执行SQL语句
            int result = stmt.executeUpdate(sql);
  • 释放连接

    • 1.next()判断是否还有下一条记录

    • 2.获取单元格,getint(),getstring(),getdouble().

    • Connection.close();

while(rs.next())
            {
            	System.out.println(rs.getInt(1) + "," + rs.getString(2) + "," + rs.getInt("price"));//可以是单元格的序号以及列名
            }
            
            rs.close();
            stmt.close();

import java.sql.*;

public class SelectTest {
    public static void main(String[] args){
    	
    	//构建Java和数据库之间的桥梁介质
        try{            
            Class.forName("com.mysql.cj.jdbc.Driver");
            System.out.println("注册驱动成功!");
        }catch(ClassNotFoundException e1){
            System.out.println("注册驱动失败!");
            e1.printStackTrace();
            return;
        }
        
        String url="jdbc:mysql://localhost:3306/test?serverTimezone=UTC";
        Connection conn = null;
        try {
        	//构建Java和数据库之间的桥梁:URL,用户名,密码
            conn = DriverManager.getConnection(url, "root", "1234567");
            
            //构建数据库执行者
            Statement stmt = conn.createStatement(); 
            System.out.println("创建Statement成功!");      
            
            //执行SQL语句并返回结果到ResultSet
            ResultSet rs = stmt.executeQuery("select bookid, bookname, price from t_book order by bookid");
                        
            //开始遍历ResultSet数据
            while(rs.next())
            {
            	System.out.println(rs.getInt(1) + "," + rs.getString(2) + "," + rs.getInt("price"));
            }
            
            rs.close();
            stmt.close();
            
        } catch (SQLException e){
            e.printStackTrace();
        }
        finally
        {
        	try
        	{
        		if(null != conn)
        		{
            		conn.close();
            	}
        	}
        	catch (SQLException e){
                e.printStackTrace();
        	}        	
        }
    }
}

JDBC事务处理

关闭自动提交,实现多语句同一事务

  • connection.setAutoCommit(false);关闭自动提交
  • connection.commit();提交事务
  • connection.rollback();回滚事务,如果被提交就不可以回滚。
  • 保存点机制
    • connection.setSavepoint();
    • connection.roolback(Savepoint);
// 构建Java和数据库之间的桥梁:URL,用户名,密码
			conn = DriverManager.getConnection(url, "root", "1234567");
			conn.setAutoCommit(false);

			insertBook(conn, "insert into t_book values(101, 'aaaa', 10)");
			insertBook(conn, "insert into t_book values(102, 'bbbb', 10)");
			insertBook(conn, "insert into t_book values(103, 'cccc', 10)");
			Savepoint phase1 = conn.setSavepoint(); //设置一个保存点
			insertBook(conn, "insert into t_book values(104, 'cccc', 10)");
			insertBook(conn, "insert into t_book values(105, 'cccc', 10)");
			conn.rollback(phase1);  //回滚到phase1保存点,即上面2行无效
			conn.commit();

PreparedStatement(预编译)

PreparedStatement是Statement接口的子接口,其实现在JDBC驱动类中, 属于预处理操作,与直接使用Statement不同,PreparedStatement在操作时,是预先在数据表中准备好了一条SQL语句,但是此SQL语句的具体内容暂时不设置,而是之后在进行设置。

  • 可以更为安全的执行SQL,防止注入攻击
  • 防止繁琐的字符串拼接和
  • 直接设置对象而不需要转换为字符串
  • PreparedStatement使用预编译速度相对Statement快的多

常用方法


1:executeQuery():在此PreparedStatement对象中执行SQL语句,并返回该查询生成的ResultSet对象。

2:executeUpdate():在此PreparedStatement对象中执行SQL语句,该语句必须是一个SQL数据操作语言(Date Manipulation Language,DML)语句,比如insert、update、delete语句;或者是无返内容的SQL语句,比如DDL语句。

3:execute():在此PreparedStatement对象中执行SQL语句,该语句可以是任何种类的SQL语句

4:getMetaData():获取包含有关ResultSet对象列信息的ResultSetMetaData对象,ResultSet对象将在此执行PreparedStatement对象时返回。

5:getParameterMetaData():获取此PreparedStatement对象的参数的编号、类型和属性


注意:

  • 注意sql语句的空格,SQL语句换行加空格
  • 使用?时应注意设置参数
//使用setstring()时字符串不用加单引号
/数据库插入语句//
            String sql = "insert into t_book(bookid,bookname,price) values(?,?,?)";
            
            //构建数据库执行者
            PreparedStatement pstmt = conn.prepareStatement(sql);
            
            //执行SQL语句
            int bookid = 10;
            String bookName = "Effective Java";
            int price = 50;
            
            pstmt.setInt(1, bookid);
            pstmt.setString(2, bookName);
            pstmt.setInt(3, price);
            
            int result = pstmt.executeUpdate();
//数据库模糊查询语句//
            String sql = " select * from mall  where name like ? ";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);

            preparedStatement.setString(1,"%"+s+"%");
            ResultSet resultSet = preparedStatement.executeQuery();
///数据库查询语句/
            String sql = " select * from mall  where name =? ";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);

            preparedStatement.setString(1,s);
            ResultSet resultSet = preparedStatement.executeQuery();

            while (resultSet.next()){
                Shopping shopping = new Shopping();
                shopping.setId(resultSet.getInt(1));
                shopping.setName(resultSet.getString(2));
                shopping.setTime(resultSet.getString(3));
                stringArrayList.add(shopping);
            }
//数据库删除语句///
            String sql = "" +
                    " delete from mall " +
                    " where id=? ";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);

            preparedStatement.setInt(1,i);

            preparedStatement.execute();
数据库插入语句
            String sql = "" +
                    "insert into mall" +
                    "(id,name,time)" +
                    "values(?,?,?)";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);

            preparedStatement.setInt(1,shop.getId());
            preparedStatement.setString(2,shop.getName());
            preparedStatement.setString(3,shop.getTime());

            preparedStatement.execute();
//数据库更新语句/
            String sql = "" +
                    " update  mall " +
                    " set name=?,time=? " +
                    " where id=? ";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);

            preparedStatement.setString(1,shop.getName());
            preparedStatement.setString(2,shop.getTime());
            preparedStatement.setInt(3,shop.getId());

            preparedStatement.executeUpdate();

批量提交数据

//构建Java和数据库之间的桥梁:URL,用户名,密码
            conn = DriverManager.getConnection(url, "root", "123456");
            
            String sql = "insert into t_book(bookid,bookname,price) values(?,?,?)";
            
            //构建数据库执行者
            PreparedStatement pstmt = conn.prepareStatement(sql);
            
            //执行SQL语句
            
            String bookName = "aaaaaaaaaaaaaaaa";
            int price = 50;
            
            //values(1, 'Effective Java', 50)
            for(int i=200;i<210;i++)
            {
            	pstmt.setInt(1, i);
                pstmt.setString(2, bookName);
                pstmt.setInt(3, price);
                pstmt.addBatch();
            }            
            
            pstmt.executeBatch();
                        
            pstmt.close();

ResultSetMetaData

可以获取resultset返回的属性(如,每一行的名字类型),使用ResultSetMetaData解析ResultSet:

  • getColumnCount(),返回结果的列数
  • getColumnClassName(i),返回第i列的数据的java类名
  • getColumnTypeName(i),返回第i列的数据库类型名称
  • getColumnType(i),返回第I列的SQL类型
//构建Java和数据库之间的桥梁:URL,用户名,密码
            conn = DriverManager.getConnection(url, "root", "123456");
            
            //构建数据库执行者
            Statement stmt = conn.createStatement(); 
            System.out.println("创建Statement成功!");      
            
            //执行SQL语句并返回结果到ResultSet
            ResultSet rs = stmt.executeQuery("select bookid, bookname, price from t_book order by bookid");
                        
            //获取结果集的元数据
            ResultSetMetaData meta = rs.getMetaData(); 
            int cols = meta.getColumnCount(); 
            for(int i=1;i<=cols;i++)
            {
            	System.out.println(meta.getColumnName(i) + "," + meta.getColumnTypeName(i));
            }
            
            rs.close();
            stmt.close();

ResultSet(语句返回结果集)

查询数据库时,返回的是一个二维的结果集,需要用到ResultSet来遍历结果集,获取每一行的数据。

  • ResultSet.next():将光标从当前位置向前移动一行。ResultSet游标最初位于第一行之前;第一个对方法的调用接下来使第一行成为当前行;第二个调用使第二行成为当前行,依此类推。当对next方法的调用返回false时,光标将位于最后一行之后。
  • ResultSet.getString(columnlabel),或者getString(columnindex),可以传入返回结果集的序号顺序或者数据库列名

数据库连接池

原理

数据库操作的构建连接释放连接浪费资源,所以应该通过运用共享技术实现数据库连接池(享元模式)

  • 降低系统中数据库连接Connection对象的数量
  • 将数据库服务器的连接响应消耗
  • 提高Connection获取的响应速度

享元模式:经典设计模式的一种,当一个系统中存在大量相同的对象时,由于这类对象的大量使用,会造成系统内存的浪费,可以使用享元模式来减少系统中对象的数量。

基本属性

  • 初始数:初始数据库连接的数量
  • 最大数:最大数据库连接的数量
  • 增量:用完后增加的数量
  • 超时时间:

C3P0连接池

import java.sql.Connection;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3p0Factory1 {
	
	private static ComboPooledDataSource dataSource = null;

	public static void init() throws Exception {
		
		dataSource = new ComboPooledDataSource();
		dataSource.setDriverClass( "com.mysql.jdbc.Driver" );            
		dataSource.setJdbcUrl( "jdbc:mysql://localhost:3306/test" );
		dataSource.setUser("root");                                  
		dataSource.setPassword("1234567");
			
		// the settings below are optional -- c3p0 can work with defaults
		dataSource.setMinPoolSize(5);//最小元素为5个
		dataSource.setAcquireIncrement(5);//增量为5个
		dataSource.setMaxPoolSize(20);//最大连接池数量为5个
			
		// The DataSource dataSource is now a fully configured and usable pooled DataSource

	}
	
	public static Connection getConnection() throws Exception {
		if(null == dataSource)
		{
			init();
		}
        return dataSource.getConnection();
    }

}
import java.sql.Connection;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3p0Factory2 {
	
	private static ComboPooledDataSource dataSource = null;

	public static void init() throws Exception {
		
		dataSource = new ComboPooledDataSource();
		//dataSource 自动加载c3p0-config.xml文件	
		
		// The DataSource dataSource is now a fully configured and usable pooled DataSource

	}
	
	public static Connection getConnection() throws Exception {
		if(null == dataSource)
		{
			init();
		}
        return dataSource.getConnection();
    }
}

<?xml version="1.0" encoding="UTF-8"?>//名字必须为c3p0-config.xml
<c3p0-config>

    <default-config>  <!-- 默认配置 -->
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/test</property>
        <property name="user">root</property>
        <property name="password">123456</property>
        <property name="initialPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </default-config>

</c3p0-config>

Druid连接池

import java.sql.Connection;

import com.alibaba.druid.pool.DruidDataSource;


public class DruidFactory1 {
	private static DruidDataSource dataSource = null;

	public static void init() throws Exception {
		
		dataSource = new DruidDataSource();
		dataSource.setDriverClassName("com.mysql.jdbc.Driver"); 
		dataSource.setUsername("root");
		dataSource.setPassword("123456");
		dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/test"); 
		dataSource.setInitialSize(5);
		dataSource.setMinIdle(1); 
		dataSource.setMaxActive(10); 
		// 启用监控统计功能 dataSource.setFilters("stat");// 
	}
	
	public static Connection getConnection() throws Exception {
		if(null == dataSource)
		{
			init();
		}
        return dataSource.getConnection();
    }
}

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;


public class DruidFactory2 {
	private static DruidDataSource dataSource = null;

	public static void init() throws Exception {
		Properties properties = new Properties();
		
		InputStream in = DruidFactory2.class.getClassLoader().getResourceAsStream("druid.properties");  
		properties.load(in); 		
		dataSource = (DruidDataSource)DruidDataSourceFactory.createDataSource(properties);		
		
		in.close();
	}
	
	public static Connection getConnection() throws Exception {
		if(null == dataSource)
		{
			init();
		}
        return dataSource.getConnection();
    }
}

//druid.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test
username=root
password=123456
filters=stat
initialSize=2
maxActive=300
maxWait=60000
timeBetweenEvictionRunsMillis=60000
minEvictableIdleTimeMillis=300000
validationQuery=SELECT 1
testWhileIdle=true
testOnBorrow=false
testOnReturn=false
poolPreparedStatements=false
maxPoolPreparedStatementPerConnectionSize=200

测试类


import java.sql.*;

public class SelectTest {
    public static void main(String[] args){    	
    	  
        Connection conn = null;
        try {
        	//从c3p0获取
            //conn = C3p0Factory1.getConnection();
            //conn = C3p0Factory2.getConnection();
            
            //从Druid获取
            //conn = DruidFactory1.getConnection();
            conn = DruidFactory2.getConnection();
            
            //构建数据库执行者
            Statement stmt = conn.createStatement(); 
            System.out.println("创建Statement成功!");      
            
            //执行SQL语句并返回结果到ResultSet
            ResultSet rs = stmt.executeQuery("select bookid, bookname, price from t_book order by bookid");
                        
            //开始遍历ResultSet数据
            while(rs.next())
            {
            	System.out.println(rs.getInt(1) + "," + rs.getString(2) + "," + rs.getInt("price"));
            }
            
            rs.close();
            stmt.close();
            
        } catch (Exception e){
            e.printStackTrace();
        } finally {
        	try	{
        		if(null != conn) {
            		conn.close();
            	}
        	} catch (SQLException e){
                e.printStackTrace();
        	}        	
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值