java JDBC概念 JDBC使用的常用类 JDBC中涉及到的各个接口
JDBC概念 ? 什么是JDBC:Java DataBase Connectivity 使用java语言链接数据库的技术 ? 本质:就是官方定义的操作数据库的一套规则,都是接口.各个数据库厂商去实现这套接口,提供对应的数据库驱动java包.我们可以使用驱动java包, 来完成连接数据库操作数据库的功能 ? 快速入门 步骤: 1.添加java包到工程中,添加到工程中的lib文件夹下 public class JDBCDemo { public static void main(String[] args) throws Exception { //2.注册驱动 Driver com.mysql.jdbc.Driver.class Class.forName("com.mysql.jdbc.Driver");//通过改类的路径反射生成该类的字节码对象 //3.获取数据库的连接对象 Connection Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/java31","root","root"); //4.执行sql语句 String sql = "update account set balance = 20000 where username = '张三'"; //5.获取执行sql语句的对象 Statement Statement statement = connection.createStatement(); //6.通过statement独享执行sql语句 int count = statement.executeUpdate(sql); //判断如果count>0就代表执行成功 if (count>0) { System.out.println("更新数据库成功"); }else{ System.out.println("更新数据库失败"); } //打开的连接对象关闭 先打开后关闭,后打开先关闭 statement.close(); connection.close(); } } 1.注册驱动 2.获取连接 3.获取数据库操作对象 4.执行sql语句 5.处理查询结果集 6.释放资源 ? 快速回忆: ○ 多表连接: § 内连接:隐式内连接 用,号连接,连接条件使用where,没有inner join,显式内连接 使用关键字[inner] join on 条件 § 外连接:左外连接 left [outer] join on 条件,右外连接 right [outer] join on 条件 ○ 子查询: § 单行单列 使用比较运算符> < != <>… 条件放在where语句后面 § 多行单列 使用in运算符 in(散列数据) 条件放在where语句的后面 § 多行多列 放在from的后面 作为一张表进行二次查询的条件判断介绍JDBC快速入门用到的包和类 ? java.sql 所有与JDBC访问数据库相关的类和接口. ? javax.sql 用到数据库连接池 数据库的扩展包,提供数据库操作的额外一些功能.如:连接池 ? DriverManager(类) 驱动管理 注册驱动 还有获取数据库对象 ? Connection(接口) 连接对象 用于创建执行sql的对象 Statement,PreparedStatement ? Statement(接口) sql语句执行对象,用于将sql语句发送给数据库服务器 ? PreparedStatment(接口) sql语句执行对象 是Statement接口的子接口 带着预编译 ? ResultSet(接口) 用于封装从数据库查询出来的结果值 DriverManager ? 从JDBC3开始,可以不用注册驱动,可以直接使用,class.forName(); ? Connection getConnection(url,user,password); 可以获取到数据库连接对象 ? Connection getConnection(String url,Properties info);通过连接字符串和属性对象,获取数据连接对象 ? user 登录数据库用户名 ? passworld 登录数据库的密码 ? url 连接数据库的路径 对于mysql而言 jdbc:mysql://服务器IP地址:端口号3306/数据库名称 ? (参数名 = 参数值) ? 驱动类路径 com.mysql.jdbc.Driver ? jdbc:mysql://服务器IP地址:端口号3306/数据库名称 ? (参数名 = 参数值).如果数据库的服务器是在本地中,省略掉ip地址和端口号 jdbc:mysql:///数据库名称 ? (参数名 = 参数值) 如果数据传输时引发了乱码,后面可以使用参数characterEncoding = utf8 jdbc:mysql:///数据库名称 ? characterEncoding = utf8Connection接口 作用:连接数据库,他是一个接口,由具体的厂商来提供具体的实现类,代表的是一个连接对象 Statement createStatement() 创建一个sql执行对象 PrepareStatement preparedStatement()创建一个sql预处理对象Statement接口 作用:用来执行sql语句,本质是吧sql语句发送给数据库服务器 ○ int executeUpdate(String sql) 用于吧sql语句发送给服务器,执行增删改操作,返回值int影响数据库的记录数(行数) ○ ResultSet executeQuery(String sql) 用于吧sql语句发送给服务器 执行查询操作.返回值ResultSet 查询返回的结果集 PreparedStatement ? 执行sql对象 ? 会防止一些sql非法注入问题,在拼接sql语句时,可能会造成安全性问题。如: ? " select * from account where username like '% " +username + " % ' and balance = ' " + balance + " ' + " or 1 = 1 " ? 此时出现 " or 1=1 " 非法拼接问题。 ? 使用预编译的sql,参数使用?作为占位符 ? 操作: ○ 在sql语句中涉及到参数时使用?替代具体的数据 如: select * from user where username = ? and password = ? ○ 使用连接对象执行sql语句获取预编译对象 connection.preparedStatement(String sql) ○ 给?赋值:使用方法:setXxx(?索引下标,?对应的实际值) ○ 使用预编译对象执行sql,获取返回的结果集值--->preparedStatement.executeQuery(); ○ 处理结果 ○ 释放资源。释放资源 ? 需要释放的资源对象:ResultSet对象,Statement对象,Connection对象 先开后关 后开先关 ? 释放顺序 Resultset--->Statement--->Connection ? 使用finally语句块,一定会被加载到.不能单独使用,需要搭配try语句块使用 常用数据库数据类型和Java类型的对照sql jdbc javaint getInt() intbigInt getLong() longbit getBoolean booleanvarchar getString stringdate/time/timeStamp getDate/getTime/getTimeStamp java.util.Date/java.sql.Time/java.sql.Timestampdouble getDouble double备注:java.sql.Date/Time/TimeStamp(时间戳三个共同的父类是java.util.Date)数据库工具类 DBUtil// 数据库工具类public class DBUtil { // 定义四个常量值 private static final String DRIVER = "com.mysql.jdbc.Driver"; private static final String URL = "jdbc:mysql:///java31?characterEncoding=utf8"; private static final String USER = "root"; private static final String PASSWORD = "root"; // 定义JDBC常用类和接口 private static Connection con = null; private static Statement st = null; private static PreparedStatement ps = null; private static ResultSet set = null; static { try { Class.forName(DRIVER); con = DriverManager.getConnection(URL, USER, PASSWORD); } catch (Exception e) { e.printStackTrace(); } } // 针对查询的功能 public static ResultSet select(String sql,Object[] args) { //String sql2 = "select * from account where u_name = ? and password = ?"; try { // 获取预处理对象 ps = con.prepareStatement(sql); // 使用sql语句中的占位符 ? // 遍历数组 // 占位符 在sql中是有前后顺序的 u_name对应的问号 索引是 1 password对应的问号就是2 for (int i = 0; i < args.length; i++) { // 把问号提换成具体的数据 ps.setObject(i+1, args[i]); } // 执行sql语句 获取结果值 set = ps.executeQuery(); } catch (SQLException e) { e.printStackTrace(); } return set; } // 针对更新的功能 insert update delete executeUpdate() public static int update(String sql,Object[] args) { // 获取预处理对象 // 定义一个变量 用来记录印象数据库表的行数 int count = 0; try { ps = con.prepareStatement(sql); // 使用sql语句中的占位符 ? // 遍历数组 // 占位符 在sql中是有前后顺序的 u_name对应的问号 索引是 1 password对应的问号就是2 for (int i = 0; i < args.length; i++) { // 把问号提换成具体的数据 ps.setObject(i+1, args[i]); } // 执行sql语句 获取结果值 count = ps.executeUpdate(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 返回给调用处 return count; } // 关闭连接的方法 public static void closeAll() { // 关闭时 先关闭ResultSet if (set != null) { try { set.close(); } catch (SQLException e) { e.printStackTrace(); } } if (st != null) { try { st.close(); } catch (SQLException e) { e.printStackTrace(); } } if (con != null) { try { con.close(); } catch (SQLException e) { e.printStackTrace(); } } }}表与类的关系 ? 整个表可以看做成一个类 ? 表的每一行称之为一条记录,可以看做成一个类的实例 ? 表中的每一列可以看做成实例对象中的每个属性。 ? 实体类、model类需要和数据库中的类进行一一映射 ? 表中的列名和model类中的属性名保持一致 ? 表中的列字段数据类型和model类中的属性数据类型保持一致 ? 操作:数据库java31中的 account表 ? 需要创建封装层中的model类 -----> Account类 表与实体类的对应关系如图所示: 项目分层 合理的分层能够使项目的开发和维护更方便