PreparedStatement批处理和延迟加载
什么是PreparedStatement接口
预编译的Statement对象,PreparedStatement是Statement的子接口,它允许数据库预编译sql语句(这些sql语句通常带有参数),以后每次只改变sql命令的参数,避免数据库每次都需要编译sql语句,无需再传入sql语句,只要为预编译的sql语句传入参数值即可。
继承Statement接口,功能更多更强大。可以预处理,批处理,延迟加载。
说了半天估计没懂,举个例子:现在公司来了一个新员工,我们需要向员工表(emp)中插入一条数据,里面包括新入值员工信息,当然,这些信息是活动的,今天来的人不可能和明天来的人是同一个人,这都是变化的,不可能像之前插入的方法一样,所以这里我们需要用PreparedStatement
来动态获取。
首先用普通方法Statement动态获取参数:
Statement执行增删改查操作的时候不具备延迟加载,不具备批处理方式,所以一般不推荐使用,常用的是preparedstatement。
- 定义方法inserEmp,参数列表放在map集合中
- 加载驱动
Class.forName
- 创建数据库连接
Connection conn= DriverManager.getConnection
- 返回它所生成结果的对象Statement:
Statement stmt = conn.createStatement()
- 放入参数
String XXX = map.get("XXX")
- 书写SQL语句:
String sql="......";
stmt.execute(sql)
- 关闭连接
public class MyEmpDemo {
public boolean inserEmp(Map<String, String> map){ //定义方法inserEmp,参数列表在map集合中
boolean b=false;
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db214","root","123456");
Statement stmt = conn.createStatement();
//参数列表:empno:10000,ename:lisi,job:clerk,sal=3000,deptno=20
String empno = map.get("empno"); //员工编号
String ename = map.get("ename"); //员工姓名
String job = map.get("job"); //员工职位
String sal = map.get("sal"); //员工薪资
String deptno = map.get("deptno"); //所在部门
String sql="insert into emp(empno,ename,job,sal,deptno) values("+empno+",'"+ename+"','"+job+"',"+
sal+","+deptno+");";
System.out.println(sql);
b= stmt.execute(sql);
System.out.println(b);
if (b) {
System.out.println("数据插入成功!");
}else{
System.out.println("数据插入失败!");
}
return b;
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
return b;
}
}
public static void main(String[] args) {
//参数列表:empno:10000,ename:lisi,job:clerk,sal=3000,deptno=20
MyEmpDemo med=new MyEmpDemo();
Map<String, String> map=new HashMap<>();
map.put("empno","10000");
map.put("ename","lisi");
map.put("job","clerk");
map.put("sal","3000");
map.put("deptno","20");
med.inserEmp(map);
}
}
用PreparedStatement来实现动态获取:
list套map存放数据,然后foreach获取参数列表
- 加载驱动
Class.forName
- 创建数据库连接
Connection conn= DriverManager.getConnection
- 定义SQL语句:
String sql=“......”;
- 定义preparedstatement对象
PreparedStatement ps = conn.prepareStatement(sql)
- 执行批处理:
int[] is = ps.executeBatch();
- 关闭连接
public class MyPreparedStatement {
public int myInsertBatch(List<Map<String, String>> paramlist){
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db214","root","123456");
String sql="insert into emp(empno,ename,job,mgr,deptno) values (?,?,?,?,?)"; //定义sql语句,参数值延迟加载
PreparedStatement ps = conn.prepareStatement(sql);//定义preparedstatement对象
for(Map<String, String> map : paramlist){//foreach获取参数列表
ps.setString(1, map.get("empno"));//获取list-map-每个字段
ps.setString(2, map.get("ename"));
ps.setString(3, map.get("job"));
ps.setString(4, map.get("mgr"));
ps.setString(5, map.get("deptno"));
ps.addBatch(); //将获取到的参数放置到批处理中
}
int[] is = ps.executeBatch();//执行批处理,返回值是数组记录批处理操作每条sql语句的结果数
for(int i: is){
System.out.println(i);
}
return is.length; //数据操作成功的数组个数
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return 0;
}
public static void main(String[] args) {
List<Map<String, String>> paramlist=new ArrayList<>();//定义list集合参数,里面是map集合参数
for(int i=0;i<5;i++){
Map<String, String> map=new HashMap<>();
map.put("empno", 10000+i+"");
map.put("ename", "wangwu"+i);
map.put("job", "wangwu"+i);
map.put("mgr", 3000+i+"");
map.put("deptno", "20");
paramlist.add(map);
}
MyPreparedStatement ms=new MyPreparedStatement();
ms.myInsertBatch(paramlist);//调用批量执行方法
}
}