Java-JDBC(数据库)

JDBC

JDBC(Java DataBase Connectivity)是Java和数据库之间的一个桥梁,是一个规范而不是一个实现,能够执行SQL语句。它由一组用Java语言编写的类和接口组成。各种不同类型的数据库都有相应的实现
JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。

执行流程:

  1. 连接数据源,如:数据库。
  2. 为数据库传递查询和更新指令。
  3. 处理数据库响应并返回的结果

JDBC具体语法1:

1.获取连接对象
// 参数为连接数据名,用户名,密码(这里密码为空妹设密码)
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/newdb3","root","");
2.创建SQL执行对象Statement
Statement s = conn.createStatement();
3.执行SQL语句
String sql = "create table jdbct1(id int,name varchar(10))";
s.execute(sql);
4.关闭连接
conn.close();

   

JDBC具体语法2(创建预编译SQL执行对象):

2.创建预编译SQL执行对象PreparedStatement
// 此sql语句用?号进行占位
String sql = "select count(*) from user where username=? and password=?";
// 创建预编译的SQL执行对象
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, name); // 第一个?是name(不是从0开始的!)
ps.setString(2, pwd); // 第二个?是pwd
3.执行SQL语句
// 这里()里面就不需要再写sql了
ResultSet rs = ps.executeQuery();


   

预编译SQL执行对象PreparedStatement相比较Statement的优势

  • 代码整洁

  • 可以避免SQL注入风险,因为在创建对象时已经把SQL语句的逻辑锁死,不会被用户输入的内容所影响

  • 如果SQL语句中没有使用变量则使用Statement,如果有变量则使用PreparedStatement

   

示例:
  1. 创建maven工程,在pom.xml中导入jar包
<dependency>
   <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.6</version>
</dependency>
  1. 增删改查基本操作如下

public void test() throws SQLException {
	System.out.println("执行sql语句");
	// 获取连接对象
	Connection conn = DriverManager.getConnection(
			"jdbc:mysql://localhost:3306/newdb3",
			"root",columnIndex
			""
			);
	// 创建SQL执行对象
	Statement s = conn.createStatement();
	// 执行SQL插入语句
	String sql = "insert into jdbct1 values(1,'张三'),(2,'李四'),(3,'王五'),(4,'周六')";
	s.executeUpdate(sql);
	// 执行SQL修改语句
	sql = "update jdbct1 set name='张三三' where id=1";
	s.executeUpdate(sql);
	// 执行SQL删除语句
	sql = "delete from jdbct1 where id=1";
	s.executeUpdate(sql);
	// 执行SQL查询语句
	sql = "select * from jdbct1";
	// 查询得到一个ResultSet结果集
	ResultSet rs = s.executeQuery(sql);
	System.out.println(rs.getFetchSize());
	// 遍历结果集
	while(rs.next()) {
		int id = rs.getInt("id");
		// 这里还可以写数字,代表获取的第几个字段
		String name = rs.getString("name");
		System.out.println(id+":"+name);
	}
	// 关闭连接
	conn.close();
	System.out.println("执行完成!");
}

   

执行SQL的查询语句得到的是一个ResultSet查询结果集

  • 可通过遍历ResultSet得到每一个查询出来的值
  • rs.next()判断是否还有下一个
  • rs.getString/rs.getInt等方法得到字段的值

   

    

DBCP数据库连接池

  • DBCP:DataBase Connection Pool
  • 作用:将连接重用,避免频繁的开关连接,从而达到提高执行效率的目的
package cn.tedu.jdbc;

import java.sql.Connection;
import java.sql.SQLException;

import org.apache.commons.dbcp.BasicDataSource;

/**
 * 数据库连接池
 */
public class Demo_03 {
	public static void main(String[] args) throws SQLException {
		// 创建数据库连接池对象
		BasicDataSource ds = new BasicDataSource();
		// 设置连接信息
		// 注册驱动 告诉编译器使用的数据库是MySQL
		ds.setDriverClassName("com.mysql.jdbc.Driver");
		ds.setUrl("jdbc:mysql://localhost:3306/newdb3");
		ds.setUsername("root");
		ds.setPassword("");
		// 设置初始连接对象
		ds.setInitialSize(3);
		// 设置最大连接数量
		ds.setMaxActive(5);
		// 从连接池中获取连接对象
		Connection conn = ds.getConnection();
		
		System.out.println(conn);
	}
}

需要在pom.xml中导入相应jar包,maven 仓库中搜索dbcp

<!-- 数据库连接池坐标 -->
<!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp -->
<dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.3</version>
</dependency>

    

将数据库连接池/连接对象写在一个工具类DBUtils.java中

  1. 在src/main/resources下新建配置文件jdbc.properties,将数据库连接相关的信息写入此文件中

    # Database config
    # 注册驱动
    driver = com.mysql.jdbc.Driver
    # 数据库路径
    url = jdbc:mysql://localhost:3306/newdb3
    # 用户名
    username = root
    # 密码(此处没有密码,注意:不能写成空字符串 password=""是错的)
    password = 
    
    1. 将数据库连接对象写在工具类DBUtils.java中
    package cn.tedu.jdbc;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.util.Properties;
    
    import org.apache.commons.dbcp.BasicDataSource;
    
    /**
     * 数据库操作的工具类
     */
    public class DBUtils {
    	private static BasicDataSource ds;
    	static {
    		// 创建属性对象
    		Properties p = new Properties();
    		// 获取文件输入流
    		InputStream ips = DBUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
    		// 把文件加载到属性对象中
    		try {
    			p.load(ips);
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		// 连接数据库的相关信息
    		String driver = p.getProperty("driver");
    		String url = p.getProperty("url");
    		String username = p.getProperty("username");
    		String password = p.getProperty("password");
    		// 创建数据库连接池对象
    		ds = new BasicDataSource();
    		// 设置连接信息
    		// 注册驱动 告诉编译器使用的数据库是MySQL
    		ds.setDriverClassName(driver);
    		ds.setUrl(url);
    		ds.setUsername(username);
    		ds.setPassword(password);
    		// 设置初始连接对象
    		ds.setInitialSize(3);
    		// 设置最大连接数量
    		ds.setMaxActive(5);
    	}
    	
    	/**
    	 * 获取连接对象Connection
    	 * @return conn
    	 * @throws Exception
    	 */
    	public static Connection getConn() throws Exception {
    		// 从连接池中获取连接对象
    		Connection conn = ds.getConnection();
    		return conn;
    	}
    }
    
    

    

批量操作

将多条SQL语句由默认的多次数据传输合并成一次传输,从而提高执行效率。

Statement对象

  1. 创建SQL执行对象
    Statement s = conn.createStatement();
  2. 添加到批量操作
    s.addBatch(sql1);
    s.addBatch(sql2);
    s.addBatch(sql3);
  3. 执行批量操作(这样网络只传输一次,如果分三次执行的话网络传输三次)
    s.executeBatch();

PreparedStatement对象

  1. 创建SQL执行对象
    PreparedStatement ps = conn.prepareStatement(sql);
  2. 添加到批量操作
    ps.addBatch();
  3. 执行批量操作
    ps.executeBatch();

示例:

package cn.tedu.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;

import org.junit.Test;

public class Demo_05 {
	@Test
	/**
	 * 批量插入示例(Statement对象)
	 */
	public void test01() {
		try (Connection conn = DBUtils.getConn()) {
			String sql1 = "insert into jdbct1 values(6,'璐璐')";
			String sql2 = "insert into jdbct1 values(7,'七七')";
			String sql3 = "insert into jdbct1 values(8,'巴巴')";
			// 创建SQL执行对象
			Statement s = conn.createStatement();
			// 添加到批量操作
			s.addBatch(sql1);
			s.addBatch(sql2);
			s.addBatch(sql3);
			// 执行批量操作(这样网络只传输一次,如果分三次执行的话网络传输三次)
			s.executeBatch();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Test
	/**
	 * 往数据库中插入100条数据(PreparedStatement对象)
	 * user表字段(id,username,password)
	 */
	public void test02() {
		try (Connection conn = DBUtils.getConn()) {
			String sql = "insert into user values(null,?,?)";
			PreparedStatement ps = conn.prepareStatement(sql);
			for(int i=1;i<=100;i++) {
				ps.setString(1, "name"+i);
				ps.setString(2, "pwd"+i);
				// 添加到批量操作
				ps.addBatch();
				// 避免内存溢出(每隔20条执行一次)
				if(i%20==0) {
					// 执行批量操作
					ps.executeBatch();
				}
			}
			// 执行批量操作
			ps.executeBatch();
			System.out.println("执行完毕!");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}	

   

获取自增主键值

如果插入数据后需要使用自增的主键值时用以下代码

  1. 创建SQL执行对象 并设置获取自增主键值(传入第二个参数Statement.RETURN_GENERATED_KEYS)
    PreparedStatement ps = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);

  2. 获取自增主键值(返回ResultSet)
    ResultSet rs = ps.getGeneratedKeys();
    遍历后:int id = rs.getInt(1);
    返回的结果只有一个id,固定写法

    package cn.tedu.jdbc;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.Statement;
    
    
    public class Demo_07 {
    	public static void main(String[] args) {
    		try (Connection conn = DBUtils.getConn()) {
    			String name = "Tom";
    			String pwd = "123";
    			String sql = "insert into user values(null,?,?)";
    			// 创建SQL执行对象 并设置获取自增主键值
    			PreparedStatement ps = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
    			ps.setString(1, name);
    			ps.setString(2, pwd);
    			ps.executeUpdate();
    			// 获取自增主键值
    			ResultSet rs = ps.getGeneratedKeys();
    			while(rs.next()) {
    				// 获取自增的id
    				int id = rs.getInt(1);
    				System.out.println("id="+id);
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    }
    
    

   

数据库元数据对象

数据库的元数据对象,该对象保存了数据库的相关信息

  • 获取数据库元对象
  1. DatabaseMetaData dbmd = conn.getMetaData();//获取元数据对象
  2. dbmd.getDatabaseProductName() 获取数据库名
  3. dbmd.getDriverVersion() 获取数据库的驱动版本
  4. dbmd.getUserName() 获取数据库的用户名
  • 获取表元数据对象(需要先写查询)
  1. ResultSet rs = s.executeQuery(sql);
  2. ResultSetMetaData rsmd = rs.getMetaData(); 获取表元数据对象
  3. int count = rsmd.getColumnCount(); 获取字段数量
  4. rsmd.getColumnName(int i); 获取字段名称
  5. rsmd.getColumnTypeName(i+1); 获取字段类型

相应的方法有很多,这里只列举常用的几个,其他的用到的时候去查API

示例:

package cn.demo.jdbc;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;

/**
 * 数据库元对象,该对象保存了数据相关的信息
 */
public class Demo_08 {
	public static void main(String[] args) {
		try (Connection conn = DBUtils.getConn()) {
			// 获取数据库元数据对象
			DatabaseMetaData dbmd = conn.getMetaData();
			System.out.println("数据库名:"+dbmd.getDatabaseProductName());
			System.out.println("数据库驱动版本:"+dbmd.getDriverVersion());
			System.out.println("数据库用户名:"+dbmd.getUserName());
			
			// 获取表元数据对象需要先写查询
			String sql = "select * from emp";
			Statement s = conn.createStatement();
			ResultSet rs = s.executeQuery(sql);
			// 获取表元数据对象
			ResultSetMetaData rsmd = rs.getMetaData();
			// 获取字段数量
			int count = rsmd.getColumnCount();
			// 遍历每个字段的信息
			for(int i=0;i<count;i++) {
				String name = rsmd.getColumnName(i+1);
				String type = rsmd.getColumnTypeName(i+1);
				System.out.println(name+":"+type);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

// 打印结果如下:
数据库名:MySQL
数据库驱动版本:mysql-connector-java-5.1.6 ( Revision: ${svn.Revision} )
数据库用户名:root@localhost
EMPNO:INT
ENAME:VARCHAR
JOB:VARCHAR
MGR:INT
HIREdate:DATE
SAL:DOUBLE
COMM:DOUBLE
DEPTNO:INT
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值