为热爱编程的你点赞!
学习SpringBoot实战课程 https://edu.csdn.net/course/detail/31433
学习SpringCloud入门课程 https://edu.csdn.net/course/detail/31451
项目开发离不开数据库,JDBC是Java数据库开发必须要掌握的技术。
JDBC(Java Database Connectivity,Java数据库连接)作用是:连接数据库,对表中的数据进行增删改查操作
在java.sql包下
类名 | 说明 |
---|---|
DriverManager | 驱动管理器类,管理数据库驱动,获得数据库连接 |
Connection | 连接类,连接数据库 |
Statement | 命令接口,发送SQL命令给数据库 |
PreparedStatement | 预编译命令接口,命令接口的子接口 |
ResultSet | 结果集,保存查询的数据 |
用于管理驱动,并获得连接对象:
URL字符串写法:
jdbc:mysql://数据库服务器地址:3306/数据库名?参数=值&参数=值
URL参数:
参数名 | 说明 |
---|---|
user | 账号 |
password | 密码 |
useSSL | 是否加密传输 true/false |
useUnicode | 是否使用Unicode字符 true/false |
characterEncoding | 指定编码类型 |
serverTimezone | 时区 |
通过TCP/IP协议实现和数据库的通信,实现连接
常用方法:
方法名 | 说明 |
---|---|
createStatement() | 创建Statement对象 |
prepareStatement(String sql) | 创建PreparedStatement对象 |
setAutocommit() | 设置是否自动提交 |
beginTransaction() | 启动事务 |
commit() | 提交事务 |
rollback() | 回滚事务 |
close() | 关闭连接 |
用于向数据库发送SQL命令
常用方法:
方法名 | 说明 |
---|---|
ResultSet executeQuery(SQL语句) | 执行查询语句 |
int executeUpdate(SQL语句) | 执行增删改语句 |
close() | 关闭命令 |
用于查询数据
常用方法:
方法名 | 说明 |
---|---|
boolean next() | 移动到下一行,返回是否到了末尾 |
boolean first() | 移动第一行,返回是否有数据 |
boolean last() | 移动到最后一行,返回是否有数据 |
String getString(“列名” 或 列索引) | 获得某一列的字符串值 |
int getInt(“列名” 或 列索引) | 获得某一列的整数值 |
/**
* 测试查询功能
*/
public class TestQuery {
public static final String URL = "jdbc:mysql://localhost:3306/mydb";
static{
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
@Test
public void testJDBC(){
try (Connection conn = DriverManager.getConnection(URL,"root","123456")){
Statement statement = conn.createStatement();
String sql = "insert into students(stu_name,stu_age,stu_gender,stu_class_id) values(‘张三’,20,‘男’,1)";
int rows = statement.executeUpdate(sql);
if(rows > 0){
System.out.println("执行成功");
}else{
System.out.println("执行失败");
}
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Test
public void testQuery(){
try(Connection conn = DriverManager.getConnection(URL,"root","123456")){
Statement st = conn.createStatement();
String sql = "select * from students";
//执行查询操作,返回结果集
ResultSet rs = st.executeQuery(sql);
//循环访问每一行
while(rs.next()){
//访问每一列
System.out.println("编号:"+rs.getInt("stu_id"));
System.out.println("姓名:"+rs.getString("stu_name"));
System.out.println("年龄:"+rs.getInt("stu_age"));
System.out.println("性别:"+rs.getString("stu_gender"));
System.out.println("班级:"+rs.getInt("stu_class_id"));
}
rs.close();
}catch(SQLException ex){
ex.printStackTrace();
}
}
}
Statement的子接口
优点:对SQL语句进行了预编译,数据库可以直接执行,更加高效和安全。
创建方法:
Connection对象.prepareStatement("SQL语句");
常用方法:
方法名 | 说明 |
---|---|
setXXX(占位符位置,值) | 给占位符赋值,如:setInt、setString、setFloat… |
ResultSet executeQuery() | 执行查询 |
int executeUpdate() | 执行增删改 |
当需要操作大量数据时,默认情况下JDBC会单独编译和发送每一条SQL语句,执行效率比较低。
批处理:将多条语句打包,一起编译,一起发送给数据库,数据库一起执行。
实现方法:
/**
* 测试批处理
*/
public class TestBatch {
public static final String URL = "jdbc:mysql://localhost:3306/mydb?user=root&password=123456";
static{
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//添加多个学生的信息
public void addStudents(List students){
try(Connection conn = DriverManager.getConnection(URL)){
//关闭自动提交
conn.setAutoCommit(false);
String sql = "insert into students(stu_name,stu_age,stu_gender,stu_class_id) values(?,?,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
for(Student stu : students){
//添加一个学生的信息
ps.setString(1, stu.getStu_name());
ps.setInt(2,stu.getStu_age());
ps.setString(3, stu.getStu_gender());
ps.setInt(4, stu.getStu_class_id());
//添加到批处理
ps.addBatch();
}
//执行批处理
ps.executeBatch();
//数据库提交
conn.commit();
}catch(SQLException ex){
ex.printStackTrace();
}
}
@Test
public void testBatch(){
List students = Arrays.asList(new Student(1,"马八",20,"男",1),
new Student(1,"马大八",30,"男",1),new Student(1,"马小八",10,"男",1));
addStudents(students);
}
}
创建数据库连接对象需要消耗比较多时间和内存,连接池开辟一个池,在池中放置一定数量的连接对象,用户使用连接对象后,连接不会直接销毁,而是回到池中,做其它操作时可以直接利用,减少连接对象的创建次数,从而提高程序的性能。
步骤
配置文件
src下添加:c3p0-config.xml
com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/mydb
root
123456
10
30
100
10
200
案例:使用JDBC+连接池+反射编写基本的ORM框架
常见的ORM(对象关系映射)框架,如Hibernate、MyBatis能通过对Java对象的操作,完成对数据库的增删改查,下面模拟其中的保存操作。
需求:
问题:
分析:
/**
* JDBC工具类
*/
public class JDBCUtils {
//连接池对象
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
/**
* 保存任意对象的数据到表中
* @param obj
*/
public static void save(Object obj){
//获得对象的类型对象
Class clazz = obj.getClass();
//获得类名
String className = clazz.getSimpleName();
StringBuilder stb = new StringBuilder("insert into ");
stb.append(className+"(");
//获得所有的属性
Field[] fields = clazz.getDeclaredFields();
//i = 1跳过第一列自动增长主键
for(int i = 1;i < fields.length;i++){
stb.append(fields[i].getName()+",");
}
//删除最后的,
stb.deleteCharAt(stb.length() - 1);
stb.append(") values (");
//添加?
for(int i = 1;i < fields.length;i++){
stb.append("?,");
}
//删除最后的,
stb.deleteCharAt(stb.length() - 1);
stb.append(")");
System.out.println("test sql--- "+stb.toString());
//添加数据
try(Connection conn = dataSource.getConnection()){
PreparedStatement ps = conn.prepareStatement(stb.toString());
//设置SQL语句中的参数
for(int i = 1;i < fields.length;i++){
String fname = fields[i].getName();
String mname = "get" + fname.substring(0, 1).toUpperCase() + fname.substring(1);
System.out.println("method:"+mname);
//调用方法获得返回值,给SQL参数赋值
Method m = clazz.getMethod(mname);
ps.setObject(i, m.invoke(obj));
}
//执行SQL
ps.executeUpdate();
System.out.println("添加完成!!!");
}catch(Exception ex){
ex.printStackTrace();
}
}
}
作业:定义findAll方法,查询不同的表,返回不同类型的集合
问题:
分析:
public static List findAll(String sql,Class clazz){
}
大家如果需要学习其他Java知识点,戳这里 超详细的Java知识点汇总