目录

一、SQL常见语句:

二、构建数据库操作步骤:

三、SQL中字符串拼接

四、事务处理

五、数据库类型

六、数据库连接池


一、SQL常见语句:

  • 建表:create table t1(a int ,b varchar(20)));
  • 插入:insert into t1(a,b) values(1,'abc');
  • 选择:select a from t1;
  • 条件选择:select a,b from t1 where a>1;
  • 删除:delete from t1 where a = 10 and b='ab';
  • 更新:update t1 set a=2, b='cd' where a=1 and b='ab';
  • 删表:drop table t1;

字段类型: int 4个字节 double 8个字节 datetime时间7个字节 varchar 字符串

JDBC是数据库和Java连接方法是最主流的。

连接数据库的连接字符串:

jdbc:oracle:thin:@127.0.0.1:1234:dbname

jdbc:mysql://localhost:1234/mydb

jbdc:sqlserner://localhost:1234;DatabaseName=dbname

二、构建数据库操作步骤:

1.注册驱动,建桥

2.构建数据库指定者

3.执行SQL语句。

若是执行select语句时则需要获取结果,并且遍历结果输出。

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"));
            }

 建表,插入,删除操作等

import java.sql.*;

public class UpdateTest {
	public static void main(String[] args){
		executeUpdate("update t_book set price = 300 where bookid = 1");
		executeUpdate("insert into t_book(bookid, bookname, price) values(4, '编译原理', 90)");
		executeUpdate("delete from t_book where id = 4");
	}
    public static void executeUpdate(String sql)
    {
    	//构建Java和数据库之间的桥梁介质
        try{            
            Class.forName("com.mysql.jdbc.Driver");
            System.out.println("注册驱动成功!");
        }catch(ClassNotFoundException e1){
            System.out.println("注册驱动失败!");
            e1.printStackTrace();
        }
        
        String url="jdbc:mysql://localhost:3306/test";        
        Connection conn = null;
        try {
        	//构建Java和数据库之间的桥梁:URL,用户名,密码
            conn = DriverManager.getConnection(url, "root", "123456");
            
            //构建数据库执行者
            Statement stmt = conn.createStatement(); 
            System.out.println("创建Statement成功!");      
            
            //执行SQL语句
            int result = stmt.executeUpdate(sql);
                        
            stmt.close();
            
        } catch (SQLException e){
            e.printStackTrace();
        }
        //最后将连接关闭
        finally
        {
        	try
        	{
        		if(null != conn)
        		{
            		conn.close();
            	}
        	}
        	catch (SQLException e){
                e.printStackTrace();
        	}        	
        }
    }
}

三、SQL中字符串拼接

需要注意地是SQL字符串拼接很危险,如果拼接的字符串中又含有和SQL关键字会造成错误。很容易出现SQL注入。

防止的方法主要是通过 PreparedStatement类方法,用?代替变量。同时可以用addBatch批量更新。select可以用ResulSet接收结果。

示例:

public static void safeInsertBook()
	{
		//构建Java和数据库之间的桥梁介质
        try{            
            Class.forName("com.mysql.jdbc.Driver");
            System.out.println("注册驱动成功!");
        }catch(ClassNotFoundException e1){
            System.out.println("注册驱动失败!");
            e1.printStackTrace();
        }
        
        String url="jdbc:mysql://localhost:3306/test?allowMultiQueries=true";        
        Connection conn = null;
        try {
        	//构建Java和数据库之间的桥梁:URL,用户名,密码
            conn = DriverManager.getConnection(url, "root", "123456");
            
            String sql = "insert into t_book(bookid,bookname,price) values(?,?,?)";
            
            //构建数据库执行者
            PreparedStatement pstmt = conn.prepareStatement(sql);//比起creatStatement更安全地执行SQL,sql字符串中地?代替字符串拼接
            
            //执行SQL语句
            int bookid = 10;
            String bookName = "Effective Java',50);delete from t_book;insert into t_book values(101, 'faked book";
            int price = 50;
            
            //values(1, 'Effective Java', 50)
            pstmt.setInt(1, bookid);
            pstmt.setString(2, bookName);
            pstmt.setInt(3, price);
            
            int result = pstmt.executeUpdate();
                        
            pstmt.close();
            
            System.out.println("操作成功");
            
        } catch (SQLException e){
            e.printStackTrace();
        }
        finally
        {
        	try
        	{
        		if(null != conn)
        		{
            		conn.close();
            	}
        	}
        	catch (SQLException e){
                e.printStackTrace();
        	}        	
        }
    }
public static void batchInsertBook()
	{
		//构建Java和数据库之间的桥梁介质
        try{            
            Class.forName("com.mysql.jdbc.Driver");
            System.out.println("注册驱动成功!");
        }catch(ClassNotFoundException e1){
            System.out.println("注册驱动失败!");
            e1.printStackTrace();
        }
        
        String url="jdbc:mysql://localhost:3306/test?allowMultiQueries=true";        
        Connection conn = null;
        try {
        	//构建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();
            
            System.out.println("操作成功");
            
        } catch (SQLException e){
            e.printStackTrace();
        } finally {
        	try {
        		if(null != conn) {
            		conn.close();
            	}
        	}
        	catch (SQLException e){
                e.printStackTrace();
        	}        	
        }
}

四、事务处理

有场景:数据库操作时,需要是一系列操作,要么完全的执行,要么完全地不执行。

事务需要有原子性,一致性,隔离性,持续性

通过conn.setAutoCommit(false);//关闭自动提交

再依次执行,最后手动提交:conn.commit();

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Statement;

public class TransactionTest {

	public static void main(String[] args) throws Exception {
		// 构建Java和数据库之间的桥梁介质
		try {
			Class.forName("com.mysql.jdbc.Driver");
			System.out.println("注册驱动成功!");
		} catch (ClassNotFoundException e1) {
			System.out.println("注册驱动失败!");
			e1.printStackTrace();
		}

		String url = "jdbc:mysql://localhost:3306/test";
		Connection conn = null;
		try {
			// 构建Java和数据库之间的桥梁:URL,用户名,密码
			conn = DriverManager.getConnection(url, "root", "123456");
			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();//手动提交

			System.out.println("操作成功");

		} catch (SQLException e) {
			e.printStackTrace();
			conn.rollback();
		} finally {
			if (null != conn) {
				conn.close();
			}
		}
	}

	public static void insertBook(Connection conn, String sql) {
		try {
			// 构建数据库执行者
			Statement stmt = conn.createStatement();
			//System.out.print("创建Statement成功!");

			// 执行SQL语句
			int result = stmt.executeUpdate(sql);

			stmt.close();

		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

五、数据库类型

java数据库为什么要建表 java数据库建表语句_System

 getColumnName()返回列头的名字。

import java.sql.*;

public class ResultSetMetaDataTest {
    public static void main(String[] args){
    	
    	//构建Java和数据库之间的桥梁介质
        try{            
            Class.forName("com.mysql.jdbc.Driver");
            System.out.println("注册驱动成功!");
        }catch(ClassNotFoundException e1){
            System.out.println("注册驱动失败!");
            e1.printStackTrace();
            return;
        }
        
        String url="jdbc:mysql://localhost:3306/test";        
        Connection conn = null;
        try {
        	//构建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++)//列从1开始
            {
            	//返回每一列的数据名称和数据类型,入bookid是int类型
            	System.out.println(meta.getColumnName(i) + "," + meta.getColumnTypeName(i));
            }
            
            rs.close();
            stmt.close();
            
        } catch (SQLException e){
            e.printStackTrace();
        }
        finally
        {
        	try
        	{
        		if(null != conn)
        		{
            		conn.close();
            	}
        	}
        	catch (SQLException e){
                e.printStackTrace();
        	}        	
        }
    }
}

六、数据库连接池

上述例子中连接数据库都需要构建连接,但是构建需要耗费大量成本,所以推出享元模式。

数据库池:初始数、最大数、增量、超时时间等参数

优点:来降低系统中数据库连接Connection对象的数量,降低数据库服务器的连接响应消耗,提高Connection获取响应的速度。

我们一般常用C3P0数据库连接池,公认最好的是Druid数据库池。

需要进行依赖Druid

<dependency>
	    <groupId>com.alibaba</groupId>
	    <artifactId>druid</artifactId>
	    <version>1.1.10</version>
	</dependency>
import java.sql.*;

public class SelectTest {
    public static void main(String[] args){    	
    	  
        Connection conn = null;
        try {
        	//从c3p0获取
            
            //从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();
        	}        	
        }
    }
}

方式1:在代码中进行数据课池设定

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();
    }
}

方法二:在文件中进行设定

设定druid.properties文件

filters:配置插件,stat为监控统计

maxActivive:最大活跃

maxWait:最大等待

timeBetweenEvictionRunsMillis:检查空闲连接的频率,单位毫秒, 非正整数时表示不进行检查

minEvictableIdleTimeMillis:池中某个连接的空闲时长达到 N 毫秒后, 连接池在下次检查空闲连接时,将回收该连接

validationQuery:检查池中的连接是否仍可用的 SQL 语句,drui会连接到数据库执行该SQL, 如果正常返回,则表示连接可用,否则表示连接不可用

testWhileIdle:当程序请求连接,池在分配连接时,是否先检查该连接是否有效。(高效)true

testOnBorrow:程序 申请 连接时,进行连接有效性检查(低效,影响性能)false

testOnReturn:程序 返还 连接时,进行连接有效性检查(低效,影响性能)false

maxPoolPrepareStatementPerConnectionSize:每个连接最多缓存多少个SQL

poolPreparedStatements:

poolPreparedStatements

缓存通过以下两个方法发起的SQL:

true

 

public PreparedStatement prepareStatement(String sql)

 

 

 

public PreparedStatement prepareStatement(String sql,

 

 

 

int resultSetType, int resultSetConcurrency)

 

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.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();
    }
}

中国大学mooc《java核心技术》