JDBC
JDBC:java database connectivity java 连接数据库
JDBC其实就是Java定义的一套和数据库建立连接的规范(接口),那么各家数据库厂商,想要java去操作各家的数据库,必须实现这套接口,我们把数据库厂商写的这套实现类称之为数据库驱动。
package com.itheima;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class demo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//JDBC:快速入门
//1.引入MySQL的驱动jar包,记得依赖一下。
//2.加载驱动
//3.获取连接对象。
//4.获取操作对象
//5.发送SQL语句进行操作。
//6.释放资源。
//2.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//3.获取连接对象。
String url="jdbc:mysql://localhost:3306/mydb";
String username="root";
String password="123456";
Connection conn = DriverManager.getConnection(url, username, password);
//4.获取操作对象
Statement statement = conn.createStatement();
//5.发送SQL语句进行操作。
String sql="insert into product(name) values('裤子') ";
//执行executeUpdate(sql) 增删改的语句
int l = statement.executeUpdate(sql);
if(l>0){
System.out.println("插入成功");
}else{
System.out.println("插入失败");
}
//6.释放资源。
conn.close();
statement.close();
}
}
Class.forName("com.mysql.jdbc.Driver"); 加载驱动,也可以省略不写
注册驱动这个动作是Driver里面有个静态代码块在做
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
几个类的介绍
类 DriverManager Java提供的管理一组 JDBC 驱动程序的基本服务。
接口 Connection 试图建立到给定数据库URL的连接
接口 Statement 用于执行静态代码 SQL 语句并返回它所生成结果的对象。
boolean b = statement.execute(sql);//用来执行所有的SQL语句 返回:
如果第一个结果为 ResultSet 对象,则返回 true;如果其为更新计数或者不存在任何结果,则返回 false
int i = statement.executeUpdate(sql);//用来执行DML语句 用来对表中数据进行增删改 返回值是影响的行数
statement.executeQuery(sql);//用来执行DQl语句
package com.itheima;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class demo1 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//3.获取连接对象
//DriverManager 管理一组 JDBC 驱动程序的基本服务。
// 试图建立到给定数据库 URL 的连接。DriverManager 试图从已注册的 JDBC 驱动程序集中选择一个适当的驱动程序。
//URL:统一资源定位符,格式:协议://ip:端口/具体的资源路径
//主协议:子协议://ip:端口/资源路径
//如果是本地连接:ip和端口可以省略不写 "jdbc:mysql:///mydb"
// String url = "jdbc:mysql://192.168.17.123:3306/mydb"; 写ip MySQL需要设置了远程访问
//获取连接对象
String url="jdbc:mysql://localhost:3306/mydb";
String username="root";
String password="123456";
Connection conn = DriverManager.getConnection(url, username, password);
//Connection 接口 与特定数据库的连接(会话)。在连接上下文中执行 SQL 语句并返回结果。
//获取操作对象
Statement statement = conn.createStatement();
// 接口 Statement 用于执行静态 SQL 语句并返回它所生成结果的对象。
//5.发送SQL语句进行操作。
String sql="insert into product(name) values('水果') ";
//executeUpdate(sql); 执行的 DML 语句
//ResultSet executeQuery(String sql) 执行DQL语句
// 执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。
// boolean execute (String sql)执行任意的SQL语句。
int i = statement.executeUpdate(sql);
if(i>0){
System.out.println("插入成功");
}else{
System.out.println("插入失败");
}
//释放资源
conn.close();
statement.close();
}
}
结果集对象 ResultSet
结果集对象是执行了查询语句之后返回的一个查询结果对象。
ResultSet 对象具有指向其当前数据行的光标。 最初,光标被置于第一行之前。next 方法将光标移动到下一行;因为该方法在 ResultSet 对象没有下一行时返回 false,所以可以在 while循环中使用它来迭代结果集。
while (resultSet.next()){
//参数就是数据库中的字段序号 从1开始
//String username = resultSet.getString(1);
//int age = resultSet.getInt(2);
//通过字段名来获取字段的值
String username = resultSet.getString("username");
int age = resultSet.getInt("age");
//System.out.println(username+"==="+age);
//我们从数据库中取出了数据,就是为了要使用这些数据,那我们就要对这些数据进行封装
Student student = new Student(username, age);
list.add(student);
}
package com.itheima;
public class MyLog {
private int id;
private String name;
private int price;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "MyLog{" +
"id=" + id +
", name='" + name + '\'' +
", price=" + price +
'}';
}
}
package com.itheima;
import com.sun.org.apache.regexp.internal.RE;
import java.sql.*;
import java.util.ArrayList;
public class Test1 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mydb";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, username, password);
Statement statement = conn.createStatement();
String sql = "select * from product";
//执行DQL语句
//ResultSet 结果集对象,封装的的查询出的多条结果
//resultSet.next() 往下移动指针,如果没有了数据,就返回false;
ResultSet resultSet = statement.executeQuery(sql);
ArrayList<MyLog> list = new ArrayList<>();
while (resultSet.next()) {
//可以传入列名,或者列号
int id = resultSet.getInt("id");
// 列号从1开始 int anInt = resultSet.getInt(1);
String name = resultSet.getString("name");
int price = resultSet.getInt("price");
//将数据查询出来打印在控制台
// System.out.println(id+"--"+name+"--"+price);
//我们从数据库查出了数据,要在别的地方用,你应该把查询出的数据封装起来。
MyLog myLog = new MyLog();
myLog.setId(id);
myLog.setName(name);
myLog.setPrice(price);
//把资源放到集合中
list.add(myLog);
}
System.out.println(list);
conn.close();
statement.close();
resultSet.close();
}
}
数据库实现用户登录
package com.itheima;
import java.sql.*;
import java.util.Scanner;
//登录 数据存储在数据库中cherry
public class Test2 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名");
String name = sc.nextLine().trim();
System.out.println("请输入用户密码");
String pwd = sc.nextLine().trim();
// 查询数据库比对是否输入正确
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mydb2";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, username, password);
Statement statement = conn.createStatement();
//定义sql语句
String sql = "select *from user where username='+name+'and password='+pwd+'";
ResultSet resultSet = statement.executeQuery(sql);
if (resultSet.next()) {
System.out.println("登录成功");
} else {
System.out.println("登录失败");
}
//释放资源
conn.close();
statement.close();
resultSet.close();
}
}
SQL注入
SQL注入是指web应用程序对用户输入数据的合法性没有判断或过滤不严。
攻击者可以在web应用程序中将事先定义好的查询语句的结尾添上额外的SQL语句,
在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
预编译操做对象 PreparedStatement
这个操作对象,可以在安全方面防止SQL注入
使用步骤:1.conn.prepareStatement(sql);
2.sql语句中的字段的值用?问号占位
3.给sql语句中的问号赋值
//SQL语句中的值 全部用 ? 问号占位
String sql="SELECT * FROM users WHERE username=? AND PASSWORD=?";
//获取一个预编译操作对象 PreparedStatement
PreparedStatement preparedStatement = conn.prepareStatement(sql); //把SQL语句给给这个预编译操作对象
//下来给问号赋值 参1.问号的顺序,从1开始数 参数2 问号的值
preparedStatement.setString(1,uname);
preparedStatement.setString(2,pwd);
ResultSet resultSet = preparedStatement.executeQuery(); //这里就不要再传入SQL语句
package com.itheima;
import java.sql.*;
public class Test3 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mydb2";
String username = "root";
String password = "123456";
//建立连接
Connection connection = DriverManager.getConnection(url, username, password);
//定义编译语句
String sql= "insert into user(username,password) values(?,?)";
String sql2="select * from user where username='lisa1'";
//获取预编译对象
PreparedStatement preparedStatement2 = connection.prepareStatement(sql2);
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,"lisa1");
preparedStatement.setString(2,"654321");
//开始查询是否存在
ResultSet resultSet = preparedStatement2.executeQuery();
if(resultSet.next()){
//存在
System.out.println("注册失败");
}else{
//不存在 开始注册
int i = preparedStatement.executeUpdate();
if(i>0){
System.out.println("插入成功");
}else{
System.out.println("插入失败");
}
}
}
}
批处理
在插入大量的数据的时候使用批处理来做。
statement.addBatch();//添加批处理,先将数据缓存起来
statement.executeBatch();//执行批处理
statement.clearBatch();//清空缓存
JDBC 调用存储过程和函数 CallableStatement
调用存储过程 {call <procedure-name>[(<arg1>,<arg2>, ...)]}
Connection conn = JDBCUtils.getConnection();
String sql="{call testPro(?,?)}"; //输入或输出参数用?占位
CallableStatement prepareCall = conn.prepareCall(sql);
//给输入参数设置值
prepareCall.setInt(1,7369);
//如果有输出参数我们需要注册输出参数
prepareCall.registerOutParameter(2, Types.INTEGER);
boolean b = prepareCall.execute();
//获取输出结果
int r = prepareCall.getInt(2);
System.out.println(r);
//释放资源
JDBCUtils.close(conn,prepareCall);
调用自定义函数 {?=call<procedure -name >[( < arg1 >,<arg2 >, ...)]}
String sql="{?=call testFun(?)}";
CallableStatement callableStatement = conn.prepareCall(sql);
//设置输入参数
callableStatement.setInt(2,7902);
//注册返回值
callableStatement.registerOutParameter(1, Types.INTEGER);
callableStatement.execute();
//获取返回的结果
int r = callableStatement.getInt(1);
System.out.println("结果是:"+r);
//释放资源
JDBCUtils.close(conn,callableStatement);
获取自增长键的值
要获取自增长键的值 需要在获取操作对象时声明一个参数 Statement.RETURN_GENERATED_KEYS
PreparedStatement preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
2.当数据插入成功后,就可以取出这个自增长键的值
//获取自增长键的结果集
ResultSet generatedKeys = preparedStatement.getGeneratedKeys();
while (generatedKeys.next()){
keyValue = generatedKeys.getInt(1);
}
3.你在其他表中就可以使用这个自增长键的值
事务
基本 概念:事务是指一组最小逻辑的操作单元,里面有多个操作组成。组成事务的每一部分必须要同时提交成功,如果有一个操作失败,整个操作就会回滚。
事务ACID特性
原子性(Atomicity):原子性是指事务是一个不可分割的工作单元,事务中的操作要么都发生,要么都不发生。
一致性(Consistency):事务必须使数据库从一个一致性状态变换到另一个一致性状态。
隔离性(isolation):事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的数据所干扰,多个并发事务之间要相互隔离。
持久性(Durability):持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
一般情况下,Connection对象处于自动提交的模式下,这意味着它在执行每个语句后都会自动提交更改。
如果禁用了自动提交模式,那么提交更改就必须显示调用。
commit 方法;否则无法保存数据库更改。
//void setAutoCommit ( boolean autoCommit) throws SQLException将此连接的自动提交模式设置为给定状态。如果连接处于自动提交模式下,则它的所有 SQL 语句将被执行并作为单个事务提交。否则,它的 SQL 语句将聚集到事务中,
//直到调用 commit 方法或 rollback 方法为止。默认情况下,新连接处于自动提交模式。
模式银行的转账
Connection conn1= JDBCUtils.getConnection();
//减钱
String sql1="update bank set money=money-1000 where username='zhangsan'";
//加钱
String sql2="update bank set money=money+1000 where username='lisi'";
//获取操作对象
PreparedStatement preparedStatement1 = conn1.prepareStatement(sql1);
PreparedStatement preparedStatement2= conn1.prepareStatement(sql2);
//执行操作 减去钱 自动开启了一个事务 执行完 提交事务,数据就持久化
preparedStatement1.executeUpdate();
//模拟异常
System.out.println(1/0);
//加上钱 自动开启了一个事务 提交事务,数据就持久化
preparedStatement2.executeUpdate();
conn1= JDBCUtils.getConnection();
//把自动提交事务,改成手动提交事务。
conn1.setAutoCommit(false);
//减钱
String sql1="update bank set money=money-1000 where username='zhangsan'";
//加钱
String sql2="update bank set money=money+1000 where username='lisi'";
//获取操作对象
PreparedStatement preparedStatement1 = conn1.prepareStatement(sql1);
PreparedStatement preparedStatement2= conn1.prepareStatement(sql2);
//执行操作 减去钱 自动开启了一个事务 执行完 提交事务,数据就持久化
preparedStatement1.executeUpdate();
//模拟异常
System.out.println(1/0);
//加上钱 自动开启了一个事务 自动提交事务,数据就持久化
preparedStatement2.executeUpdate();
//默认清空下,减钱 是一个事务,加钱是一个事务,我们应该把减钱和加钱这两部操作,放到同一个事务中。
} catch (Exception e) {
e.printStackTrace();
//一旦遇到异常,就回滚事务
try {
conn1.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
}finally {
try {
conn1.commit(); //手动提交事务
//释放资源
} catch (SQLException e) {
e.printStackTrace();
}
}
事务的隔离级别
不考虑隔离性会出现的读问题:
脏读:在一个事务中读取到另一个事务没有提交的数据。
不可重复读:在一个十五中,两次查询的结果不一致,这种情况主要针对的是update操作,不可重复读,是指在数据库访问中,一个事务范围内两个相同的查询却返回了不同的数据。
虚读:也称为幻读,在一个事务中,两次查询的结果不一致 这个主要针对的是insert操作,mysql默认避免。
通常可以通过设置数据库的隔离级别来避免上面的问题;
read uncommitted 读未提交 上面的三个问题都会出现
read committed 读已提交 可以避免脏读的发生 Oracle 默认级别
repeatable read 可重复读 可以避免脏读和不可重复读的发生 MySQL 默认级别
serializable 串行化 可以避免所有的问题
四种隔离级别的效率:
read uncommitted>read committed>repeatable read>serializable
四种隔离级别的安全性
read uncommitted<read committed<repeatable read<serializable
开发中是不允许脏读的发生的;
mysql中默认级别:repeatable read
oracle中默认级别:read committed
模拟银行操作:
Connection conn1 =null;
Savepoint savepoint=null;
try {
conn1= JDBCUtils.getConnection();
//把自动提交事务,改成手动提交事务。
conn1.setAutoCommit(false);
//减钱
String sql1="update bank set money=money-1000 where username='zhangsan'";
//加钱
String sql2="update bank set money=money+1000 where username='lisi'";
//获取操作对象
PreparedStatement preparedStatement1 = conn1.prepareStatement(sql1);
PreparedStatement preparedStatement2= conn1.prepareStatement(sql2);
//执行操作 减去钱 自动开启了一个事务 执行完 提交事务,数据就持久化
preparedStatement1.executeUpdate();
//模拟异常
//System.out.println(1/0);
//加上钱 自动开启了一个事务 自动提交事务,数据就持久化
preparedStatement2.executeUpdate();
//设置回滚点
savepoint = conn1.setSavepoint();
System.out.println("----------------------------------------");
//减钱
String sql3 = "update bank set money=money-500 where username='zhangsan'";
//加钱
String sql4 = "update bank set money=money+500 where username='lisi'";
//获取操作对象
PreparedStatement preparedStatement3 = conn1.prepareStatement(sql3);
PreparedStatement preparedStatement4 = conn1.prepareStatement(sql4);
//执行操作 减去钱 自动开启了一个事务 执行完 提交事务,数据就持久化
preparedStatement3.executeUpdate();
//模拟异常
System.out.println(1/0);
//加上钱 自动开启了一个事务 自动提交事务,数据就持久化
preparedStatement4.executeUpdate();
//默认清空下,减钱 是一个事务,加钱是一个事务,我们应该把减钱和加钱这两部操作,放到同一个事务中。
} catch (Exception e) {
e.printStackTrace();
//一旦遇到异常,就回滚事务
try {
// conn1.rollback();
conn1.rollback(savepoint); //回滚到,回滚点的地方
} catch (SQLException ex) {
ex.printStackTrace();
}
}finally {
try {
conn1.commit(); //手动提交事务
//释放资源
} catch (SQLException e) {
e.printStackTrace();
}
}
}
常见连接池的使用
连接池:通过连接池预先同数据库建立一些连接,放在内存中,应用程序需要建立数据库连接时到连接池中申请就行,使用完毕之后再归还到连接池中。
数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个,释放空间时间超过最大空闲时间的数据库连接来避免避免因为没有释放数据库连接而引起的数据库连接漏洞了,这项技术能明显提高对数据库操作的性能。
连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。而连接的建立、断开都由连接池自身来管理。同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数以及每个连接的最大使用次数、最大空闲时间等等。也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等
三种连接池的介绍
DBCP连接池
DBCP(DataBase Connection Pool)数据库连接池,
是Java数据库连接池的一种,由Apache开发,通过数据库连接池,
可以让程序自动管理数据库连接的释放和断开
使用步骤:
1.导入jar包(commons-dbcp-1.4.jar和commons-pool-1.5.6.jar)
2.使用api
a.硬编码
a.硬编码(不推荐)
//创建连接池
BasicDataSource ds = new BasicDataSource();
//配置信息
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql:///day07");
ds.setUsername("root");
ds.setPassword("1234");
Connection conn=ds.getConnection();
String sql="insert into category values(?,?);";
PreparedStatement st=conn.prepareStatement(sql);
//设置参数
st.setString(1, "c011");
st.setString(2, "饮料");
int i = st.executeUpdate();
System.out.println(i);
采用配置文件的方式
//存放配置文件
Properties prop = new Properties();
prop.load(new FileInputStream("src/dbcp.properties"));
//设置
//prop.setProperty("driverClassName", "com.mysql.jdbc.Driver");
//创建连接池
DataSource ds = new BasicDataSourceFactory().createDataSource(prop);
Connection conn=ds.getConnection();
String sql="insert into category values(?,?);";
PreparedStatement st=conn.prepareStatement(sql);
//设置参数
st.setString(1, "c012");
st.setString(2, "饮料1");
int i = st.executeUpdate();
System.out.println(i);
采用该连接池实现查询功能:
package com.itheima.demo;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import javax.sql.DataSource;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
public class DBCPTest {
public static void main(String[] args) throws Exception {
Properties pp = new Properties();
pp.load(new FileReader("dbcp.properties"));
DataSource ds = BasicDataSourceFactory.createDataSource(pp);
Connection conn = ds.getConnection();
//建立连接对象
PreparedStatement preparedStatement = conn.prepareStatement("select * from user");
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
int anInt = resultSet.getInt(1);
System.out.println(anInt);
String string = resultSet.getString(2);
System.out.println(string);
}
preparedStatement.close();
resultSet.close();
}
}
C3P0连接池
C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate、Spring等。
c3p0与dbcp区别
dbcp没有自动回收空闲连接的功能
c3p0有自动回收空闲连接功能
使用步骤:
1.导入jar包(c3p0-0.9.1.2.jar)
2.使用api
方式1:硬编码
ComboPooledDataSource ds = new ComboPooledDataSource();
//设置基本参数
ds.setDriverClass("com.mysql.jdbc.Driver");
ds.setJdbcUrl("jdbc:mysql:///day07");
ds.setUser("root");
ds.setPassword("1234");
Connection conn=ds.getConnection();
String sql="insert into category values(?,?);";
PreparedStatement st=conn.prepareStatement(sql);
//设置参数
st.setString(1, "c013");
st.setString(2, "毒药");
int i = st.executeUpdate();
System.out.println(i);
采用配置文件的方式
b.配置文件
要求1:配置文件的名称:c3p0.properties 或者 c3p0-config.xml
要求2:配置文件的路径:src下
编码只需要一句话
new ComboPooledDataSource()//使用默认的配置
//可以切换xml配置文件中的标签 来加载不同的配置比如更换Orecal的数据库的配置
new ComboPooledDataSource(String configName)//使用命名的配置 若配置的名字找不到,使用默认的配置
package com.itheima.demo;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class C3P0Test {
public static void main(String[] args) throws SQLException {
ComboPooledDataSource ds = new ComboPooledDataSource();
Connection connection = ds.getConnection();
// System.out.println(connection);
String sql="select *from user'";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()){
String name = resultSet.getString(1);
String pwd = resultSet.getString(2);
System.out.println("查询成功");
System.out.println(name);
System.out.println(pwd);
}
preparedStatement.close();
resultSet.close();
}
}
//如果传入 xml配置文件中的第二配置名,那就读取第二配置
ComboPooledDataSource ds = new ComboPooledDataSource("myname");
Druid 阿里德鲁伊连接池
DRUID是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0、DBCP、PROXOOL等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针对监控而生的DB连接池(据说是目前最好的连接池,不知道速度有没有BoneCP快)。
使用步骤,导入德鲁伊的jar包
1.采用硬编码的方式
//采用硬编码的方式来创建连接池
DruidDataSource dataSource = new DruidDataSource();
//设置参数
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUsername("root");
dataSource.setPassword("123456");
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/crm");
dataSource.setInitialSize(5);
dataSource.setMinIdle(1);
dataSource.setMaxActive(10);
//获取连接对象
DruidPooledConnection connection = dataSource.getConnection();
System.out.println(connection);
2.采用配置文件的方式,
a.引入配置文件
b.加载配置文件
//采用加载配置文件的方式
Properties properties = new Properties();
properties.load(new FileInputStream("src/db_server.properties"));
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
Connection conn = dataSource.getConnection();
System.out.println(conn);
package com.itheima.demo;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.FileReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
public class DruidTest {
public static void main(String[] args) throws Exception {
Properties properties = new Properties();
properties.load(new FileReader("druid.properties"));
DataSource ds = DruidDataSourceFactory.createDataSource(properties);
Connection connection = ds.getConnection();
String sql="select * from user where username='cherry'";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()){
String name = resultSet.getString(1);
String pwd = resultSet.getString(2);
System.out.println(name);
System.out.println(pwd);
}
resultSet.close();
preparedStatement.close();
}
}
Commons DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,
使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能。
使用步骤:
1.导入jar包(commons-dbutils-1.4.jar)
2.创建一个queryrunner类
queryrunner作用:操作sql语句
构造方法:
new QueryRunner(Datasource ds);
3.编写sql
4.执行sql
query(..):执行r操作
update(...):执行cud操作
使用步骤
// 创建对象
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
// 定义sql
String sql = "insert into bank(username,money) values(?,?)";
// 执行sql
runner.update(sql,"赵六",500);
....
执行查询后返回的结果集
ResultSetHandler:封装结果集 接口
BeanListHandler, 将查询结果的每一条记录封装成指定的bean对象,将每一个bean对象放入list中 返回.