JDBC学习笔记:(eclipse的几个使用技巧:ctrl+/<用来注释打断数据>;ctrl+1<修改文件中的某个字段>;f3可以找到一个类的源代码或者是一个变量定义的地方);选择重复的代码,右键refactor extract method即可抽象出方法;
一、编写JDBC步骤:
(1)加载驱动;
(2)注册驱动:
1>DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
2>System.setProperty("jdbc.drivers","oracle.jdbc.driver.OracleDriver");
3>Class.forName("oracle.jdbc.driver.OracleDriver");//最常用的方式,因为它在内存中只有一份。而且编译的时候不会报错。
(3)建立连接:
Connection
conn=DriverManager.getConnextion("jdbc:oracle:thin:@localhost:1521:orcl","username","paswor d");
(4)创建执行语句的通道:
Statement st=conn.createStatement();
(5)获得结果集:
ResultSet rs=st.executeQuery("select * from table");
(6)结果处理:
while(rs.next){
...
...
}
(7)释放资源:(在用完时一定要记得释放资源,该资源时非常有限的,如果不马上释放,有可能导致电脑死机。应该最晚打开,最早释放)
rs.close(); st.close(); conn.close();
二、CRUD(一般不要在程序中写*,拿数据时最好按列名称拿)
读取:st.executeQuery("select * from table");
删除:st.executeUpdate(sql);(它的返回值是一个整型值)
查找:st.executeUpdate(sql);
修改:st.executeUpdate(sql);
三、因为在上面的链接数据库过程中,用的是Statement来执行sql语句,它存在sql注入的不安全性,所以不能用Statement,数据库用来另外一种方式来避免这种不安全性,PreparedStatement,它会对sql语句进行预处理,包括特殊字符
(1)Statement在执行的时候接受sql语句,而PreparedStatement在构造的时候接受sql语句:String sql="select * from users where username=?"
PreparedStatement ps=conn.PreparedStatement(sql);
ps.setString(1,name);//1表示第一个问号,name表示?的值。
(2)通常情况下PreparedStatement的效率要比Statement 的高。
ps.executeUpdate();
四、JDBC中的事件处理
因为在项目中,业务逻辑层中使用的Date是Until包中的,可是在Jdbc中使用的是sql包中的,sql中的Date是继承自Until包中的,所以要在数据访问层的Jdbc中要对时间类进行转换。
时间的插入(until中的Date转换成sql中的date):insert into yxt(birthday)values(?);
PreparedStatement ps=conn.preparedStatement(sql);
ps.setDate(1,new java.sql.Date(birthday.getTime()));
ps.executeUpdate();
时间的读取:(sql中的date转换成until中的date):
直接进行赋值:rs.getDate(birthday);(子类给父类赋值可以直接进行赋值);五、JDBC中访问大段文本数据
大短文本的插入:String sql="insert into clob_test(big_test)values(?)";
PreparedStatement ps=conn.prepareStatement(sql);
File file=new File("src");
Reader reader=new BufferedReader(new FileReader(file));
ps.setCharacterStream(1, reader, (int)file.length());
reader.close();
大短文本的读取:
ResultSet rs=ps.executeQuery();
while(rs.next()){
// Clob clob=rs.getClob(1);
// Reader reader1=clob.getCharacterStream();//读取clob中的数据,用来处理字符流的。
Reader reader1=rs.getCharacterStream(1);
File file1=new File("");//存放数据的文件
Writer write=new BufferedWriter(new FileWriter(file1));//将数据写入到file文件中char[] buff=new char[1024];
for(int i=0;(i=reader1.read())>0;){
write.write(buff, 0, i);
}
write.close();
reader1.close();
}
六、大的二进制数插入,如图片
String sql="insert into clob_test(big_test)values(?)";
PreparedStatement ps=conn.prepareStatement(sql);
File file=new File("src");
InputStream in=new BufferedInputStream(new FileInputStream(file));
ps.setBinaryStream(1, in, (int)file.length());
in.close();
大的二进制数读取,如图片
ResultSet rs=ps.executeQuery();
while(rs.next()){
// Blob blob=rs.getBlob(1);
// InputStream input=blob.getBinaryStream();//读取clob中的数据
InputStream input=rs.getBinaryStream(1);
File file1=new File("");//存放数据的文件
OutputStream output=new BufferedOutputStream(new FileOutputStream(file1));//将数据写入到file文件中
byte[] buff=new byte[1024];
for(int i=0;(i=input.read())>0;){
output.write(buff, 0, i);
}
}
七、在程序中,只要关闭Connection,则所有的PreparedStatement,和ResultSet都无效了。
开发步骤:首先写实体类(entity或domain),然后写数据访问层的接口;
八、jdbc中异常的处理
在jdbc中,出现异常一定要让上一层知道。
数据访问层:
package cn.itcast.jdbc.dao;
public class DaoException extends RuntimeException {
private static final long serialVersionUID = 1L;
public DaoException() {
}
public DaoException(String message) {
super(message);
}
public DaoException(Throwable cause) {
super(cause);
}
public DaoException(String message, Throwable cause) {
super(message, cause);
}
}
九、如何使业务逻辑层只与数据访问层的接口有关,而与具体的实现类无关
Properties 文件;
userDaoClass=https://www.wendangku.net/doc/d113102943.html,erDaoJdbcImpl
#userDaoClass=https://www.wendangku.net/doc/d113102943.html,erDaoHibernateImpl
key=value
key1=value1
service文件:
UserDao userDao = DaoFactory.getInstance().getUserDao(); DaoFactory文件:
package cn.itcast.jdbc.dao;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Properties;
class DaoFactory {
private static UserDao userDao = null;
private static DaoFactory instance = new DaoFactory();
private DaoFactory() {
try {
Properties prop = new Properties();
InputStream inStream = DaoFactory.class.getClassLoader()
.getResourceAsStream("daoconfig.properties");
prop.load(inStream);
String userDaoClass = prop.getProperty("userDaoClass");
Class clazz = Class.forName(userDaoClass);
userDao = (UserDao) clazz.newInstance();
} catch (Throwable e) {
throw new ExceptionInInitializerError(e);
}
}
public static DaoFactory getInstance() {
return instance;
}
public UserDao getUserDao() {
return userDao;
}
}
十、JDBC工具类
package cn.itcast.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public final class JdbcUtils {
private static String url = "jdbc:mysql://localhost:3306/jdbc";
private static String user = "root";
private static String password = "";
private JdbcUtils() {
}
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
throw new ExceptionInInitializerError(e);
}
}
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, user, password);
}
public static void free(ResultSet rs, Statement st, Connection conn) { try {
if (rs != null)
rs.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (st != null)
st.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (conn != null)
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
十一、事物(ACID):
1>放在conn.setAutoCommit(false); https://www.wendangku.net/doc/d113102943.html,mit();之间的代码,要么全执行,要么不执行,它们是一个事物。如果不提交事物:conn.rollBack(); 2>保存点的设置(事物回滚的时候只回滚到保存点,保存点之前的都被保存)package cn.itcast.jdbc;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Statement;
public class SavePointTest {
public static void main(String[] args) throws SQLException { test();
}
static void test() throws SQLException {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
Savepoint sp = null;
try {
conn = JdbcUtils.getConnection();
conn.setAutoCommit(false);
st = conn.createStatement();
String sql = "update user set money=money-10 where id=1";
st.executeUpdate(sql);
sp = conn.setSavepoint();
sql = "update user set money=money-10 where id=3";
st.executeUpdate(sql);
sql = "select money from user where id=2";
rs = st.executeQuery(sql);
float money = 0.0f;
if (rs.next()) {
money = rs.getFloat("money");
}
if (money > 300)
throw new RuntimeException("已经超过最大值!");
sql = "update user set money=money+10 where id=2";
st.executeUpdate(sql);
https://www.wendangku.net/doc/d113102943.html,mit();
} catch (RuntimeException e) {
if (conn != null && sp != null) {
conn.rollback(sp);
https://www.wendangku.net/doc/d113102943.html,mit();
}
throw e;
} catch (SQLException e) {
if (conn != null)
conn.rollback();
throw e;
} finally {
JdbcUtils.free(rs, st, conn);
}
}
}