readPrepared("'or 1 or'");就不会全部查出来了,只会查询空结果,因为表中没有一个学生的名字叫做 'or 1 or'。
下面再来看一下JDBC中特殊数据类型的操作问题
第一个是日期问题:
我们在操作日期问题的时候会发现,使用PreparedStatement进行参数赋值的时候,有一个方法是:setDate(...),但是这个方法接收的参数是sql中的Date类,而不是我们平常使用的util中的Date类,所以我们要做一次转化,通常我们是这样做的,就是在定义实体类的时候将其日期型的属性定义成util中的Date类型,在进行数据库操作的时候.
进行一次转换:setDate(x,new Date(birthday.getTime());,这里birthday就是一个util.Date类型的一个属性,而new Date是sql.Date类型的,这样转化就可以了,同样我们在读取数据的时候将转化操作反过来即可。
第二个问题就是大文本数据的问题,因为有时候我们会存入一些文本内容,因为varchar的大小在mysql中也是有上线的,所以我们这里要使用blob类型了,我们这里来看一下实例:
/**
* 插入大文本
*/
static void insert(){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
conn = JdbcUtils.getConnection();
String sql = "insert into clob_test(bit_text) values( )";
ps = conn.prepareStatement(sql);
File file = new File("src/com/weijia/type/ClubDemo.java");
Reader reader = new BufferedReader(new FileReader(file));
//ps.setAsciiStream(1, new FileInputStream(file), (int)file.length());//英文的文档
ps.setCharacterStream(1, reader, (int)file.length());
ps.executeUpdate();
reader.close();
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtils.free(rs,ps,conn);
}
}我们将一个Java代码文件插入到数据库中
我们查询一下clob_test表:

我们看到文件内容存入到库中了。同样我们也可以从表中读取一段文本出来,使用
Clob clob = rs.getClob(1); InputStream is = clob.getAsciiStream();或者读取一个Reader也是可以的,这里的InputStream和Reader是针对不同流,一个字节流,这个不需要关心编码问题的,Reader是字符流需要关心编码问题。
下面再来看一下JDBC中事务的概念:
我们当初在学习数据库的时候就了解事务的概念了,事务在数据库中的地位是很重要的。在JDBC中默认情况事务是自动提交的,所以我们在进行CRUD操作的时候不需要关心开启事务,提交事务,事务回滚的一些操作,那么下面我们就来看一下怎么手动的操作一些事务:
下载我们假定这样的一个场景:
有来两个用户1和2,现在
将用户1中的账户的钱减少10
查询用户2中的账户的钱,如果钱少于300,就增加10,否则抛出异常
看一下代码:
static void test() throws Exception{
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try{
conn = JdbcUtils.getConnection();
/**************事务START********************/
conn.setAutoCommit(false);
st = conn.createStatement();
String sql = "update user set money=money-10 where id=1";
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);
conn.commit();
/*******************事务END*********************/
}catch(RuntimeException e){
}finally{
JdbcUtils.free(rs, st, conn);
}
}我们运行测试一下,因为我们这里想让它抛出异常,所以我们将用户2中的钱改成大于300的,运行一下,结果抛出异常了,但是我们发现了用户1中的钱少了10,但是由于抛出异常,所以后面的代码不执行了,用户2中的钱没有变化,那么这样的操作明显不对的,所以我们这时候要解决这个问题,使用事务的回滚操作,在捕获到异常的时候需要做回滚操作:
if(conn != null){
conn.rollback();
}这样即使抛出了异常,这些操作也会进行回滚的,那么用户1中的钱就不会少10了。
同时上面我们看到,我们是在开始的时候手动的关闭事务的自动提交,然后再手动的提交事务,下面再来看一下事务的保存点的问题。
场景:在上面的基础上,我们添加一个用户3,同时对用户1和用户3中的钱进行减少10,用户2的操作不变,但是当抛出异常的时候,我们希望用户1的操作还是有效的,用户3的操作还原,这时候我们需要将事务回滚到用户3的那个点就可以了,这就是事务的保存点的概念,看一下代码:
static void test() throws Exception{
Connection conn = null;
State