一.JDBC概述
1.数据的持久化
把数据存储在可掉电设备上存储,雏菊花多数是由关系数据库完成。
2.JDBC的理解
JDBC是sun公司提供的一套API,用来操作访问数据库。(DML,DCL,DDL操作,连接释放资源)
3.图示理解
好处:
1.面向接口编程,不需要关注底层细节
2.数据库厂商只需要实现这套接口就可以被改语言访问
4.数据库的驱动
安装JDBC驱动
5.面向接口编程的思想
面向接口编程思想。
二.数据库的连接
1.配置文件(src目录下)
2.自定义获取连接
public static Connection getConnection() throws Exception {
ResourceBundle bundle = ResourceBundle.getBundle("db");
String driver = bundle.getString("driver");
String url = bundle.getString("url");
String user = bundle.getString("user");
String password = bundle.getString("password");
Connection conn = null;
//1.注册驱动
try {
Class.forName(driver);
//2.获取数据库连接
conn = DriverManager.getConnection(url, user, password);
}catch (Exception e){
e.printStackTrace();
}
return conn;
}
3.关闭连接
public static void closeResource(Connection conn, Statement st, ResultSet res){
try{
if (conn != null){
conn.close();
}
if (st != null){
st.close();
}
if (res != null){
res.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
4.Statement弊端:
存在拼串、繁琐,存在sql注入,无法操作Blob类型数据,插入效率低
5.PreparedStatement
是Statement的接口下的子接口
预编译的sql语句
解决sql注入和拼串问题
安全,效率高
自定义使用PreparedStatement的通用的更新操作
package DAO;
import jdbcUtil.JDBCUtils;
import java.io.File;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
//***************************Dao是未使用泛型需要传入类名来查询数据库**********************************
/*
* 用来封装数据库操作方法的类
*/
public abstract class BaseDao {
//通用的数据库更新方法
public int update(Connection conn,String sql,Object...args) {
int temp = 0;
PreparedStatement pst = null;
try {
//获取数据库操作对象,预编译sql语句
pst = conn.prepareStatement(sql);
//填充占位符
for (int i = 0; i < args.length; i++) {
pst.setObject(i+1,args[i]);
}
//执行sql语句
temp = pst.executeUpdate();
}catch (Exception e){
e.printStackTrace();
}finally {
//关闭资源
JDBCUtils.closeResource(null,pst);//关闭资源
JDBCUtils.closeResource(null,pst);
}
return temp;
}
//插入一条数据的方法
public int insertOneInfo(Connection conn,String sql,Object...args){
int temp = 0;
PreparedStatement pst = null;
try {
pst = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
pst.setObject(i+1,args[i]);
}
temp = pst.executeUpdate();
return temp;
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtils.closeResource(null,pst);
}
return temp;
}
//插入多条数据的方法
public int insertManyInfo(Connection conn,String sql,int count){
int[] temp = null;
PreparedStatement pst = null;
try {
pst = conn.prepareStatement(sql);
conn.setAutoCommit(false);
for (int i = 11; i <= 15; i++) {
pst.setObject(1,i);
pst.setObject(2,"name"+i);
pst.setObject(3,i*10);
pst.addBatch();
if (i % 5 == 0){
temp = pst.executeBatch();
pst.clearBatch();
}
}
conn.commit();
return temp[0];
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtils.closeResource(null,pst);
}
return temp[0];
}
//通用的查询单挑语句的方法
public <T> T selectOneInfo(Connection conn,Class<T> tClass,String sql,Object...args){
PreparedStatement pst = null;
ResultSet res = null;
try {
//获取数据连接
//执行预编译sql语句
pst = conn.prepareStatement(sql);
//填充占位符
for (int i = 0; i < args.length; i++) {
pst.setObject(i + 1, args[i]);
}
//处理查询结果集
res = pst.executeQuery();
//如果查询结果部位空
if (res.next()) {
//创建泛型对象
T t = tClass.newInstance();
//获取查询结果的列数,列名,并通过反射关系将数据库中的数据对应到javabean类中的属性
//获取查询结果的元数据
ResultSetMetaData metaData = res.getMetaData();
//通过元数据获取查询数据的列名和列数
int colCount = metaData.getColumnCount();
for (int i = 0; i < colCount; i++) {
//依次获取数据的列名,列值
String colLabel = metaData.getColumnLabel(i + 1);
Object colValue = res.getObject(i + 1);
//利用反射机制获取对应的类的属性
Field filed = tClass.getDeclaredField(colLabel);
filed.setAccessible(true);
filed.set(t, colValue);
}
return t;
}
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtils.closeResource(null,pst,res);
}
return null;
}
//通用的查询多条语句的方法
public <T> List<T> selectManyInfo(Connection conn,Class<T> tClass,String sql,Object...args){
PreparedStatement pst = null;
ResultSet res = null;
try{
pst = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
pst.setObject(i+1,args[i]);
}
res = pst.executeQuery();
//处理查询结果集
List<T> list = new ArrayList<>();
while (res.next()){
//获取查询结果元数据
ResultSetMetaData metaData = res.getMetaData();
int colCount = metaData.getColumnCount();
T t = tClass.newInstance();
for (int i = 0; i < colCount; i++) {
//获取列名,列值
String colLabel = metaData.getColumnLabel(i + 1);
Object colValue = res.getObject(i + 1);
//反射
Field field = tClass.getDeclaredField(colLabel);
field.setAccessible(true);
field.set(t,colValue);
}
list.add(t);
}
return list;
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtils.closeResource(null,pst,res);
}
return null;
}
//通用的特殊查询方法
public <E> E selectSpciInfo(Connection conn,String sql,Object...args){
PreparedStatement pst = null;
ResultSet res = null;
try {
pst = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
pst.setObject(i+1,args[i]);
}
res = pst.executeQuery();
if (res.next()){
Object object = res.getObject(1);
return (E) object;
}
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtils.closeResource(null,pst,res);
}
return null;
}
}
6.总结
两种思想:
面向接口编程思想,ORL思想(一个表对应一个类,表中一条数据对应一个对象,一个字段对应一个属性)
两种技术:
1.使用结果集的元数据:ResultMetaData
>matedata.getColumnCount():获取列数
>metadata.getColumnLabel();获取列名
2.反射:
>创建对应的运行时对象
>动态调用指定运行时类的属性和对象
3.图示:
三.数据库事务
四.DAO(封装数据库增删改查操作)直接贴代码:
BaseDao类:
package DAO;
import jdbcUtil.JDBCUtils;
import java.io.File;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
//***************************Dao是未使用泛型需要传入类名来查询数据库**********************************
/*
* 用来封装数据库操作方法的类
*/
public abstract class BaseDao {
//通用的数据库更新方法
public int update(Connection conn,String sql,Object...args) {
int temp = 0;
PreparedStatement pst = null;
try {
//获取数据库操作对象,预编译sql语句
pst = conn.prepareStatement(sql);
//填充占位符
for (int i = 0; i < args.length; i++) {
pst.setObject(i+1,args[i]);
}
//执行sql语句
temp = pst.executeUpdate();
}catch (Exception e){
e.printStackTrace();
}finally {
//关闭资源
JDBCUtils.closeResource(null,pst);//关闭资源
JDBCUtils.closeResource(null,pst);
}
return temp;
}
//插入一条数据的方法
public int insertOneInfo(Connection conn,String sql,Object...args){
int temp = 0;
PreparedStatement pst = null;
try {
pst = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
pst.setObject(i+1,args[i]);
}
temp = pst.executeUpdate();
return temp;
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtils.closeResource(null,pst);
}
return temp;
}
//插入多条数据的方法
public int insertManyInfo(Connection conn,String sql,int count){
int[] temp = null;
PreparedStatement pst = null;
try {
pst = conn.prepareStatement(sql);
conn.setAutoCommit(false);
for (int i = 11; i <= 15; i++) {
pst.setObject(1,i);
pst.setObject(2,"name"+i);
pst.setObject(3,i*10);
pst.addBatch();
if (i % 5 == 0){
temp = pst.executeBatch();
pst.clearBatch();
}
}
conn.commit();
return temp[0];
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtils.closeResource(null,pst);
}
return temp[0];
}
//通用的查询单挑语句的方法
public <T> T selectOneInfo(Connection conn,Class<T> tClass,String sql,Object...args){
PreparedStatement pst = null;
ResultSet res = null;
try {
//获取数据连接
//执行预编译sql语句
pst = conn.prepareStatement(sql);
//填充占位符
for (int i = 0; i < args.length; i++) {
pst.setObject(i + 1, args[i]);
}
//处理查询结果集
res = pst.executeQuery();
//如果查询结果部位空
if (res.next()) {
//创建泛型对象
T t = tClass.newInstance();
//获取查询结果的列数,列名,并通过反射关系将数据库中的数据对应到javabean类中的属性
//获取查询结果的元数据
ResultSetMetaData metaData = res.getMetaData();
//通过元数据获取查询数据的列名和列数
int colCount = metaData.getColumnCount();
for (int i = 0; i < colCount; i++) {
//依次获取数据的列名,列值
String colLabel = metaData.getColumnLabel(i + 1);
Object colValue = res.getObject(i + 1);
//利用反射机制获取对应的类的属性
Field filed = tClass.getDeclaredField(colLabel);
filed.setAccessible(true);
filed.set(t, colValue);
}
return t;
}
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtils.closeResource(null,pst,res);
}
return null;
}
//通用的查询多条语句的方法
public <T> List<T> selectManyInfo(Connection conn,Class<T> tClass,String sql,Object...args){
PreparedStatement pst = null;
ResultSet res = null;
try{
pst = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
pst.setObject(i+1,args[i]);
}
res = pst.executeQuery();
//处理查询结果集
List<T> list = new ArrayList<>();
while (res.next()){
//获取查询结果元数据
ResultSetMetaData metaData = res.getMetaData();
int colCount = metaData.getColumnCount();
T t = tClass.newInstance();
for (int i = 0; i < colCount; i++) {
//获取列名,列值
String colLabel = metaData.getColumnLabel(i + 1);
Object colValue = res.getObject(i + 1);
//反射
Field field = tClass.getDeclaredField(colLabel);
field.setAccessible(true);
field.set(t,colValue);
}
list.add(t);
}
return list;
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtils.closeResource(null,pst,res);
}
return null;
}
//通用的特殊查询方法
public <E> E selectSpciInfo(Connection conn,String sql,Object...args){
PreparedStatement pst = null;
ResultSet res = null;
try {
pst = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
pst.setObject(i+1,args[i]);
}
res = pst.executeQuery();
if (res.next()){
Object object = res.getObject(1);
return (E) object;
}
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtils.closeResource(null,pst,res);
}
return null;
}
}
UserDao类:定义user类的接口,包含众多抽象的方法
package DAO;
import bean.User;
import java.sql.Connection;
import java.util.List;
public interface UserDao {
/**
* 根据传入的user的id,将对应的数据修改成user的属性值的方法
* @param conn
* @param user
*/
public abstract int update(Connection conn, User user);
/**
* 根据传入的id删除表中的数据
* @param conn
* @param id
*/
public abstract int delete(Connection conn,int id);
/**
* 将传入的user添加到数据库中
* @param conn
* @param user
*/
int insertOneInfo(Connection conn,User user);
/**
* 将多条数据添加到数据表中
* @param conn
* @param list
*/
int insertManyInfo(Connection conn, int count);
/**
* 通过id查询一个用户的信息
* @param conn
* @param id
* @return
*/
User selectOneInfo(Connection conn,int id);
/**
* 查询表中所有的数据
* @param conn
* @return
*/
List<User> selectManyInfo(Connection conn);
/**
* 查询最高工资
* @param conn
* @return
*/
Double selectHighestBalance(Connection conn);
/**
* 查询有多少条数据
* @param conn
* @return
*/
Long selectCount(Connection conn);
}
UserDaoImpl类:实现UserDao的类
package DAO;
import bean.User;
import java.sql.Connection;
import java.util.List;
public class UserDaoImpl extends BaseDao implements UserDao {
@Override
public int update(Connection conn, User user) {
String sql = "update user_tab set name = ? ,balance = ? where id = ?";
int update = update(conn, sql, user.getName(), user.getBalance(), user.getId());
return update;
}
@Override
public int delete(Connection conn, int id) {
String sql = "delete from user_tab where id = ?";
int update = update(conn, sql, id);
return update;
}
@Override
public int insertOneInfo(Connection conn, User user) {
String sql = "insert into user_tab (id,name,balance) values(?,?,?)";
int info = insertOneInfo(conn, sql, user.getId(), user.getName(), user.getBalance());
return info;
}
@Override
public int insertManyInfo(Connection conn, int count) {
String sql = "insert into user_tab (id,name,balance) values(?,?,?)";
int manyInfo = insertManyInfo(conn, sql, count);
return manyInfo;
}
@Override
public User selectOneInfo(Connection conn, int id) {
String sql = "select id,name,balance from user_tab where id = ?";
User user = selectOneInfo(conn, User.class, sql, id);
return user;
}
@Override
public List<User> selectManyInfo(Connection conn) {
String sql = "select id,name,balance from user_tab";
List<User> list = selectManyInfo(conn, User.class, sql);
return list;
}
@Override
public Double selectHighestBalance(Connection conn) {
String sql = "select max(balance) from user_tab";
Double balance = selectSpciInfo(conn, sql);
return balance;
}
@Override
public Long selectCount(Connection conn) {
String sql = "select count(*) from user_tab";
Object o = selectSpciInfo(conn, sql);
return (Long)o;
}
}
五.数据库连接池详解: