当前位置: 首页 > news >正文

9月21日培训日记

评某位学员(不愿公布其姓名)使用PrepareStatement的代码,该程序代码如下:
package cn.incast;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Logger;

public class DemoClass {
private ConnectionConfig connectionConfig = null;
//private Logger log = Logger.getLogger("cn.incast");
private Connection cn = null;
private PreparedStatement pstmt = null;
private ResultSet rs = null;
public boolean doQuery(String name,String pass) throws IOException, ClassNotFoundException, SQLException
{
cn = this.connectionConfig.foundConnection();
pstmt = cn.prepareStatement("select id from student where user=? and pass=?");
//如果使用Statement类那么查询语句应该是"Select id from Student where name='"+name +"'pass='"+pass"'"
//就容易出现
//使用SQL Server,因为SQL Server中''是转义字符
//name = name.replace("'","''");
//使用MySql ,因为MySql中\是转义字符,而java中\\是字符\
name = name.replace("'","\\'");
pstmt.setString(1,name);
pstmt.setString(2,pass);
rs = pstmt.executeQuery();

boolean bool = true;
if(rs.next())
{
//log.info("WelCome come "+ name +" !");
this.doClose();
return bool;
}
else
{
//log.info("The UserName and Userpassword error !");
bool = false;
this.doClose();
return bool;
}

}

public void doClose()
{
connectionConfig.close(rs,pstmt,cn);
}
public ConnectionConfig getConnectionConfig() {
return connectionConfig;
}

public void setConnectionConfig(ConnectionConfig connectionConfig) {
this.connectionConfig = connectionConfig;
}

}
问题:
(1)使用PrepareStatement后,参数中的单引号(')不用再进行转义处理,该学员的name = name.replace("'","\\'");语句显然有问题,弄巧成拙!
(2)对于boolean bool = true;这条语句:变量命名为bool,显然不如命名为bFound好;另外,boolean变量的初始值设置为false要比设置为true的感觉好得多!
(3)该程序后面的if...else...代码块太幼稚了,if与else中的代码有许多重复,应把这些重复代码放在if...else...代码块的后面,修改成如下形式,就要优雅得多:
boolean bFound = false;
if(rs.next())
{
bFound = true;
}

this.doClose();
return bFound;
两个小技巧:
(1)在实际项目中往数据库里存密码,应采用MD5加密
(2)如果一个函数接受的参数很多,应将这些参数打包成一个对象。
思考:
将mysql连接串写成jdbc:mysql:///itcast:能明白什么意思吗?

复习编写mysql的存储过程,并讲解在jdbc中如何调用存储过程和如何获取存储过程的返回值。李杰实验经验:如果获取是sql server的存储过程返回值,一定要用registerOutParameter方法对返回参数注册,而我们今天在Mysql中获取输出参数的值时,没有调用registerOutParameter。

李杰完成的实验结果:网络断线多长时间,rs.next都可以,但时间较长,cn.createStatement就不行了。
原因与实际问题的思考:网络是虚连接,应考虑web server与database server不在同一台服务器上的时候,网络断线或database server重新启动的情况,这也是cn.createStatement有可能失败的原因之一。

讲解DataSource,各个驱动程序中都应该提供DataSource实现,查看sql server 和mysql的驱动jar包,可以看到它们提供的DataSource实现类。
讲解了连接池的实现原理,再次引出包装设计模式,示意代码如下:
class PooledConnection implements Connection
{
Connection realConnection = null;
Pool pool;
PooledConnection(Connection realConnection,Pool pool)
{
this.realConnection = realConnection;
this.pool = pool;
}

createStatement()
{
realConnection.createStatement();
}

prepareCall()
{
realConnection.prepareCall();
}

close()
{
//realConnection.close();
pool.release(realConnection);
}
}

class Pool
{
public Connection getConnection()
{
Connection realConnection = xxxx;
return new PooledConnection(realConnection,this);
}
}

讲解各种开源框架实现的数据源:Spring的DriverManagerDataSource,Jakarta的BasicDataSource(以及相应的数据源工厂BasicDataSourceFactory),ibatis的SimpleDataSource(以及相应的数据源工厂),hibernate的DriverManagerConnectionProvider。做ibatis实验时,发现即使密码为"",但这一部分也必须设置,找出错误的原因就是在eclipse中查看源代码。
下面是课堂现场讲解中使用spring对上面几个数据源进行实验的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<bean id="dsdemo" class="cn.itcast.DsDemo">
<property name="dataSource">
<ref bean="ds"></ref>
</property>
</bean>
<bean id="ds" class="com.ibatis.common.jdbc.SimpleDataSource">
<constructor-arg>
<props>
<prop key="JDBC.Driver">com.mysql.jdbc.Driver</prop>
<prop key="JDBC.ConnectionURL">jdbc:mysql:///itcast</prop>
<prop key="JDBC.Username">root</prop>
<prop key="JDBC.Password"></prop>
</props>
</constructor-arg>
</bean>
<!-- bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql:///itcast</value>
</property>
<property name="username">
<value>root</value>
</property>
</bean-->
<!-- bean id="ds" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql:///itcast</value>
</property>
<property name="username">
<value>root</value>
</property>
</bean-->
</beans>
作业:
第一小组:dbcp实验,请在程序中硬编码使用BasicDataSourceFactory创建出BasicDataSource对象。
第二小组:hibernate实验,请在程序中硬编码使用Hibernate的DriverManagerConnectionProvider获取连接
第三小组:ibatis实验,请在程序中硬编码使用SimpleDataSourceFactory创建出SimpleDataSource对象。
第四小组:由李杰做一个调用存储函数并获取存储函数返回值的实验。

相关文章:

  • xCode5增加第三方framework包有问题
  • 9月22日培训日记(上)
  • 人脸识别,并生成包含所有人脸的合适UIImage
  • 9月22日培训日记(下)
  • 我认为二氧化碳排放是好事
  • iOS7的UITableViewCell的clipsToBounds默认是YES
  • 发现Hibernate的bug与对Properties的深入认识
  • NSNumber、NSData、NSValue的使用场景
  • Blog小技巧之二-让朋友在Blog上也能QQ到自己
  • 高尔夫实际和弹玻璃珠是一回事
  • 兰德酷路泽原来就是陆地巡洋舰啊
  • 市场上咋没有好的关于嵌入式项目管理的书呢?
  • 比较日期精确到日
  • 一个感人的真事
  • 为什么《Visual Basic 2005程序开发与界面设计秘诀》和《Visual C# 2005程序开发与界面设计秘诀》值得买?...
  • create-react-app项目添加less配置
  • exif信息对照
  • Javascript 原型链
  • js作用域和this的理解
  • Python实现BT种子转化为磁力链接【实战】
  • spring + angular 实现导出excel
  • Spring-boot 启动时碰到的错误
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 聊聊hikari连接池的leakDetectionThreshold
  • 前端自动化解决方案
  • 使用 Docker 部署 Spring Boot项目
  • 使用Gradle第一次构建Java程序
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 问:在指定的JSON数据中(最外层是数组)根据指定条件拿到匹配到的结果
  • 异步
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • 正则学习笔记
  • 2017年360最后一道编程题
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • ​渐进式Web应用PWA的未来
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • #define与typedef区别
  • #if #elif #endif
  • #大学#套接字
  • (1)bark-ml
  • (2022 CVPR) Unbiased Teacher v2
  • (接口封装)
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (四)汇编语言——简单程序
  • (一)UDP基本编程步骤
  • (转)关于如何学好游戏3D引擎编程的一些经验
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • .NET 动态调用WebService + WSE + UsernameToken
  • .NET 中让 Task 支持带超时的异步等待
  • .NET 中什么样的类是可使用 await 异步等待的?
  • .NetCore部署微服务(二)
  • /proc/vmstat 详解
  • @KafkaListener注解详解(一)| 常用参数详解
  • @RequestBody详解:用于获取请求体中的Json格式参数
  • [ Linux ] Linux信号概述 信号的产生