JDBC小结
JDBC:(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API。与数据库建立连接、发送 操作数据库的语句并处理结果。
一、创建连接:两种方式。先创建一个配置文件 driver.properties
1.创建一个连接:Connection();代码如下:
public class JDBCTools {
private static Properties p1;
private static String user;
private static String password;
private static String url;
private static boolean ok=false;
static{
p1=new Properties();
try {
p1.load(JDBCTools.class.getResourceAsStream("/driver.properties"));
Class.forName(p1.getProperty("driverClass"));
Url = p1.getProperty("url");
User = p1.getProperty("user");
password=p1.getProperty("password");
ok=true;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection(){
if(ok){
try {
Return DriverManager.getConnection(url,user,password);
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
2.创建一个连接池:ComboPooledDataSource();代码如下:
public class JDBCTools {
private static ComboPooledDataSource cpd;
private static Properties p1;
private static boolean ok=false;
static{
if(cpd==null){
cpd=new ComboPooledDataSource();
}
p1=new Properties();
try {
p1.load(JDBCTools.class.getResourceAsStream("/driver.properties"));
cpd.setDriverClass(p1.getProperty("driverClass"));
cpd.setJdbcUrl((p1.getProperty("url")));
cpd.setUser((p1.getProperty("user")));
cpd.setPassword((p1.getProperty("password")));
cpd.setMaxPoolSize(Integer.parseInt(p1.getProperty("max")));
cpd.setMaxPoolSize(Integer.parseInt(p1.getProperty("min")));
cpd.setMaxPoolSize(Integer.parseInt(p1.getProperty("init")));
cpd.setMaxPoolSize(Integer.parseInt(p1.getProperty("dealtime")));
ok=true;
} catch (IOException e) {
e.printStackTrace();
} catch (PropertyVetoException e) {
e.printStackTrace();
}
}
public static Connection getConnection(){
if(ok)
try {
return cpd.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}finally{
}
return null;
}
二、Statement(数据库指令操作工具)
1、createStatement()//创建statement对象,不传入sql语句。
编写一个方法,对数据库进行插入操作,如下:
public boolean insert(){
Connection c1=JDBCTools.getConnection();
Statement st=null;
try {
st=c1.createStatement();
//将要进行的数据库操作,将sql语句传给executeUpdate();可进行增、删、改
return st.executeUpdate("insert into dept(deptno,dname,loc) values(100,'科研部','北京')")>0;
} catch (SQLException e) {
e.printStackTrace();
}finally{
//另写的一个静态方法关闭statement,resultSet,connection;
JDBCTools.close(st, c1, null);
}
return false;
}
PreparedStatement(预处理指令装置)(推荐使用)
PreparedStatement()//将sql语句传入Preparedstatement对象中。
1.准备sql语句,对参数使用占位符?
2.为sql语句中的占位符赋值,setObject(argIndex,values);
executeUpdate(),对数据库进行增删改
/**
*sql:为要进行操作的sql语句 形如:” insert into dept(deptno,dname,loc) values(?,?,?)”
*args:为将要传给sql语句中占位符?的值
*/
public boolean insert(String sql,Object...args){
Connection c1=JDBCTools.getConnection();
PreparedStatement ps=null;
try {
//对sql语句进行处理,值可用占位符?代替
ps=c1.prepareStatement(sql);
//为sql语句中的占位符赋值
for (int i = 0; i < args.length; i++) {
ps.setObject(i+1, args[i]);
}
return ps.executeUpdate()>0;
} catch (SQLException e) {
e.printStackTrace();
}finally{
JDBCTools.close(ps, c1, null);
}
return false;
}
三、ResultSet 对象具有指向其当前数据行的光标。
最初光标被置于第一行之前;next()方法将光标下移一行。没有下一行时返回false,可用while迭代返回结果集。
利用getInt(colunmIndex),getString(colunmName)方法定位列。
我们利用它进行查询操作,代码如下:
/**
*根据数据库表的信息,封装一个工具类ClassOfDept,将表dept的列名声明为ClassOfDept的属性
*返回一个装有ClassOfDept类的对象的List
*/
public List<ClassOfDept> select(){
Connection c1=JDBCTools.getConnection();
PreparedStatement ps=null;
ResultSet rs=null;
try {
ps=c1.prepareStatement("select *from dept");//预处理sql语句
rs=ps.executeQuery();
List<ClassOfDept> l1=new ArrayList<ClassOfDept>();//创建一个list,用于存放ClassOfDept类的对象。
//resultSet迭代获取表中每一行的数据。
while(rs.next()){
ClassOfDept cd=new ClassOfDept(rs.getInt(1),rs.getString("dname"),rs.getString("loc"));//将获得的数据封装成一个ClassOfDept类的对象。
l1.add(cd);//将封装好的对象存入List中。
}
return l1;//返回LIst。
} catch (SQLException e) {
e.printStackTrace();
}finally{
JDBCTools.close(ps, c1, rs);
}
return null;
}
四、事务处理
1.事务由一个或多个这样的语句组成:这些语句已被执行、完成并被提交或还原。2.当调用方法commit或rollback时,当前事务即告就结束,另一个事务随即开始。
3.缺省情况下,新连接将处于自动提交模式。即当执行完语句后,将自动对那个语句调用commit方法。这种情况下,每个语句都是被单独提交的,因此一个事务只由一个语句组成。
4.如果禁用自动提交模式,事务将要等到commit或rollback方法被显式调用时才结束,因此它将包括上一次调用commit或rollback方法以来所有执行过的语句。
则事务中的所有语句将作为组来提交或还原。
5.如果多个操作都成功,则调用commit方法,从而使多个操作结果成为永久性的;如果其中存在失败的操作,则调用rollback方法,以将值恢复为进行操作之前的值。
例:
/**
*下列代码为两个插入数据的事务处理操作。当其中一个操作失败时,另一个操作也无法完成,并还原至操作前。
粗体代码为事务处理的关键代码。
*/
public static void main(String[] args) {
Connection c1=JDBCTools.getConnection();
PreparedStatement ps1=null;
PreparedStatement ps2=null;
Savepoint sp=null;
try {
c1.setAutoCommit(false);//设置为手动提交
sp=c1.setSavepoint();//设置保存点
ps1=c1.prepareStatement("insert into dept(deptno,dname,loc) values(3,'疗养院','青岛')");
ps2=c1.prepareStatement("insert into dept(deptno,dname,loc) values(2,'体育部','青岛')");
PreparedStatement[] ps=new PreparedStatement[]{ps1,ps2};
for (int j = 0; j < ps.length; j++) {
int a= ps[j].executeUpdate();
ps[j].close();
}
c1.commit();//都成功时提交
System.out.println("ok");
} catch (SQLException e) {
e.printStackTrace();
try {
c1.rollback(sp);//滚回至保存点sp。
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
JDBCTools.close(null, c1, null);
}
}