java使用jdbc操作数据库

一、概述

为了持久化&方便管理数据,出现了mysql、sqlserver等多种数据库,我们可以直接这些数据库中使用sql语言增删改查管理数据。但是对于业务人员来说不懂sql,没法通过sql直接在数据库操作,所以我们要通过程序提供对数据库的操作;

这些数据库厂商为了让编程语言操作自身数据库,提供了支持不同语言的驱动包、比如mysql驱动包、sqlserver包等

而编程语言也提供了对接驱动包的接口,java中就是java.sql接口包,几个关系如下

二、基本使用

1、连接

public void con(){
		//把几个用于连接数据库的字符串定义成常量,不必每次去创建,这些字符串也可以通过配置文件方式读取
		String USER = "root";//数据库用户名
		String UPWD = "root";//数据库密码
		//本地数据库shop
		String URL = "jdbc:mysql://localhost:3306/db_book";
		//驱动
		String DRIVER = "com.mysql.jdbc.Driver";
		Statement st = null;
		Connection con = null;
		try {
			//加载驱动
			Class.forName(DRIVER);
			//获取连接对象
			con = DriverManager.getConnection(URL, USER, UPWD);
			//获取执行对象
			st = con.createStatement();
			String sqlString = "create table stu(id int,name varchar(25),age int)";
			//执行sql
			int row = st.executeUpdate(sqlString);
			System.err.println(row);
			
		} catch (Exception e) {
			try {
				if(st != null) {
					st.close();
				}
			} catch (SQLException e2) {
				e2.printStackTrace();
			}
			try {
				if(con != null) {
					con.close();
				}
			} catch (SQLException e3) {
				e3.printStackTrace();
			}
		}
	}

2、api

int executeUpdate(String sql) throws SQLException;//执行insert update delete
ResultSet executeQuery(String sql) throws SQLException;用于执行sql语句
boolean execute(String sql) throws SQLException;//执行create drop 等ddl语句


boolean  next():判断是否有下一行数据,若有,则向下移动一行指针
getXxx(int columnIndex):获取当前行中,第几列.(从1开始):不推荐,
getXxx(String columnName):获取当前行中的,指定列名的列的值.columnName是列名/列的别名,若列的类型是VARCHAR/CHAR/TEXT,都使用getString来获取列的值.若列的类型是int/integer/-->getInt来获取列的值.
对于上面的getint  getstring()都可以使用getObject  或者都使用getString()

3、查询

  • 查询一个数

  • 查询一行数据

  • 查询多行数据

4、sql注入原理

select * from user where name = '123' and pass = '234' or 1=1
上面模拟登录 不管用户名密码对不对都能查到结果

5、Statement和Preparement(获取自动生成的主键)

statement

String sqlString = "insert into stu(name,age)value('123',20)";
			//执行sql
			st.executeUpdate(sqlString,st.RETURN_GENERATED_KEYS);
			
			ResultSet resultSet = st.getGeneratedKeys();
			if(resultSet.next()) {
				int id = resultSet.getInt(1);
				System.out.println(id);
			}

Preparement

String sqlString = "insert into stu(name,age)value(?,?)";
			
			PreparedStatement pStatement = con.prepareStatement(sqlString,Statement.RETURN_GENERATED_KEYS);
			pStatement.setString(1, "123");
			pStatement.setInt(2, 20);
			pStatement.executeUpdate();
			ResultSet resultSet = pStatement.getGeneratedKeys();
			if(resultSet.next()) {
				int id = resultSet.getInt(1);
				System.out.println(id);
			}

三、工具类

package pojo;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Properties;

/**
 * 封装的jdbc工具类
 * 
 * @author Administrator
 *
 */
public class MyJDBCUtil {
	// 定义数据库连接对象
	private static Connection con;
	// 定义执行sql对象
	private static PreparedStatement ps;
	// 定义结果集对象
	private static ResultSet rs;
	private static String driver;
	private static String url;
	private static String username;
	private static String password;

	// 工具类的构造器私有了,不让外部调用
	private MyJDBCUtil() {
	}

	// 下面的数据可以通过配置文件读取
	static {
		try {
			readConfig();
			Class.forName(driver);
			con = DriverManager.getConnection(url, username, password);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 读取配置文件
	private static void readConfig() {
		InputStream in = MyJDBCUtil.class.getClassLoader().getResourceAsStream("database.properties");
		System.out.println(in);
		Properties properties = new Properties();
		try {
			properties.load(in);
			driver = properties.getProperty("driver");
			url = properties.getProperty("url");
			username = properties.getProperty("username");
			password = properties.getProperty("password");
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	// 提供获取连接对象的公共方法
	public static Connection getConnection() {
		return con;
	}

	// 查询操作
	public static ResultSet excuteQuery(String sql, List params) throws SQLException {
		if (con == null || con.isClosed())// 连接对象是空 或者已经打开了就重新开启
		{
			getConnection();
		}
		ps = con.prepareStatement(sql);
		if (params != null && params.size() > 0) {
			for (int i = 0; i < params.size(); i++) {
				ps.setObject(i + 1, params.get(i));
			}
		}
		rs = ps.executeQuery();
		return rs;
	}

	// 更新操作
	public static int excuteUpdate(String sql, List params) throws SQLException {
		if (con == null || con.isClosed())// 连接对象是空 或者已经打开了就重新开启
		{
			getConnection();
		}
		ps = con.prepareStatement(sql);
		if (params != null && params.size() > 0) {
			for (int i = 0; i < params.size(); i++) {
				ps.setObject(i + 1, params.get(i));
			}
		}
		return ps.executeUpdate();
	}

	// 关闭资源
	public static void closeAll() {
		try {
			if (rs != null && !rs.isClosed()) {
				rs.close();
			}
			if (ps != null && !ps.isClosed()) {
				ps.close();
			}
			if (con != null && !con.isClosed()) {
				con.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

测试

public static void main(String[] args){
    String sql = "select * from tb_stu";
    ResultSet rs = MyJDBCUtil.excuteQuery(sql,null);
    while(rs.next()){
        System.out.priint(rs.getInt("id);
    }
    MyJDBCUtil.closeAll();
}
  

四、使用连接池操作数据库

1、不使用连接池缺点

每次CRUD操作都要使用数据库的时候,都要创建一个数据库连接对象;普通的JDBC数据库连接使用 DriverManager 来获取;每次向数据库建立连接的时候都要将 Connection 加载到内存中;然后再验证用户名和密码花费时间0.05s~1s左右;每次CRUD操作就向数据库要要一个连接

执行完成后再断开连接。这样的方式将会消耗大量的资源和时间。

2、连接池原理

数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的可以通过连接池的管理机制监视数据库的连接的数量﹑使用情况,为系统开发﹑测试及性能调整提供依据。与数据库连接

3、连接池分类

java中使用javax.sql.DataSource接口来表示连接池,DataSource和jdbc一样,也是只提供一个接口,由第三方组织来提供,DataSource数据源和连接池Connection Pool是同一个东西,只是叫法不一样而已

DBCP:Spring推荐,Tomcat的数据源使用的就是DBCP,也就是tomcat内置dbcp,单独使用dbcp需要2个包:commons-dbcp.jar,commons-pool.jar

C3P0:C3P0是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布;从2007年就没有更新了,性能比较差。

Druid:阿里巴巴提供的连接池-德鲁伊-号称最好的连接池,它里面除了这些, 还有更多的功能。

4、使用连接池

DBCP连接池

导入jar包

  • mysql-connector-java-5.0.4-bin.jar
  • commons-pool-1.5.6.jar
  • commons-dbcp-1.4.jar

src下编写database.properties文件

driverClassName

数据库名称

必填

url

数据库地址

必填

username

用户名

必填

password

密码

必填

maxActive

最大连接数量

选填

minldle

最小空闲连接

选填

maxldle

最大空闲连接

选填

initialSize

初始化连接

选填

工具类

package pojo;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;


public class DBCPUtils {
	private static DataSource dataSource;
	static{
		try {
			//1.加载找properties文件输入流
			InputStream is = DBCPUtils.class.getClassLoader().getResourceAsStream("database.properties");
			//(也可以使用流的方式加载)
			//FileInputStream is=  new FileInputStream("database.properties");
			//2.加载输入流
			Properties props = new Properties();
			props.load(is);
			//3.创建数据源
			dataSource = BasicDataSourceFactory.createDataSource(props);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	public static DataSource getDataSource(){
		return dataSource;
	}
	
	public static Connection getConnection(){
		try {
			return dataSource.getConnection();
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
}

测试
public class Test {
	public static void main(String[] args) {
		System.out.println(DBCPUtils.getDataSource());
		System.out.println(DBCPUtils.getConnection());
	}
}

C3p0连接池

c3p0-0.9.2.1.jar  
mysql-connector-java-5.1.10-bin.jar  
mchange-commons-java-0.2.3.4.jar

src下编写配置文件properties和xml两种,建议xml,文件名称(固定)c3p0-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
	<!-- 默认配置 -->
  <default-config>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
	<property name="jdbcUrl">jdbc:mysql:///db_jdbcdemo</property>
	<property name="user">root</property>
	<property name="password">root</property>
	<property name="initialPoolSize">5</property>
	<property name="maxPoolSize">20</property>
  </default-config>
  <!-- 命名配置 -->
  <named-config name="lph"> 
    <property name="driverClass">com.mysql.jdbc.Driver</property>
	<property name="jdbcUrl">jdbc:mysql:///db_jdbcdemo</property>
	<property name="user">root</property>
	<property name="password">root</property>
  </named-config>
</c3p0-config>

属性

解释

acquireIncrement

当连接池中的连接耗尽的时候c3p0一次同时获取的连接数 默认为:3

acquireRetryAttempts

定义在从数据库获取新连接失败后重复尝试的次数 默认为:30

acquireRetryDelay

两次连接中间隔时间,单位毫秒 默认为:1000

autoCommitOnClose

连接关闭时默认将所有未提交的操作回滚 默认为:false

automaticTestTable

c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么

属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试使用 默认为:null

breakAfterAcquireFailure

获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效

保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试

获取连接失败后该数据源将申明已断开并永久关闭 默认为:false

checkoutTimeout

当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出

SQLException,如设为0则无限期等待。单位毫秒 默认为:0

connectionTesterClassName

通过实现ConnectionTester或QueryConnectionTester的类来测试连接。类名需制定全路径

默认为:com.mchange.v2.c3p0.impl.DefaultConnectionTester

factoryClassLocation

指定c3p0 libraries的路径,如果(通常都是这样)在本地即可获得那么无需设置,默认null即可 默认为:null

idleConnectionTestPeriod

每60秒检查所有连接池中的空闲连接 默认为:0

initialPoolSize

初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间 默认为:3

maxIdleTime

最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃 默认为:0

maxPoolSize

连接池中保留的最大连接数 默认为:15

maxStatements

JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements

属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。

如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭 默认为:0

maxStatementsPerConnection

maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数 默认为:0

numHelperThreads

c3p0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能

通过多线程实现多个操作同时被执行 默认为:3

overrideDefaultUser

当用户调用getConnection()时使root用户成为去获取连接的用户。主要用于连接池连接非c3p0

的数据源时 默认为null

overrideDefaultPassword

与overrideDefaultUser参数对应使用的一个参数 默认为:null

user

用户名 默认为: null

password

密码 默认为:null

preferredTestQuery

定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个一显著提高测试速度。注意:

测试的表必须在初始数据源的时候就存在 默认为:null

propertyCycle

-用户修改系统配置参数执行前最多等待300秒 默认为:300

testConnectionOnCheckout

因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的

时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable

等方法来提升连接测试的性能 默认为:false

testConnectionOnCheckin

如果设为true那么在取得连接的同时将校验连接的有效性 默认为:false

工具类

package c3p0;

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

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0Utils {
	//使用默认配置
	//private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
	//使用命名配置
	private static ComboPooledDataSource dataSource = new ComboPooledDataSource("lph");
	//获得连接池(数据源)
	public static DataSource getDataSource() {
		return dataSource;
	}
	//获得连接
	public static Connection getConn() {
		try {
			return dataSource.getConnection();
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException("连接获取错误");
		}
	}
}

测试
public class Test {
	public static void main(String[] args) {
		//获取连接池
		System.out.println(C3P0Utils.getDataSource());
		//获取连接对象
		System.out.println(C3P0Utils.getConn());
	}
}

Druid连接池

导入druid-1.1.2.jar

五、dbutils操作数据库

dbutils是Apache公司编写的数据库操作实用的工具,小巧,简单,实用,封装了对JDBC的操作,简化了JDBC操作;需要导入驱动包和commons-dbutils-1.6.jar

1、核心功能

QueryRunner中提供对sql语句操作的api

ResultSetHandler接口用于定义select操作后怎么封装结果集

DbUtils类,工具类 定义了关闭资源与事务处理方法

2、QueryRunner

QueryRunner(DataSource ds)或者QueryRunner();如果使用带参数的是提供数据源连接池,会自动帮你创建连接,没有参数是不用连接池的

2.1 Update(String sql,Object...obj)执行更新数据

添加

删除

修改

2.2 执行查询query(String sql, ResultSetHandler<T> rsh,Object...params)params数组可有可无 、可多可少  、可直接写或者传数组

3、ResultSetHandler查询操作和处理

第一种:new ArrayHandler()

第二种:new ArrayListHandler()

第三种:new BeanHandler<User>(User.class)

第四种new BeanListHandler<User>(User.class)

第五种new ColumnListHandler<>(“列名”)

第六种query(sql, new ScalarHandler())

第七种new MapHandler()

第八种new MapListHandler()

总结

query参数是连接对象、 sql语句、 ResultHandler接口的实现类、参数数组(一个/多个/没有/传递);query返回值 泛型,根据结果集处理类变化;说明:如果参数中有con就是没有使用连接池的

  • ArrayHandler:把结果集中的第一行数据转成对象数组。
  • ArrayListHandler:把结果集中的每一行数据都转成一个对象数组,再存放到List中。
  • BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
  • BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。//重点
  • MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。//重点**
  • MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
  • ColumnListHandler:将结果集中某一列的数据存放到List中。
  • KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里(List),再把这些map再存到一个map里,其key为指定的列。
  • ScalarHandler:将结果集第一行的某一列放到某个对象中。//重点

4、DbUtils

DbUtils.closeQuietly(con);关闭资源

六、dbutils结合连接池操作数据库

导入jar以及配置文件

编写工具类

选择连接池中的工具列(工具类中的getConn方法可以去掉 只留下获取数据源的即可)

举例:不使用配置文件的德鲁伊工具类
import com.alibaba.druid.pool.DruidDataSource;
public class Pool {
	private static DruidDataSource dataSource = null;
	static {
		dataSource = new DruidDataSource();
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUrl("jdbc:mysql://localhost:3306/1808?characterEncoding=utf-8");// 设置连接的数据库
		dataSource.setUsername("root");// 设置用户名
		dataSource.setPassword("");// 设置密码
	}

	public static DruidDataSource getDataSource() {
		return dataSource;
	}
}

测试

import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayListHandler;

public class Test {
	//使用有参数的方法传递数据源
	private  static QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
	//插入操作
	public static void insert() {
		String sql = "insert into user(name,pass)values(?,?)";
		Object[] params  = {"xixi","345"};
		try {
			//此时不必要串连接对象
			int row  =qr.update(sql,params);
			System.out.println(row);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
	}
	public static void select() {
		String sql = "select * from user";
		try {
			List<Object[]> list = qr.query(sql, new ArrayListHandler());
			for(Object[] ojbs:list) {
				for(Object obj:ojbs) {
					System.out.println(obj);
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {	
		insert();
		select();
	}	
}

总结

QueryRunner里面要传递数据源对象,由工具类获取,操作和不用连接池一样,知识参数不再传递连接对象,操作数据库建议使用这种dbutils和和连接池结合的方式

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
使用Java中的JDBC连接数据库,首先需要准备好相关的工具和配置。可以参考以下步骤: 1. 引用所提供的第一份文献介绍了使用JDBC连接数据库的工具类和示例代码,可以作为参考。 2. 需要在项目中添加MySQLJDBC驱动程序依赖。可以使用Maven等构建工具,在项目的pom.xml文件中添加以下依赖项: ```xml <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.37</version> </dependency> ``` 3. 注册MySQLJDBC驱动程序。可以使用以下代码中的任意一种方式注册驱动程序: ```java Class.forName("com.mysql.jdbc.Driver"); ``` 或者 ```java System.setProperty("jdbc.drivers", "com.mysql.jdbc.Driver"); ``` 4. 连接到MySQL数据库。需要提供数据库的URL、用户名和密码。可以使用以下代码创建数据库连接: ```java private static final String DB_URL = "jdbc:mysql://localhost:3306/test"; private static final String USER = "root"; private static final String PASS = "123456"; private Connection conn = DriverManager.getConnection(DB_URL, USER, PASS); ``` 注意,以上代码中的DB_URL、USER和PASS需要根据实际情况进行修改。 5. 现在可以通过创建Statement或PreparedStatement对象来执行SQL语句并与数据库进行交互。 这些步骤可以帮助您使用Java中的JDBC连接到MySQL数据库。希望对您有所帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [java使用jdbc连接数据库工具类和jdbc连接mysql数据示例](https://download.csdn.net/download/weixin_38502929/12810866)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Java使用JDBC连接数据库](https://blog.csdn.net/qq_27870421/article/details/87958738)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Java-JDBC连接数据库](https://blog.csdn.net/rbx508780/article/details/127285877)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序三两行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值