数据表的导入
通过可视化界面导入sql脚本
JDBC
前端
VUE/Resact/jQuery
Java DataBase Connectivity
JDBC本质:
定义了操作关系型数据库的规则(接口),各个数据库厂商去实现这套接口,提供数据库驱动 jar 包。
我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动 jar 包中的实现类。
connection对象 数据库连接对象
statement对象 执行SQL语句,增删改查操作
ResultSet对象 查询
在工程中新建一个lib文件夹,将包复制进去
再右键选择bulid Path
此时就多了一个引用的库
Driver类------ctrl+H显示该类的路径,使用路径.构造方法创建对象
方法:connect ( trl , info)
-
-
Connection
connect(String url, Properties info)
尝试使数据库连接到给定的URL。
-
方法一:Driver对象-----添加url------封装用户名、密码------建立连接传入url用户名密码(connection对象)
方法二:为了更好的可移植性-----不出现第三方包
驱动加载:通过反射 Class.forName(全类名) 得到 驱动Driver 的 .class对象,
驱动注册:通过 newInstance() 返回全类名的实现类对象
创建 Properties()类对象,设置用户名和密码的属性值 设置url
获取连接:通过实现类对象的connect(),传入url和Properties()对象 获取连接
方法三:使用DriverManager替换Driver---------需要注册驱动DriverManager.registerDriver()
驱动加载:通过反射 Class.forName(全类名) 得到 .class 对象,
提供需要连接的三个信息 url user password
驱动注册:用 DriverManager.registerDriver() 传入 newInstance() 返回的 Driver对象
获取连接:直接使用 DriverManager.getConnectio(url,user,password) 获取连接
方法四:可以只是加载驱动,不用显示的驱动在加载时,已经注册过了
在加载驱动时,静态代码块就注册了驱动
另外:mysql5以后,加载驱动也可以省略,导入jar包时,就已经加载了Driver了
最好不省略,只适用于mysql5以后,oracle不适用
提供需要连接的三个信息 url user password
驱动加载:通过反射 Class.forName(全类名) 得到 .class 对象,
获取连接:直接使用 DriverManager.getConnectio(url,user,password) 获取连接
方法五:最终方法---将数据库连接需要的四个基本连接信息--写入配置文件---通过读取配置文件获取连接
通过反射的类加载器 类名.class.getClassLoader().getResourceAsStream(配置文件) 获取流对象
再创建配置文件对象Properties的 .load() 方法将流对象读取的内容加载到配置文件对象
再通过getProperties(名称) 得到 1. user 2. password 3.url 4. 封装的Driver接口全类名
驱动加载:通过反射 Class.forName(封装的Driver全类名) 得到 .class 对象
获取连接:直接使用 DriverManager.getConnectio(url,user,password) 获取连接
4、定义sql语句
为什么用PreparedStataement替换掉Statement-------------拼接sql引发sql注入
SQL注入
Connection(数据连接) 中 4个基本信息
1.驱动在具体的数据库中,的Driver接口,创建具体的实现类
2.url:填写指定协议,指定ip下指定端口号中,的哪一个数据库
3.用户名
4.密码
完整的向customers表中添加一条记录
import com.guigu.connection.ConnectionTest;
import com.guigu.util.JDBCUtils;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Properties;
public class PreparedstatementUpdateTest {
// 全局变量
PreparedStatement ps = null; // 通过conn返回的一个sql预编译实例对象
Connection conn = null; // 一个连接对象(包含了url、user、password)
// 向customers表中添加一条记录
@Test
public void testInsert() {
/*PreparedStatement ps = null;
Connection conn = null;*/
try {
//3 获取连接
//1 读取配置文件中的4个基本信息---获取类加载器---需要配置文件
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");
Properties pro = new Properties();
pro.load(is);
String user = pro.getProperty("user");
String password = pro.getProperty("password");
String url = pro.getProperty("url");
String driverClass = pro.getProperty("driverClass");
//2 驱动加载 -- 省略了驱动注册--配置文件中读取了Driver类,已经注册了
Class.forName(driverClass);
//3 获取连接
conn = DriverManager.getConnection(url, user, password);
// System.out.println(conn);
//4 预编译sql语句,返回
String sql = "insert into customers(name ,email,birth) values(?,?,?)";//?占位符
// String sql = "update customers set email ='a' where id=1";//?占位符
ps = conn.prepareStatement(sql);
//5 填充占位符 --- 数据库索引从1开始
ps.setString(1, "敖丙");
ps.setString(2, "aobing@gmail.com");
// Date类型的数据添加----需要自定义数格式
// 使用SimpleDateFormat()创建对象 传入格式, 对象.parse(指定数据)
SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd");
java.util.Date date = sdf.parse("1000-01-01");
ps.setDate(3, new Date(date.getTime()));
// 执行操作
ps.execute();
} catch (Exception e) {
System.out.println(e);
} finally {
// 资源释放
try {
if (ps != null)
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
封装数据库连接和关闭资源操作
=================================================
向指定表插入一条数据
===============================================
通用增删改操作
调用通用增删改操作方法
===============================================================
对不同类型的表属性,使用不同类型的set方法操作
ps.setObject ( 索引值,属性值 )
ps.setString ( )
ps.setDate ( )
===============================================================
查询通用方法
针对customers表的通用查询方法
通过别名,查指定的表的属性值
表的字段名,和类的属性名不同时,声明sql语句时,需要使用别名( 类属性名 ),元数据获取列名时用 getColumnLabel()
@test 注解的方法需要返回值为void
针对所有表的通用查询方法(参数中传入Class对象)----返回一条记录
定义时,参数--带泛型的Class对象,返回值类型---指定的泛型对象
需要创建类对象时,直接class对象.newInstance返回指定泛型的类对象
反射得到指定别名的属性对象时,使用带泛型的Class对象获取属性对象
返回类对象时,就返回newInstance返回的指定泛型的类对象
/**
* 创建一个针对所有表的通用查询方法
* 参数中传入带泛型的Class对象,返回值类型为指定泛型
*/
public class PreparedstatementQueryTest {
// 测试针对所有表的通用查询方法
@Test
public void testGetInstance(){
String sql = "select id,name,email,birth from customers where id = ?";
Customer ins = getInstance(Customer.class, sql, 12);
System.out.println(ins);
}
// 全局变量
Connection conn = null;// 创建连接
PreparedStatement ps = null;// 获取sql实例对象
ResultSet rs = null;//结果集
// 参数传入带泛型的Class对象,返回一个指定泛型的对象
public <T> T getInstance(Class<T> clazz,String sql,Object...args){
try {
conn = JDBCUtils.getConnection();// 创建连接
ps = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setObject(i+1,args[i]);
}
// 结果集 + 元数据
// 执行并返回结果集
rs = ps.executeQuery();
// 获取结果集的元数据(列表属性)----ResultSetMetaData
ResultSetMetaData rsmd = rs.getMetaData();
// 通过元数据获取列数
int columnCount = rsmd.getColumnCount();
if (rs.next()) {
// 通过带泛型的Class对象newInstace返回泛型对象
T t = clazz.newInstance();
// 遍历结果集,处理每一行中的每一列
for (int i = 0; i < columnCount; i++) {
// 获取列值---索引从1开始
Object columValue = rs.getObject(i + 1);
// 获取每列的别名----通过元数据----索引从1开始
String columnLabel = rsmd.getColumnLabel(i + 1);
// 反射
// 通过反射,获取泛型对象列别名对应的属性对象(对象的属性名==列别名)
Field field = clazz.getDeclaredField(columnLabel);
field.setAccessible(true);
// 通过属性对象设置泛型对象t的属性值
field.set(t,columValue);
}
// 返回泛型对象
return t;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(conn,ps,rs);
}
return null;
}
}
向数据表中插入Blob数据类型
插入Blob类型的字段
通过文件输入流传入文件,再填充占位符
查询表中Blob类型的字段
先查询到指定位置行的结果集,通过结果集返回除Blob类型外的其他值---封装到表对象对象--输出
再返回Blob类型的值,通过getBinaryStream(),返回输入流,再创建文件输出流(传入文件名),循环读取-输出
判断关闭输入出流
使用PreparedStatement实现批量数据的操作