1、什么是JDBC技术?
JDBC技术全称:Java Data Base Connectivity(Java 连接数据库技术),底层使用Java代码实现
2、如何搭建JDBC开发环境
1.jdbc_test –>create new project –> java项目 –>项目名/项目路径
2.在项目名下新建lib文件夹,将jdbc 相关jar包导入
3.右键Jar包,选择add as library ,将Jar包解析
4.建立包,编写相关代码
3.如何通过JDBC提供的代码连接数据库,并插入一条数据
1.准备相关参数连接数据库
public static final String Driver/URL/USERNAME/PASSWORD=" ";
2.加载驱动(准备JDBC相关技术的内容)
Class.forName(DRIVER);
Class.forName:获取指定类的字节码,加载指定类。
3.获取连接对象(建立Java连接MySQL的通道)(java.sql包下)
Connection conn=DriverManager.getConnection(URL,USERNAME,PASSWORD);
4.准备SQL语句
String sql= "insert into dog values(default,'David',2)";
5.装载SQL语句(准备交通工具将货物放在交通工具上)(java.sql包)
PreparedStatement ps= conn.prepareStatement(sql);
6.执行SQL语句
规则:执行增删改语句,executeUpdate; 执行查询,executeQuery
//executeUpdate 返回值int类型
int result = ps.executeUpdate();
if(result>0){
System.out.println("执行成功");
}else{
System.out.println("执行失败");
}
7.关闭资源(finally)
resultSet.close();
ps.close();
conn.close();
4.如何将控制台录入的数据写到sql语句中
字符串拼接的方式
insert into dog values(default,'"+name+"','"+age+"')
字符串拼接的方式存在安全隐患–>SQL注入攻击:通过输入违法字符 改变原有SQL语义的行为,只发生在SQL语句进行拼接处理的阶段。
通过?占位的方式,完成SQL语句
insert into dog values(default,?,?)
问号占位的特点:
1>通过问号占位后,给问号位置赋值的数据会在数据两端自动添加单引号。
2>给问号赋值的数据,会提前预编译,清除无关字符。(保证数据的正确性)
给?赋值 4.2 在装载SQL语句之后
通过set方法给?赋值,
第一个参数,表示给第几个问号赋值。
第二个参数,表示给问号赋值的具体数据
ps.setString(1,name);
ps.setInt(2,age);
5、使用JDBC查询数据库数据
/*使用executeQuery 执行查询,返回一个ResultSet*/
Class.forName(DRIVER);
connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
String sql = "select dog_id,dog_name,dog_age from dog";
ps = connection.prepareStatement(sql);
ResultSet resultSet = ps.executeQuery();
System.out.println(result);
while (resultSet.next()){//指针下移,返回一个布尔值,判断是否有数据,借助循环遍历
int dog_id=result.getInt(1);//result.get 方法,参数可以声明列号(从一开始)或者列明来进行查询
String dog_name=result.getString(2);
int dog_age= result.getInt(3);
Dog dog= new Dog(dog_id,dog_name,dog_age);
System.out.println(dog);
}
???模糊查询
6、JDBC代码的提取封装(C,U,D)
浅提取
将前两步提取到方法里(Util包),将创建好的连接对象当作返回值返回
public static Connection getConnection() {
Connection connection = null;
try {
Class.forName(DRIVER);
connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return connection;
}
public static void close(Connection connection, PreparedStatement ps,ResultSet rs){
if(rs!=null){
rs.close();
}
try {
ps.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
if (connection!=null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
深提取/深度封装
将共通的代码提取
把深度封装的代码提取到BaseDao中,负责深度提取增删改代码,完成DML操作。
public static int execute(String sql,Object...args){
/*
问号的数量不确定--> 可变形参Object...args,本质上是一个数组。
赋值给问号的数据类型不确定!-->Object类型
调用execute 第一个参数一定是SQL语句,第二个参数及以后,一定是给问号依次赋值的数据
*/
PreparedStatement ps= null;
int result=0;
Connection connection = JdbcUtil.getConnection();
try {
ps= connection.prepareStatement(sql);
for (int i=0;i<args.length;i++){
ps.setObject(i+1,args[i]);
}
result=ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
JdbcUtil.close(connection,ps);
}
return result;
}
impl实体类代码简化
public boolean addDog(Dog dog){
String sql = "insert into dog values(default,?,?)";
int result = BaseDao.execute(sql, dog.getDogName(), dog.getDogAge());
return result>0;
}
7、利用JDBC封装查询功能
全查询
模糊查询
select * from dog where dog_name like '%?%';--不能这么写!
--给问号赋值,问号会自动给数据两端加单引号
select * from dog where dog_name like ? --在PrepareStatement 的set方法中,拼接字符串
用反射的方式给属性赋值。
public static <T> List<T> executeQ(String sql, Class<T> class1, Object ... args){
PreparedStatement ps= null;
ResultSet rs= null;
List<T> list = new ArrayList<>();
Connection connection = JdbcUtil.getConnection();
try {
ps=connection.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setObject(i+1,args[i]);
}
rs=ps.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
while (rs.next()){
T t= class1.newInstance();
int columnCount = rsmd.getColumnCount();
for (int i = 1; i <=columnCount ; i++) {
String columnName=rsmd.getColumnName(i);
Field field= class1.getDeclaredField(columnName);
field.setAccessible(true);
field.set(t,rs.getObject(i));
}
list.add(t);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}finally {
JdbcUtil.close(connection,ps,rs);
}
return list;
}
8.JDBC中PreparedStatement和Statement的区别
两者都用于装载SQL语句
PreparedStatment 具有预编译功能,支持SQL语句中使用问号占位。
statement,不具备预编译功能,不支持SQL语句中使用问号占位,即,SQL语句必须通过拼接完成。