JDBC
概述
JDBC(Java DataBase Connectivity),即java数据库连接
是一种用于执行sql语句的API.其中包含了一组由java定义的接口与类,用于访问关系型数据库
JDBC可以让java开发人员只需要编写一次程序,就可以访问不同的数据库.
然后由数据库公司的开发人员来提供实现jdbc的代码
JDBC API: 供程序员调用的接口与类,集成在java.sql包中 DriverManager类作用:管理各种不同的jDBC驱动 Connection 接口 与特定数据库的连接 Statement 接口 执行sql PreparedStatement接口 执行sql ResultSet接口 接收查询结果
JDBC搭建
主要分为6步:
1.将数据库中的驱动放入目录内并且导入进项目中
2.注册JDBC驱动程序,即加载数据库的驱动类(以mysql加载为例)
两种方式:
Class.forName(“com.mysql.cj.jdbc.Driver”); //反射实现 DriverManager.registerDriver(new Driver());
注意参数内的Driver类是com.mysql.cj包下的这是mysql8以后对应的加载方式,com.mysql包下的Driver类是mysql5对应的加载方式
3.连接数据库
DriverManager.getConnection(),创建一个Connection对象,它代表一个物理连接的数据库.
用法:
Connection connection =DriverManager.getConnection(URL,USER,PASS);
URL:jdbc:mysql://ip(127.0.0.1):端口(3306)/数据库名?serverTimezone=Asia/Shanghai USER:用户名(root) PASS:密码
4.发送sql语句
利用Statement接口发送
Connection 接口中的createStatement()方法可以返回一个Statement对象
Statement接口中的方法:
Int executeUpdate(String sql) 用于执行ddl语句和dml(增,删,改)语句 返回操作的行数
其中用于执行ddl语句返回0,用于执行dml语句返回操作的行数
ResultSet executeQuery(String sql); 用于执行查询语句 返回一个ResultSet 集合
int res= statement.executeUpdate("insert into tuser(user_name,user_password,birthday,reg_time)" +
"value ('"+userName+"','"+userPassword+"','"+birthday+"',now())");
注意在参数传入的时候需要拼接字符串,由于sql语句是一个字符串对象,所有用" +参数+ "的方式连接字符串
利用PrepareStatement接口发送
Connection 接口中的prepareStatement(String sql)方法可以返回一个prepareStatement对象
注意:这里sql语句中需要利用?占位符来代替参数的位置,使用setXX方法向sql中设置参数
设置完参数之后再执行sql语句
Int executeUpdate() 用于执行ddl语句和dml(增,删,改)语句 返回操作的行数 同样,用于执行ddl语句返回0,用于执行dml语句返回操作的行数
ResultSet executeQuery(); 用于执行查询语句 返回一个ResultSet 集合
//预编译sql语句到prepareStatement对象中去,但不执行,用?占位符表示参数
PreparedStatement ps= connection.prepareStatement("insert into tuser (user_name,user_password,birthday,reg_time) value(?,?,?,?)");
ps.setObject(1,userName);//设置sql语句中的参数,在此方法中会检测参数是否合法
ps.setObject(2,userPassword);//该方法中的参数的位置是与sql语句中的?符从前往后一一对应的
ps.setObject(3,birthday);
ps.setObject(4,new java.util.Date());//注意这里可以传入一个日期对象
ps.executeUpdate();//执行sql语句
5.关闭与数据库的链接通道
Connection接口,Statement,prepareStatement,ResultSet接口中都有close()方法用于关闭连接
完整代码示例
public static void main(String[] args) throws SQLException, ClassNotFoundException {
//模拟从用户界面获取的用户名与密码还有生日
String userName="admin2";
String userPassword="2222";
String birthday="2020-2-2";
String id="1";
//加载mysql驱动类
//第一种加载方式
DriverManager.registerDriver(new Driver());//注意这里参数有两个类的对象com.mysql.cj.jdbc包中的Driver类是mysql8类
//第二种加载方式
//Class.forName("com.mysql.jc.jdbc.Driver");
//建立与数据库的连接
Connection connection=
DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/chat1?serverTimezone=Asia/Shanghai","root","123456");
//发送sql语句
Statement statement=connection.createStatement();
//修改操作
/*int res= statement.executeUpdate("update tuser set user_name='"+userName+"',user_password='"+userPassword+"'" +
",birthday='"+birthday+"',reg_time=now() where user_id="+id );*/
//删除操作
int res =statement.executeUpdate("delete from tuser where user_id="+id);
System.out.println(res);
//关闭与数据库交互的通道
statement.close();
connection.close();
}
PreapareStatement与Statement的区别
1、代码的可读性和可维护性.
虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无 论从可读性还是可维护性上来说.都比直接用Statement的代码高很多档次:
2.极大地提高了安全性,可以防止sql注入
String sql=“ delete from user where id = ”+num; 此时如果我们把[or 1=1]作为id传入进来 delete from tb_name where id = 1 or 1 = 1; 因为‘1’=‘1’肯定成立,,会导致数据库表中的所有数据被删除
而如果你使用预编译语句.你传入的任何内容就不会和原来的语句发生任何匹配的关系. 这是因为预编译模式中每个占位符处,只能通过set方法插入一个值,而会过滤其他语句.
查询数据结果集的处理
Statement与PrepareStatement对象中都有ResultSet executeQuery()方法可以返回一个ResultSet 接口的对象查询的数据会被封装进入该对象内
● 使用ResultSet中的next()方法获得下一行数据 ● 使用getXXX(String name)方法获得值(getInt(),getString(),getDate(),getTimestamp()等方法可以获取结果集中的数据)
//以PrepareStatement接口为例
ps=connection.prepareStatement("select * from tuser where user_id=?");
ps.setObject(1,id);
ResultSet rs= ps.executeQuery();//执行查询语句
//由于不知道查询出来的语句有多少太,可以用循环接收
while(rs.next()){
user=new User();
user.setUserId(rs.getInt("user_id"));//get方法可以用序号也可以用列名
user.setUserName(rs.getString("user_name"));
user.setBirthday(rs.getDate("birthday"));//getDate()只能返回年月日
user.setRegTime(rs.getTimestamp("reg_time")); //getTimestamp()可以返回年月日时分秒
}
完整代码示例:
public class Demo4 {
public static void main(String[] args) {
String id="2";
User user= null;
try {
//获取单个对象
user = new Demo4().getUserById(id);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
System.out.println(user);
}
//将查询封装在方法中
public User getUserById(String id) throws ClassNotFoundException, SQLException {
User user=null;
Connection connection=null;
PreparedStatement ps=null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
connection= DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/chat1?serverTimezone=Asia/Shanghai","root","123456");
ps=connection.prepareStatement("select * from tuser where user_id=?");
ps.setObject(1,id);
ResultSet rs= ps.executeQuery();//执行查询语句
//由于不知道查询出来的语句有多少太,可以用循环接收
while(rs.next()){
user=new User();
user.setUserId(rs.getInt("user_id"));//get方法可以用序号也可以用列名
user.setUserName(rs.getString("user_name"));
user.setBirthday(rs.getDate("birthday"));//getDate()只能返回年月日
user.setRegTime(rs.getTimestamp("reg_time")); //getTimestamp()可以返回年月日时分秒
}
}finally{
if (ps!=null) {
ps.close();
}
if (connection!=null) {
connection.close();
}
}
return user;
}
}