JDBC技术全称:Java Data Base Connectivity(Java 连接数据库技术),底层使用Java代码实现
1.jdbc_test –>create new project –> java项目 –>项目名/项目路径
2.在项目名下新建lib文件夹,将jdbc 相关jar包导入
3.右键Jar包,选择add as library ,将Jar包解析
4.建立包,编写相关代码
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();字符串拼接的方式
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);???模糊查询
浅提取
将前两步提取到方法里(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; }全查询
模糊查询
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; }两者都用于装载SQL语句
PreparedStatment 具有预编译功能,支持SQL语句中使用问号占位。
statement,不具备预编译功能,不支持SQL语句中使用问号占位,即,SQL语句必须通过拼接完成。
