jdbc访问数据库流程
- 驱动管理器:加载jdbc驱动程序
- 连接数据库:建立与数据库的连接
- sql语句:发送sql查询
- 结果集:得到查询结果
jdbc常用接口
接口 | 作用 |
---|---|
Driver接口 | 要连接数据库,必须先装载特定厂商的数据库驱动程序 |
DriverManager接口 | 跟踪可用的驱动程序,并在数据库和相应的驱动程序之间建立连接 |
Connection接口 | 与特定的数据库连接,在连接上下文中执行sql语句并返回结果 |
Statement接口 | 用于执行静态sql语句并返回它所产生结果的对象 |
三种Statement类 | 作用 |
---|---|
Statement | 由createStatement创建,用于发送简单的sql语句(不带参数的) |
PreparedStatement | 继承自Statement接口,由prepareStatement创建,用于发送含有一个或多个输入参数的sql语句。 |
CallableStatement | 继承自PreparedStatement,由方法prepareCall创建,用于调用存储过程 |
常用的Statement方法 | 作用 |
---|---|
execute() | 运行语句,返回是否有结果集 |
executeQuery() | 运行select语句,返回ResultSet结果集 |
executeUpdate() | 运行insert/update/delete操作,返回更新的行数 |
与数据库建立连接:
Class.forName("com.mysql.jdbc.Driver");//加载驱动器
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc");//建立连接
Statement类的使用方法:
Statement stmt = conn.createStatement();
String name = "张三";
String sql = "insert into t_user(username, pwd, regTime) values ('"+name+"', 333, now())";
stmt.execute(sql);
sql注入:
String id = "5";
String sql = "delete from t_user where id = "+id;
stmt.execute(sql);
用以上方式的时候只要外部程序把id的内容改成"5 or 1=1"
,那么就会将表里面所有的内容删掉。如果是update语句的话,也可以通过这种方式任意修改表的内容。所以使用Statement这种方式不是特别安全,在实际开发中一般使用prepareStatement。
prepareStatement的使用
PrepareStatement ps = conn.prepareStatement("insert into t_user(username, pwd, regTime) values(?, ?, ?)");//问号表示占位符,接下来我们需要set的值
ps.setObject(1, "username1");
ps.setObject(2, "pwd1");
ps.setObject(3, new java.sql.TimeStamp(System.currentTimeMillis));
ps.execute();
ps.setObject()
的第一个参数表示的是问号的索引,第二个参数就是传入的值。setObject()
也可以用setString()
或setDate()
等代替。
ResultSet集的用法
String sql = "seect * from";//这句话没用,但是不加入这句话,下面的select语句会显示错误
ps = conn.prepareStatement("select * from t_user where id > ?");
ps.setObject(1, 2);//把大于2的取出来
ResultSet rs = ps.executeQuery();
while (re.next()) {
System.out.println(rs.getInt(1)+"---"+rs.getString(2)+"---"+rs.getString(3)+"---"+rs.getString(4));//将表记录打印出来
}
批处理
conn.setAutoCommit(false);//设置手动提交
Statement stmt = conn.createStatement();
for(int i=0, i<20000, i++) {
stmt.addBatch("insert into t_user(username, pwd, regTime) values('user"+(i+1)+"', '666666', now())");
}
stmt.executeBatch();
conn.commit();
事务
在批处理里中用到了setAutoCommit()
和commit()
这两个语句关系到事务的概念。我的理解是事务就是多个语句的集合体,它是一个执行单元,一个语句执行不通过,其他语句也会执行失败。一个连接的事务默认是自动提交的,就是说一句语句在调用execute()
后自动提交
conn.setAutoCommit(false);//将事务提交设置为手动提交
PrepareStatement ps1 = conn.prepareStatement("insert into t_user(username, pwd) values(?, ?)");
ps1.setObject(1, "user1");
ps1.setObject(2, "111");
ps1.execute();
PrepareStatement ps2 = conn.prepareStatement("insert into t_user(username, pwd) values(?, ?)");
ps2.setObject(1, "user2");
ps2.setObject(2, "222");
ps2.execute();
conn.commit();
以上代码的ps1和ps2要么同时执行成功,要么同时失败。
以上内容基于尚学堂高淇300集