JDBC: Java DataBase Connectivity (数据库连接) SUN公司提供的一套操作数据库的标准规范
JDBC与数据库驱动的关系:接口与实现的关系(数据库驱动作为实现,不同驱动不同实现,但都由相同的接口规范)
JDBC的四个规范接口
JDBC规范(掌握四个核心对象): DriverManager:用于注册驱动 Connection: 表示与数据库创建的连接 Statement: 操作数据库sql语句的对象 ResultSet: 结果集或一张虚拟表
低级JDBC
1.导入具体数据库厂商的驱动 (jar) 由相同的接口规范的不同的实现
//1.注册驱动 JBDC
//导入的com.mysql.jdbc.Driver:驱动(不同的驱动不同的名字)
DriverManager.registerDriver(new Driver());
//2.创建连接
//url jdbc:mysql://localhost:3306/mydb
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "111");
//3.创建statement
Statement st = connection.createStatement();
//4.装货
ResultSet rt = st.executeQuery("select * from student");
//5.处理结果
rt.next();
System.out.println("学生编号:"+rt.getString(1)+" 学员名字:"+rt.getString(2));
//6.关闭资源
rt.close();
st.close();
connection.close();
接口1 DriverManager
改进1**:注册驱动时
DriverManager.registerDriver(new Driver());实例化了两个Driver对象
原因:源码中静态代码块中new 了Driver对象
执行DriverManager.registerDriver(new Driver());也执行了静态代码块
Class.forName("类名")的主要作用是向虚拟机实例化一个Class实例。
源码:
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
// ~ Static fields/initializers
// ---------------------------------------------
//
// Register ourselves with the DriverManager
//
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
so :注册驱动使用Class.forName("com.mysql.jdbc.Driver"); 替换DriverManager.registerDriver(new Driver());
com.mysql.jdbc.Driver为驱动包的位置
getConnection(String url,String user,String password);
DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "111");
接口2 Connection
用于创建Statement!
Statement st = connection.createStatement();
关闭连接:connection.close();
接口3 Statement
具体将sql语句发送到数据库中
ResultSet rt = st.executeQuery("select * from student");
接口 4 ResultSet
结果集的处理
操作光标:next(); 光标向下移动一个! 如果有下一行数据 返回true没有返回false
默认情况下!光标指向第一行数据之前!
结果集封装到List<JavaBean>
ResultSetMetaData metaData = reSet.getMetaData();
List<NewJava> list = new ArrayList<NewJava>();
while(reSet.next()){
//创建java实体类对象
NewJava java = new NewJava();
//获取一共包含多少列
int count = metaData.getColumnCount()+1;
for (int i = 1; i <count; i++) {
//通过metaData能获取列数和列名等信息
//1.获取列名
String cname = metaData.getColumnName(i);
//2.根据列名获取对应的值
String result = reSet.getString(cname);
//要根据列名找到 对应的变量设置方法
PropertyDescriptor descriptor = new PropertyDescriptor(cname, NewJava.class);
/**
* 通过描述器获取对应的get/set方法
*/
// Method readMethod = descriptor.getReadMethod(); //获取get
Method method = descriptor.getWriteMethod(); //获取set
/**
* 参数1: 当前类的实体对象
* 参数2: 调用方法的参数
*/
method.invoke(java, result); //调用方法
}
//将实体类添加到集合中
list.add(java);
}
注入攻击
查询的值当做sql语句的逻辑处理了!!!
sql逻辑的部分要跟值的部分区分开
使用PreparedStatement代替Statement
PreparedStatement st = conn.prepareStatement(sql);
String sql = "select * from stu where sid = ? and sname = ? ;";
PreparedStatement st = conn.prepareStatement(sql);
st.setString(1, password);
st.setString(2, user);
//4.执行sql语句
ResultSet set = st.executeQuery();
封装jdbc c3p0 (工具类,包,配置文件)
c3p0连接池
工具类
package com.itqf.test;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/**
* 获取连接的工具类!
* 从c3p0连接池中获取
* @author admin
*
*/
public class JDBCUtils {
public static ComboPooledDataSource source = new ComboPooledDataSource();
public static DataSource getSource(){
return source;
}
//获取连接的方法
public static Connection getConnection() throws SQLException{
return source.getConnection();
}
//释放资源的方法
public static void close(ResultSet resultSet) {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void close(Statement statement) {
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void close(Connection connection) {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void close(Statement statement,Connection connection) {
close(statement);
close(connection);
}
public static void close(ResultSet resultSet,Statement statement,Connection connection) {
close(resultSet);
close(statement);
close(connection);
}
}
c3p0配置文件(修改参数)
文件名必须是 c3p0-config.xml 文件必须放在src下
<c3p0-config>
<!-- 默认配置,如果没有指定则使用这个配置 -->
<default-config>
<!-- 基本配置 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/xxxx</property>
<property name="user">root</property>
<property name="password">1234</property>
<!--扩展配置-->
<!-- 连接超过30秒报错-->
<property name="checkoutTimeout">30000</property>
<!--30秒检查空闲连接 -->
<property name="idleConnectionTestPeriod">30</property>
<property name="initialPoolSize">10</property>
<!-- 30秒不适用丢弃-->
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property>
</default-config>
<!-- 命名的配置 -->
<named-config name="zhaowf">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/xxxx</property>
<property name="user">root</property>
<property name="password">1234</property>
<!-- 如果池中数据连接不够时一次增长多少个 -->
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">20</property>
<property name="minPoolSize">10</property>
<property name="maxPoolSize">40</property>
<property name="maxStatements">20</property>
<property name="maxStatementsPerConnection">5</property>
</named-config>
</c3p0-config>
进阶 的dbutils 利用c3p0
c3p0 再导入一个包 就可直接写sql语句
QueryRunner runner=new QueryRunner(JDBCUtils.getSource());
String sql="insert into user (username,pwd,sex,headimg) values(?,?,?,?)";
int row = runner.update(sql, user.getUsername(),user.getPwd(),user.getSex(),user.getHeadimg());
return row;
String sql="select * from user where username = ? and pwd = ?";
User user= runner.query(sql, new BeanHandler<User>(User.class) , user.getUsername(),user.getPwd());
return user;
结果集还有:new BeanListHandler<Student>(Student.class);new ScalarHandler();