JDBC:
使用java语言去连接数据库,编写SQL语句;
JDBC相关的类库在java.sql.*包下;
JDBC实际上是sun公司定制好的一套接口,纯interface
JDBC编程六步:
·注册驱动;
·获取数据库连接;
·获取数据库操作对象;
·执行SQL语句;
·处理查询结果集;
·释放资源;
第一步:注册驱动:
注册驱动的第一种方式:
Java.sql.Driver driver=new com.mysql.jdbc.Driver();
DriverManager.registerDriver(driver);
(其中com.mysql.jdbc.Driver是mysql数据库实现的接口;
如果使用的是Oracle数据库,直接还成oracle.jdbc,Driver.OracleDriver,即可)
注册驱动的第二种方式:类加载驱动
使用反射机制,反射源代码,源代码中有一个Driver类,实现了com.mysql.jdbc.Driver接口;
该类中有一个静态代码块,该静态代码块中已经编写好了驱动,只要使用反射机制,该静态代码块就会自动运行;
语法:
Class.forName(“com.mysql.jdbc.Driver”);
这是mysql数据库厂家已经编写好的源代码—静态代码块;
第二步:获取数据库连接:
String url=””;
String userName=””; 数据库的登录账号
String password=””; 数据库的登录密码
Connection conn=DriverManager.getConnection(url,userName,password);
第三步:获取数据库操作对象:
Statement sta=conn.createStatement();
通过一个连接对象Connection可以创建多个Statement对象;
第四步:执行sql语句:
编写要执行的sql语句;
private static final String insertUser=“INSERT INTO sys_user(account,user_password,salt,gmt_creat) VALUE(?,?,?,NOW())”;
执行编写好的sql语句,并且返回sql语句执行成功后的影响行数;
sta.executeUpdate(insertUser);
(其中executeUpdate方法是专门负责执行DML语句的,即增改删语句,不包括查询语句)
因此,只有使用查询语句时,才需要执行第五步:处理查询结果集;否则直接跳过第五步,执行第六步;释放资源;
如果是查询语句,那么它使用的将不是sta.executeUpdate(),
而是sta.executeQuery(selectSql);
在ResultSet中有一个next()方法,该方法是判断查询返回的结果集,是否有数据,该方法的返回类型是boolean型;
在ResultSet中所有的数据,不能是什么类型,在获取数据时,都是字符串,getString()方法;以下标取值,
但不是必须以getString()取值,也可以以特定类型取值,例如getInt()等;
同时,还可以根据查询结果的列名取值,假如列名为id或name那么就可以使用id或name进行取值;
第六步:释放资源:
在finally语句中try…catch关闭资源;
关闭资源时,先关闭ResultSet,再关闭Statement,最后关闭Connection;
语法:
Conn.close();
Sta.close();
注:JDBC中所有的下标都是从1开始;
SQL注入问题:
以后开发中,Statement不建议使用,因为它存在SQL注入问题;
推荐使用PreparedStatement,它可以解决SQL问题的注入;
Statement于PreparedStatement的区别:
Statement:
优点:可以对SQL语句进行拼接;
缺点:因为字符串的拼接,存在SQL注入等问题;
PreparedStatement:
优点:可以避免SQL注入问题;
缺点:不能对SQL语句进行拼接,只能给SQL语句传值;
这两个可以根据不同的场景,灵活运用;
JDBC事务:
在实际开发中,经常有一个操作执行多条SQL语句的需求,在默认的情况下,JDBC是支持自动提交事务的,但自动提交事务,会导致一个问题,在某种特殊的情况下,会让一部分的SQL语句执行成功,一部分SQL语句进入异常,无法执行成功;
因此,为了避免这种情况,我们需要将事务提前关闭,等所有SQL语句都执行成功没有异常之后,再手动提交事务;
手动关闭事务:
Conn.setAutoCommit(false); false代表关闭事务,true代表开启事务
手动提交事务:
Conn.commit();
回滚事务:
Conn.rollback();
若在执行SQL语句时,出现异常,可回滚事务;但在回滚之前,为了避免空指针异常,可判断conn不为NULL时,回滚事务;
关于DQL语句的悲观锁:(行级锁)
对于一个DQL语句,是可以在末尾加上这样一个关键字:for update;
加上了for update关键字的含义:
在本次事务的执行过程中,某些记录被查询;
这些记录在我查询的过程中,任何人、任何事务,都不能对其进行修改,直到我当前事务结束为止;
该种机制被称之为:行级锁机制;
在mysql数据库中:
当使用select…for update…where…时,mysql进行的是row lock(行锁)还是table lock(表锁),取决于是否能使用索引(例如主键、unique字段),能则为行锁,否则为表锁,
未查询到数据时,则为无锁;而使用‘<>’、’like’等操作时,索引会失效,自然进行的是table lock(表锁);
因此使用for update时,建议锁主键值,或者是带有unique的字段,锁别的值,可能会导致整张表都被锁住;
注:所以慎用for update;
但在Oracle数据库中,并不是这样的;