JDBC
JDBC概述
● JDBC(Java DataBase Connectivity)java数据库连接 ● 是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问,它由一组用Java语言编写的类和接口组成。 ● 有了JDBC,java开发人员只需要编写一次程序,就可以访问不同的数据库. ● JavaAPI中提供了操作数据库的标准接口,最终由不同的数据库开发商实现这些标准接口来对数据库操作 . Java定义者制定了JDBC规范 数据库开发商实现接口 程序员学习使用标准规范 JDBC API: 供程序员调用的接口与类,集成在java.sql包中 DriverManager类作用:管理各种不同的jDBC驱动 Connection 接口与特定数据库的连接 Statement 接口执行sql PreparedStatement接口执行sql ResultSet接口接收查询结
JDBC搭建
● 注册JDBC驱动程序: ● 这需要初始化驱动程序,这样就可以打开与数据库的通信信道。 Class.forName(“com.mysql.cj.jdbc.Driver”); //反射实现或者DriverManager.registerDriver(new Driver()) ● 建立与数据库连接: ● 这需要使用DriverManager.getConnection()方法来创建一个Connection对象,它代表一个物理连接的数据库. ● Connection conn =DriverManager.getConnection(URL,USER,PASS); URL:jdbc:mysql://ip(127.0.0.1):端口(3306)/数据库名?serverTimezone=Asia/Shanghai USER:用户名(root) PASS:密码 获得Satement执行sql语句 ●Statement st = connection.createStatement(); Satement中的方法: Int executeUpdate(String sql) 用于执行ddl语句和dml(增,删,改)语句 返回操作的行数 用于执行ddl语句返回0 用于执行dml语句返回操作的行数 ResultSet executeQuery(String sql); 用于执行查询语句 返回一个ResultSet 集合 获得PrepareStatement执行sql语句 ● 在sql语句中参数位置使用占位符,使用setXX方法向sql中设置参数 ● PrepareStatement ps = connection.prepareStatement(sql); PrepareStatement中的方法: Int executeUpdate() 用于执行ddl语句和dml(增,删,改)语句 返回操作的行数 用于执行ddl语句返回0 用于执行dml语句返回操作的行数 ResultSet executeQuery(); 用于执行查询语句 返回一个ResultSet 集合 关闭与数据库的链接通道 每次操作完成后关闭所有与数据库交互的通道st.close();rs.close();conn.close();ps.close();
/* java jdbc连接mysql数据库 1.导入mysql开发商提供的具体连接数据库实现的jar文件 2.加载mysql驱动类 3.建立与mysql数据库连接 4.发送sql 5.关闭与数据库的连接 6.接收数据库查询的结果 */ // Statement添加 public class Demo1 { public static void main(String[] args) throws SQLException, ClassNotFoundException { String userName = "admin1"; String userPassword = "1111"; String birthday = "2002-1-2"; //2.加载mysql驱动类 //DriverManager.registerDriver(new Driver()); Class.forName("com.mysql.cj.jdbc.Driver"); //com.mysql.cj.jdbc.ConnectionImpl@37574691 Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/chatdb?serverTimezone=Asia/Shanghai", "root", "root"); //com.mysql.cj.jdbc.StatementImpl@71248c21 Statement st = connection.createStatement(); //发送sql int res = st.executeUpdate("INSERT INTO tuser(user_name,user_password,birthday,reg_time)" + " VALUE('"+userName+"','"+userPassword+"','"+birthday+"',now())"); System.out.println(res); st.close(); connection.close(); }} // Statement修改 public static void main(String[] args) throws SQLException, ClassNotFoundException { String userName = "admin2"; String userPassword = "2222"; String birthday = "2002-2-2"; String id = "1"; Class.forName("com.mysql.cj.jdbc.Driver"); Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/chatdb?serverTimezone=Asia/Shanghai", "root", "root"); Statement st = connection.createStatement(); //发送sql /* int res = st.executeUpdate("update tuser set user_name='"+userName+"',user_password='"+userPassword+"'," + " birthday='"+birthday+"' where id= "+id);*/ int res = st.executeUpdate("delete from tuser where id ="+id); System.out.println(res); st.close(); connection.close(); } } // PreparedStatement添加 public static void main(String[] args) throws SQLException, ClassNotFoundException { String userName = "admin2"; String userPassword = "2222"; String birthday = "2002-2-2"; Class.forName("com.mysql.cj.jdbc.Driver"); Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/chatdb?serverTimezone=Asia/Shanghai", "root", "root"); PreparedStatement ps = //将sql预编译到PreparedStatement对象中,并没有执行 connection.prepareStatement("insert into tuser(user_name,user_password,birthday,reg_time)value(?,?,?,?)"); //设置值 ps.setObject(1,userName); ps.setObject(2,userPassword); ps.setObject(3,birthday); ps.setObject(4,new java.util.Date()); ps.executeUpdate(); ps.close(); connection.close(); }} // PreparedStatement修改 public static void main(String[] args) throws SQLException, ClassNotFoundException { String userName = "admin3"; String userPassword = "3333"; String birthday = "2002-3-2"; String id = "2"; Class.forName("com.mysql.cj.jdbc.Driver"); Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/chatdb?serverTimezone=Asia/Shanghai", "root", "root"); PreparedStatement ps = //将sql预编译到PreparedStatement对象中,并没有执行 connection.prepareStatement("update tuser set user_name=?,user_password=?,birthday=? where id =?"); //设置值 ps.setObject(1, userName); ps.setObject(2,userPassword); ps.setObject(3,birthday); ps.setObject(4,id); ps.executeUpdate(); ps.close(); connection.close(); }}
PreparedStatement和Statement
基于以下的原因: 1、代码的可读性和可维护性. 虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说.都比直接用Statement的代码高很多档次: stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values ('"+var1+"','"+var2+"',"+var3+",'"+var4+"')"); perstmt = con.prepareStatement("insert into tb_name (col1,col2,col2,col4) values (?,?,?,?)"); perstmt.setString(1,var1); perstmt.setString(2,var2); perstmt.setString(3,var3); perstmt.setString(4,var4); perstmt.executeUpdate(); //prestmt是 PreparedStatement 对象实例 2、最重要的一点是极大地提高了安全性. 防止sql注入 Stringsql=“ delete from user where id =”+num; 如果我们把[or 1=1]作为id传入进来? delete from tb_name where id = 1 or 1 = 1; 因为‘1’=‘1’肯定成立(会删除所有数据) 而如果你使用预编译语句.你传入的任何内容就不会和原来的语句发生任何匹配的关系. 预编译模式中每个占位符处,只能插入一个值,而会过滤其他语句.
//sql注入 sql攻击 //Statement public static void main(String[] args) throws SQLException, ClassNotFoundException { String id = "1000 or 1=1"; //sql注入 sql攻击 Class.forName("com.mysql.cj.jdbc.Driver"); Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/chatdb?serverTimezone=Asia/Shanghai", "root", "root"); Statement st = connection.createStatement(); st.executeUpdate("delete from tuser where id = "+id); st.close(); connection.close(); } } //PreparedStatement public static void main(String[] args) throws SQLException, ClassNotFoundException { String id = "1000 or 1=1"; //sql注入 sql攻击 Class.forName("com.mysql.cj.jdbc.Driver"); Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/chatdb?serverTimezone=Asia/Shanghai", "root", "root"); //预编译sql ?-->占位符 PreparedStatement ps = connection.prepareStatement("delete from tuser where id = ?"); ps.setObject(1, id);//set方法中对传入的值进行检测.一个?对应一个值,不能有其他的关键字 会报错 ps.executeUpdate();//执行 ps.close(); connection.close(); }}
结果集处理
● PreparedStatement和Statement中的executeQuery()方法中会返回一个ResultSet对象,查询结果就封装在此对象中. ● 使用ResultSet中的next()方法获得下一行数据 ● 使用getXXX(String name)方法获得
//查询单个数据 public class Demo7 { public static void main(String[] args) { String id = "6"; User user= null; try { user = new Demo7().getUserById(id); } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } System.out.println(user); } public User getUserById(String id) throws ClassNotFoundException, SQLException { User user =null; PreparedStatement ps =null; Connection connection = null; try { Class.forName("com.mysql.cj.jdbc.Driver"); connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/chatdb?serverTimezone=Asia/Shanghai", "root", "root"); ps = connection.prepareStatement("select * from tuser where id =?"); ps.setObject(1, id); ResultSet rs = ps.executeQuery();//执行查询操作,将结果封装到了ResultSet中 //从ResultSet中将数据封装到我们自己定义的对象中 while(rs.next()){ user = new User(); user.setId(rs.getInt("id")); user.setUserName(rs.getString("user_name")); user.setPassword(rs.getString("user_password")); user.setBirthday(rs.getDate("birthday")); user.setRegTime(rs.getTimestamp("reg_time")); } }finally { ps.close(); connection.close(); } return user; }} //查询表中全部数据 public class Demo8 { public static void main(String[] args) { try { ArrayList<User> users = new Demo8().getUsers(); System.out.println(users); } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } } public ArrayList<User> getUsers() throws ClassNotFoundException, SQLException { PreparedStatement ps =null; Connection connection = null; ArrayList<User> users = new ArrayList<>(); try { Class.forName("com.mysql.cj.jdbc.Driver"); connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/chatdb?serverTimezone=Asia/Shanghai", "root", "root"); ps = connection.prepareStatement("select * from tuser "); ResultSet rs = ps.executeQuery();//执行查询操作,将结果封装到了ResultSet中 //从ResultSet中将数据封装到我们自己定义的对象中 while(rs.next()){ User user = new User(); user.setId(rs.getInt("id")); user.setUserName(rs.getString("user_name")); user.setPassword(rs.getString("user_password")); user.setBirthday(rs.getDate("birthday")); user.setRegTime(rs.getTimestamp("reg_time")); users.add(user); } }finally { ps.close(); connection.close(); } return users; } } //封装 public class User { private int id; private String userName; private String password; private Date birthday; private Date regTime; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public Date getRegTime() { return regTime; } public void setRegTime(Date regTime) { this.regTime = regTime; } @Override public String toString() { return "User{" + "id=" + id + ", userName='" + userName + '\'' + ", password='" + password + '\'' + ", birthday=" + birthday + ", regTime=" + regTime + '}'; }}