JDBC的进化3
这次进化完成后,JDBC的进化就需要设置1个savepoint了,然后提交1下,提交到我们的脑袋硬盘中。
问题2: String user = "' OR 1 = 1--'";
SELECT *
FROM user_table
WHERE user = '"+user+"'; 大家知道产生了甚么?我把整张表的信息都获得了,包括密码(你的银行账户密码被我知道了),太可怕了! 这就是SQL注入问题,也是我要说的第2个问题。 Solution:
先看第1句:代表1个预编译的SQL命令对象 @Test
public void testPrepareSelect(){
String sql = "SELECT * FROM users WHERE id = ?;";
// get connection
Connection conn = null;
// get PreparedStatement's object
PreparedStatement ps = null;
// execute the sql
ResultSet rs = null;
try {
conn = JDBCUtils.getConnection();
ps = conn.prepareStatement(sql);
// set the ?
ps.setInt(1,1);
// execute the sql
rs = ps.executeQuery();
// get the rs
if(rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name");
String address = rs.getString("address");
String phone = rs.getString("phone");
User user = new User(id,name,address,phone);
System.out.println(user);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(rs,ps,conn);
}
} 是否是发现个问号,然后给这个问号设置值?问:这个问号是甚么东东啊?答:这个问号相当于1个占位符,我就把这个位置占住了。要不为何叫预编译。 /**
* PreparedStatement: through the reflect and generic and PreparedStatement
* @param sql
* @param clazz
* @param args
* @return
*/
public <T> T getPrepareSelect(String sql,Class<T> clazz,Object ... args){
T t = null;
// get the connection
Connection conn = null;
// get the PreparedStatement's object
PreparedStatement ps = null;
// execute the ps
ResultSet rs = null;
try {
conn = JDBCUtils.getConnection();
ps = conn.prepareStatement(sql);
// set values for ps
for(int i = 0; i < args.length; i++){
ps.setObject(i+1,args[i]);
}
rs = ps.executeQuery();
// get the ResultSetMetaData's object
ResultSetMetaData rsmd = rs.getMetaData();
// get the columnNum
int columnNum = rsmd.getColumnCount();
// read the data of rs,and packaging an object
if(rs.next()){
t = clazz.newInstance();
for(int i = 1; i <= columnNum; i++){
// get the columnName and columnValue of the special row special column
String columnName = rsmd.getColumnLabel(i);
Object columnValue = rs.getObject(columnName);
// through the generic put the columnValue to the Class' field
Field userField = clazz.getDeclaredField(columnName);
userField.setAccessible(true);
userField.set(t,columnValue);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(rs,conn);
}
return t;
} 我靠,你这写的甚么东西啊? 我就问你你还记得反射和泛型吗? 由于要写成通用的, 这里出现了个这东西:ResultSetMetaData 它是用来描写ResultSet的,我们知道ResultSet存的是1张数据表,而ResultSetMetaData就是用来描写这张表的,包括他有几列,每列是甚么。 现在读我这个程序是否是感觉好多了? 也不过如此么!!! 从具体到1般,我们上面写的仅仅是查询1条记录的。 /**
* PreparedStatement : getAll
* @param sql
* @param clazz
* @param args
* @return
*/
public <T> List<T> getAll(String sql,Object ... args){
List<T> list = new ArrayList<T>();
// get connection
Connection conn = null;
// get PreparedStatement
PreparedStatement ps = null;
// execute the sql
ResultSet rs = null;
try {
conn = JDBCUtils.getConnection();
ps = conn.prepareStatement(sql);
// set the ps
for(int i = 0; i < args.length; i++){
ps.setObject(i+1,args[i]);
}
rs = ps.executeQuery();
// get the columnNum
ResultSetMetaData rsmd = rs.getMetaData();
int columnNum = rsmd.getColumnCount();
// read the rs and write to an object
while(rs.next()){
T t = clazz.newInstance();
for(int i = 1; i <= columnNum; i++){
// read
String columnName = rsmd.getColumnLabel(i);
Object columnVal = rs.getObject(columnName);
// write
// through the field(reflect)
//Field field = clazz.getDeclaredField(columnName);
//field.setAccessible(true);
//field.set(t,columnVal);
// through the method(reflect)
PropertyUtils.setProperty(t,columnName,columnVal);
}
list.add(t);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(rs,conn);
}
return list;
} 来了,相比于上1个来讲,这个其实很简单了,只不过是增加了1个 这里来讲预编译: 通过上面1段话:有产生了1个新的东西: 这些说完了,我们来测试测试他和Statement的效力,不然你们还以为我骗你们,说PreparedStatement效力高。 @Test
public void testStatement() {// 260111
long start = System.currentTimeMillis();
Connection conn = null;
Statement statm = null;
try {
conn = JDBCUtils.getConnection();
statm = conn.createStatement();
for (int i = 0; i < 100000; i++) {
String sql = "insert into emp1 values(" + i + ",'emp" + i
+ "')";
statm.executeUpdate(sql);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(statm,conn);
}
long end = System.currentTimeMillis();
System.out.println("the time is :" + (end - start));
} 履行时间: @Test
public void testPreparedStatment() {// 141991
long start = System.currentTimeMillis();
// get connection
Connection conn = null;
// get PreparedStatement's object
PreparedStatement ps = null;
try {
conn = JDBCUtils.getConnection();
String sql = "insert into emp1 values(?,?)";
ps = conn.prepareStatement(sql);
for (int i = 0; i < 100000; i++) {
ps.setInt(1,i + 1);
ps.setString(2,"emp" + i);
ps.executeUpdate();
}
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(null,conn);
}
long end = System.currentTimeMillis();
System.out.println("the time is :" + (end - start));
} 141991ms 快了接近1倍 @Test
public void testStatement2() {// 271924
long start = System.currentTimeMillis();
Connection conn = null;
Statement statm = null;
try {
conn = JDBCUtils.getConnection();
statm = conn.createStatement();
for (int i = 0; i < 100000; i++) {
String sql = "insert into emp1 values(" + i + ",'emp" + i
+ "')";
statm.addBatch(sql);
if ((i % 250) == 0) {
statm.executeBatch();
statm.clearBatch();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(statm,conn);
}
long end = System.currentTimeMillis();
System.out.println("the time is :" + (end - start));
} 271924ms 好慢 PreparedStatement: @Test
public void testPreparedStatement2() {// 3230
long start = System.currentTimeMillis();
// get connection
Connection conn = null;
// get PreparedStatement's object
PreparedStatement ps = null;
try {
conn = JDBCUtils.getConnection();
String sql = "insert into emp1 values(?,"emp" + i);
ps.addBatch();
if ((i % 250) == 0) {
ps.executeBatch();
ps.clearBatch();
}
}
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(null,conn);
}
long end = System.currentTimeMillis();
System.out.println("the time is :" + (end - start));
} 3230ms 甚么???这么快!!! 我们接下来讲事务,我还是分开写吧,这个太长了,不好浏览。没耐心的观众已坐不住了!! 补充1点:大数据处理,这里只提供代码示例,可以参考着去研究研究 @Test
public void get(){
String sql = "select * from customers where id = ?";
Connection conn = null;
PreparedStatement ps = null;
InputStream is = null;
ResultSet rs = null;
OutputStream os = null;
try {
// get connection
conn = JDBCUtils.getConnection();
// get PreparedStatement's object
ps = conn.prepareStatement(sql);
ps.setInt(1,22);
// execute the ps
rs = ps.executeQuery();
while(rs.next()){
int id = rs.getInt(1);
String name = rs.getString(2);
String email = rs.getString(3);
Date birth = rs.getDate(4);
Customer customer = new Customer(id,email,birth);
System.out.println(customer);
Blob blob = rs.getBlob(5);
is = blob.getBinaryStream();
os = new FileOutputStream("1.jpg");
byte[] b = new byte[1024];
int len = 0;
while((len = is.read(b)) != -1){
os.write(b,0,len);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
JDBCUtils.close(rs,conn);
}
} 大数据的写入: public int insertBlob() {
String sql = "insert into customers values(?,?,?)";
// get connection
Connection conn = null;
// get PreparedStatement's object
PreparedStatement ps = null;
// execute ps
int rows = 0;
try {
conn = JDBCUtils.getConnection();
ps = conn.prepareStatement(sql);
ps.setInt(1,22);
ps.setString(2,"lisi");
ps.setString(3,"lisi@abc.com");
ps.setDate(4,new Date(new java.util.Date().getTime()));
ps.setBlob(5,new FileInputStream("089.jpg"));
rows = ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(ps,conn);
}
return rows;
} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |