DAO与预编译语句
(先回复一下什么是DAO,ORM,domain)
1.DAO也叫DAO组件,它是Java代码和数据库之间的一个交接的东西,比如它负责加载驱动,连接数据库创建语句,执行语句,释放资源等操作都由DAO包装起来
2.ORM就是就是对象关系映射,就是将数据库中的每一张表对应成一个对象,将表中的数据以对象的实例来表示
3. domain就是一个类,一个符合JavaBean的类,它是用户和数据库交换的核心中转站,可以理解成ORM的结果就是domain类
DAO设计规范
-
编写DAO组件
1.定义DAO接口
2.编写对应DAO实现类 -
为什么要定义接口
2.1接口就是只给出了函数声明,但是是没有函数体类。函数体在实现类中给出
2.2面向接口编程
根据客户提出的需求,定义接口,业务具体实现是通过实现类来完成。
当客户提出新的需求,只需要编写该业务逻辑新的实现类。
好处
业务逻辑更加清晰
增强代码的扩展性,可维护性
接口和实现相分离,适合团队协作开发
降低耦合度。便于以后升级扩展
举例
假设有一个数据库DAO
突然根据需要,程序要连接两个数据库,一个Oracle,一个Mysql
结构图 -
包名的规范
整体规范
域名倒写.模块名称.组件名称
DAO包规范
1.package com.it666.jdbc.domain
存储所有的domain
2.page com.it666.jdbc.dao
存储所有的dao接口
3.page com.it666.jdbc.dao.impl
存储所有的Dao接口实现类
4.page com.it666.jdbc.dao.test
存储Dao组件的测试类 -
类名规范
domain类
存储在domain包中。用于描述一个对象,是一个javaBean,写时要见名知意
dao接口
存储在dao包中,用于表示某一个对象的CRUD声明
起名规范IDomain名Dao
接口-domain名-dao
dao实现类
存储到dao.impl包中,用于表示DAO接口的实现类,要实现DAO接口
Domain名DAOImpl
domain名-dao-impl
DAO设计规范
- 开发步骤
1.创建表
2.建立domain包和domain类
3.建立dao包和dao接口
4.建立dao.impl包和dao实现类
5.根据dao接口创建dao测试类
6.编写实现类当中dao的声明的方法体
7.每编写一个dao方法,进行测试功能是否正确- 创建包
- 内部结构
- 编写实现类方法体
保存方法
删除方法
修改方法
获取一个学生
获取所有学生
- 创建包
DAO代码重构
-
上面的代码明显很多是重复多余的
-
1.每一个DAO方法当中都会写驱动名称、url、用户名、密码
把公共的这些声明为成员变量
在一个类当中能够共享这些成员变量
解决示例 -
2.每个DAO当中都会相同的4行代码。
抽取到一个公共类JdbcUtil当中
4.3.
每个dao方法每次操作只需要connection对象,至于是怎么样创建的不关心
把创建Connection代码抽取到jdbcUtil当中
并提供一个getConn就能够获得连接对象
5. 4.
每次调用getConn就会创建一个Connection对象,但不需要每次都注册驱动
把加载驱动放到静态代码块当中
只会在类被加载到JVM时,才会执行一次
每个dao方法都要关闭资源
在util当中提供一个方法专门关闭资源
在方法当中传入要关闭哪些资源
DAO方法中,拼接SQL太麻烦
要使用预编译语句对象(下面有写)
-
(待补充)7.DAO方法当中每次都创建一个connection对象,用完就关闭了,创建Connection成本很大
通过数据库连接池来解决 -
(待补充)8.jdbcUtil当中的用户名,密码这些信息都写到了文件当中,不便于维护
给写到一个单独的配置文件当中
预编语句
1. 没有预编译语句时
没有预编译语句,所有的sql都是进行拼接
2.预编译语句
1.PreparedStatement 用于预编译模板SQL语句,在性能和代码灵活性上有显著地提高
2.PreparedStatement 对象使用 ? 作为占位符,即参数标记;
3.使用 setXXX( index,value) 方法将值绑定到参数中
每个参数标记是其顺序位置引用,注意 index 从 1 开始,就是每个?的位置
4.PreparedStatement 对象执行SQL语句(注意,它们都没有参数)
executeQuery()
executeUpdate()
3. 使用预编语句的内部优化
例如这张图片显示的:
使用了预编语句,在预编译池中保留的编译语句就可以直接拿出来用,将里面的?号代替直接使用,这样不用每一句语句都用编译,这样运行的效率大大提升了
但是遗憾的是
支持优化情况
MySql不支持
Oracle支持
但是使用预编语句还有其他好处:更安全
可以防SQL注入
什么是sql注入
就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令
例如用户登录的例子中
按照上面的代码,不知道密码也能登陆用户了,这就是sql注入
4. 为什么PrepareState就能够防注入
之所以PreparedStatement能防止注入,
是因为它把单引号转义了,变成了’,
这样一来,就无法截断SQL语句,进而无法拼接SQL语句 基本上没有办法注入了。
调用存储过程
调用存储过程
1.在数据库当中定义一个存储过程
2.JDBC调用一个参数的存储过程
3.编写输入参数和输出参数的存储过程
4.JDBC调用二个参数的存储过程
Statement接口
Statement接口
Statement接口作用
用于进行Java程序和数据库之间的数据传输
具体类有3个实现
1. Statement 用于对数据库进行通用访问,使用的是静态sql
2. PreparedStatement PreparedStatement 用于预编译模板SQL语句,在运行时接受sql输入参数
3. CallableStatement 要访问数据库存储过程时使用 ,也可以接受运行时输入参数。