1.批量添加
2.字符串拼接
3.事务
4.获得自增的数据
5.添加二进制文件
1.批量添加
Batch
@Test
public void test1(){
Long start = System.currentTimeMillis();
Connection connection = null;
PreparedStatement ps = null;
try {
connection = JDBCUtils.getConnection();
String sql = "insert into user4 values (?,?)";
ps = connection.prepareStatement(sql);
for (int i = 0; i < 1000; i++) {
ps.setObject(1, i);
ps.setObject(2, "Admin" + i);
// ps.addBatch();
ps.execute();
}
// ps.executeBatch();
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.getClose(connection, ps);
}
Long end = System.currentTimeMillis();
System.out.println(end - start);
}
首先要有一个addBatch()。其次还有一个执行的executeBatch()方法
而且需要在url后面添加rewriteBatchedStatements=true
2.字符串拼接
sql注入问题
String sql = "SELECT * FROM t_employee where ename='" + ename + "'";
//如果我此时从键盘输入ename值的时候,输入:张三' or '1'= '1
//结果会把所有数据都查询出来
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);
1.正常拼接解决
String sql = "insert into t_employee(ename,tel,gender,salary) values('" + ename + "','" + tel + "','" + gender + "'," + salary +")";
Statement st = conn.createStatement();
int len = st.executeUpdate(sql);
2.占位符:?
String sql = "insert into t_employee(ename,tel,gender,salary) values(?,?,?,?)";
PreparedStatement pst = conn.prepareStatement(sql);//这里要传带?的sql,然后mysql端就会对这个sql进行预编译
//设置?的具体值
/*pst.setString(1, ename);
pst.setString(2, tel);
pst.setString(3, gender);
pst.setDouble(4, salary);*/
pst.setObject(1, ename);
pst.setObject(2, tel);
pst.setObject(3, gender);
pst.setObject(4, salary);
int len = pst.executeUpdate();//此处不能传sql
System.out.println(len);
3.获取自增的数据
@Test
public void test2()throws Exception{
Class.forName("com.mysql.jdbc.Driver");
//2、获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
//3、执行sql
String sql = "insert into user4 values(null , ?)";
/*
* 这里在创建PreparedStatement对象时,传入第二个参数的作用,就是告知服务器端
* 当执行完sql后,把自增的key值返回来。
*/
PreparedStatement pst = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
//设置?的值
pst.setObject(1, "Admin5");
//执行sql
int len = pst.executeUpdate();//返回影响的记录数
if(len>0){
//从pst中获取到服务器端返回的键值
ResultSet rs = pst.getGeneratedKeys();
//因为这里的key值可能多个,因为insert语句可以同时添加多行,所以用ResultSet封装
//这里因为只添加一条,所以用if判断
if(rs.next()){
Object key = rs.getObject(1);
System.out.println("自增的key值did =" + key);
}
}
//4、关闭
pst.close();
conn.close();
}
需要添加Statement.RETURN_GENERATED_KEYS的参数
4.事务
1.提交commit
2.回滚rollback
需要设置setAutoCommit = false
然后再最后提交,如果出现异常的话则回滚。
public class TestTransaction {
public static void main(String[] args) throws Exception{
/*
* 一般涉及到事务处理的话,那么业务逻辑都会比较复杂。
* 例如:购物车结算时:
* (1)在订单表中添加一条记录
* (2)在订单明细表中添加多条订单明细的记录(表示该订单买了什么东西)
* (3)修改商品表的销量和库存量
* ...
* 那么我们今天为了大家关注事务的操作,而不会因为复杂的业务逻辑的影响导致我们的理解,那么我们这里故意
* 用两条修改语句来模拟组成一个简单的事务。
* update t_department set description = 'xx' where did = 2;
* update t_department set description = 'yy' where did = 3;
*
* 我希望这两天语句要么一起成功,要么一起回滚
* 为了制造失败,我故意把第二条语句写错
* update t_department set description = 'yy' (少了where) did = 3;
*/
//1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2、获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456");
//设置手动提交事务
conn.setAutoCommit(false);
//3、执行sql
String sql1 = "update t_department set description = 'xx' where did = 2";
String sql2 = "update t_department set description = 'yy' did = 3";//这是错的
//使用prepareStatement的sql也可以不带?
PreparedStatement pst = null;
try {
pst = conn.prepareStatement(sql1);
int len = pst.executeUpdate();
System.out.println("第一条:" + (len>0?"成功":"失败"));
pst = conn.prepareStatement(sql2);
len = pst.executeUpdate();
System.out.println("第二条:" + (len>0?"成功":"失败"));
//都成功了,就提交事务
System.out.println("提交");
conn.commit();
} catch (Exception e) {
System.out.println("回滚");
//失败要回滚
conn.rollback();
}
//4、关闭
pst.close();
conn.setAutoCommit(true);//还原为自动提交
conn.close();
}
}