传智播客李勇Jdbc视频笔记(7-17)

7、PerparedStatement的应用:
在上面的例子中,我们看到了在构造sql语句的时候使用拼串的方式会有sql注入的问题,这个时候我们可以用
PreparedStatement 来解决这个问题
public void read(String name) {
......
PreparedStatement ps = null;
String sql = "select * from xxx where name = ?";
ps = conn.prepareStatement(sql);
ps.setString(1, name);
rs = ps.executeQuery();
......
..
}

如果我们采用上面的方式来构造sql语句就不会有sql注入问题了,因为PerparedSatatement会对传递给他的sql
语句进行一系列的处理。然后再执行。
注意:rs = ps.executeQuery()如果你写成了rs = ps.executeQuery(sql)编译器也是不会报错的,因为PerparedSatement
是从Satement继承来的,所以如果你调用的是ps.executeQuery(String sql)这个带有参数的方法的时候,其实是调用的
Statement接口的方法,因为你上面sql语句是用PerparedStatement的方式进行构造的 用?代替了参数部分,这个时候会包
错误说 ? 是非法字符,因为调用的是Statement的方法他不会对?进行处理直接传递给数据库执行,而数据库是不能解析
这个字符的。

总结:
在SQL中包含特殊字符或SQL的关键字(如:' or 1 or ')时Statement将出现不可预料的结果(出现异常或查询的结果不正确),可用PreparedStatement来解决。
PreperedStatement(从Statement扩展而来)相对Statement的优点:
1.没有SQL注入的问题。
2.Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。
3.数据库和驱动可以对PreperedStatement进行优化(只有在相关联的数据库连接没有关闭的情况下有效)。

9、Eclipse的使用问题
10、jdbc中的数据类型与日期问题
public class DateTest {
public static void main(String[] args) throws SQLException {
// create("name2", new Date(), 500.0f);
Date d = read(7);
System.out.println(d);
}

static Date read(int id) throws SQLException {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
Date birthday = null;
try {
// 2.建立连接
conn = JdbcUtils.getConnection();
// conn = JdbcUtilsSing.getInstance().getConnection();
// 3.创建语句
st = conn.createStatement();

// 4.执行语句
rs = st.executeQuery("select birthday from user where id=" + id);

// 5.处理结果
while (rs.next()) {
//birthday = new Date(rs.getDate("birthday").getTime());
//取值的时候是java.sql.Date赋值给一个父类类型java.util.Date是没有问题的
birthday = rs.getDate("birthday");
}
} finally {
JdbcUtils.free(rs, st, conn);
}
return birthday;
}

static void create(String name, Date birthday, float money)
throws SQLException {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
// 2.建立连接
conn = JdbcUtils.getConnection();
// conn = JdbcUtilsSing.getInstance().getConnection();
// 3.创建语句
String sql = "insert into user(name,birthday, money) values (?, ?, ?) ";
ps = conn.prepareStatement(sql);
ps.setString(1, name);
//插入的时候传递的是java.util.Date而方法要求的是java.sql.Date,所以要进行一下转化
ps.setDate(2, new java.sql.Date(birthday.getTime()));
ps.setFloat(3, money);

// 4.执行语句
int i = ps.executeUpdate();

System.out.println("i=" + i);
} finally {
JdbcUtils.free(rs, ps, conn);
}
}
}


11、jdbc访问大段文本数据:数据库产品不一样,字段可能不同:mysql:Text Oracle:可能是Clob

//存储大段文本数据
public static void clobTest() throws SQLException, IOException {
Connection conn = JdbcUtils.getConnection();
String sql = "insert into clob(content) values (?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
//把一个文件的内容读进来存储到数据库中
File file = new File("src/org/guo/jdbc/JdbcUtils.java");
//如果你把reader转换为数组,然后再转换成String,在这个地方可以直接pstmt.setString()
//前提是你的数据库的那个字段规定的是Clob(Text)类型,那么在下面取数据的时候
//可以直接getString()进行读取操作。
Reader reader = new BufferedReader(new FileReader(file));
//以字符流的方法设置参数
pstmt.setCharacterStream(1,reader, file.length());
pstmt.executeUpdate();
}

//读取大段文本数据
public static void readTest() throws SQLException, IOException {
Connection conn = JdbcUtils.getConnection();
String sql = "select content from clob";
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
while(rs.next()) {
//字符大对象
Clob clob = rs.getClob(1);
//下面两种方式都可以
//Reader reader = clob.getCharacterStream();
Reader reader = rs.getCharacterStream(1);
File fileBak = new File("jdbcUtils.bak.java");

Writer writer = new BufferedWriter(new FileWriter(fileBak));
char[] data = new char[1024];
//reader.read(data):把读取到的一个字符放到data字符数组中
for(int i=0; (i=reader.read(data)) >0;) {
//把字符数组中的内容写到文件中
writer.write(data, 0, i);
}
writer.close();
reader.close();
}
}


12、jdbc访问二进制类型的数据

//存储二进制数据(图片为例)
public static void blobTest() throws SQLException, IOException {
Connection conn = JdbcUtils.getConnection();
String sql = "insert into t_blob(big_bit) values (?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
File file = new File("baby.gif");
InputStream in = new BufferedInputStream(new FileInputStream(file));
pstmt.setBinaryStream(1, in, file.length());
pstmt.executeUpdate();
}

//读取二进制数据
public static void readTest() throws SQLException, IOException {
Connection conn = JdbcUtils.getConnection();
String sql = "select big_bit from t_blob";
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
while(rs.next()) {
//二进制大对象
Blob blob = rs.getBlob(1);
//下面两种方式都可以
//Reader reader = clob.getCharacterStream();
InputStream in = blob.getBinaryStream();
//下面这种方式也可以,和读取大段文本数据的原理是一样的
//InputStream in = rs.getBinaryStream(1);
File imgBit = new File("baby2.gif");

OutputStream out = new BufferedOutputStream(new FileOutputStream(imgBit));
byte[] data = new byte[1024];
for(int i=0; (i=in.read(data)) >0;) {
out.write(data, 0, i);
}
out.close();
in.close();
}
}

13、JDBC_jdbc访问其他各种数据类型:解释数据库中的类型与java中的数据类型的相互的对应关系--------->查看mysql的参考文档

14、传智播客JDBC_答疑学员的索引号问题

15、分析在实际项目中该如何应用

[img]http://dl.iteye.com/upload/attachment/229131/d85facce-6862-33ab-b00c-6d1e4a988668.jpg[/img]

我们上面的例子程序都是简单的在控制台打印一下,但是在真实的开发中不可能这样,那么我们能不能返回ResultSet对象呢?
这个其实是不可以的当Connection关闭之后,ResultSet中的数据你就拿不到了。如果我们要进行传值需要定义个domain对象。
16、DAO设计思想与搭建骨架

17、结合Service层讲解DAO层的异常处理
在处理异常的时候,不能catch住异常之后什么都不做,最起码要打印一下堆栈,最好的方式是将这个异常转化为RuntimeException抛出
如果出现了异常,你catch住了,程序会继续往下执行。如果你throw出来了 程序就不继续往下运行了
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值