JDBC概述
什么是持久化(persistence): 持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用。 保存数据: 内存中: 掉电之后,数据就没了. 磁盘中: 掉电之后,数据依然存在. 大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存到硬盘上加以”固化”,而持久化的实现过程大多通过各种关系数据库来完成。 持久化的主要应用是将内存中的数据存储在关系型数据库中,当然也可以存储在磁盘文件、XML数据文件中。 JPA:JavaEE的规范,Java persistence api: Java的持久化API. Hibernate实现了该规范.(xml/注解)
在Java中,数据库存取技术只能通过JDBC访问数据库: JDBC访问数据库的形式主要有两种: 1).直接使用JDBC的API去访问数据库服务器(MySQL/Oracle). 2).间接地使用JDBC的API去访问数据库服务器. 第三方O/R Mapping工具,如Hibernate, MyBatis等.(底层依然是JDBC) JDBC是java访问数据库的基石,其他技术都是对jdbc的封装.
代码语言:javascript复制JDBC(Java DataBase Connectivity):
是一种用于执行SQL语句的Java API(接口,类,方法),可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序.
JDBC为访问不同的数据库提供了一种统一的途径,为开发者屏蔽了一些细节问题。
JDBC的目标是使Java程序员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统,这样就使得程序员无需对特定的数据库系统的特点有过多的了解,从而大大简化和加快了开发过程。
总结: JDBC本身是java连接数据库的一个标准,是进行数据库连接的抽象层,由java编写的一组类和接口组成,接口的实现由各个数据库厂商来完成.
--------------------------------------------------------------------------------
JDBC的版本:
JDBC隶属于JavaSE的范畴,伴随着JavaSE的版本升级.
Java6开始:JDBC4.0: (了解),JDBC4.0有一个新特性-无需加载注册驱动.
Java7开始:JDBC4.1:
---------------------------------------------------------------
JDBC的API在哪里?
----->JDK的API中.
java.sql包装的就是JDBC的API.
各大数据库厂商就会对JDBC的API提供实现类.--->驱动包
注意: 在我们使用Java代码来操作JDBC的时候.
1:我们运用到的API(接口)全部来自于java.sql包,绝对不能出现来自于驱动包中.
2):使用到的全部是接口.
千万不要引入com.mysql..Xxx类.
操作JDBC的准备:
1.拷贝MySQL的驱动包到项目中去:mysql-connector-java-5.1.x-bin.jar 2.build path,告诉项目去哪里去找字节码文件.
操作JDBC的第一步,获取JDBC的连接对象:Connection. 步骤1: 加载注册驱动. Class.forName(“com.mysql.jdbc.Driver”); 为什么说这行代码就在完成加载注册驱动的操作. 1):把com.mysql.jdbc.Driver这份字节码文件加载进JVM. 2):把字节码加载进JVM之后,就会立刻执行该类的静态代码块. 步骤2: 获取连接对象,通过DriverManager的静态方法(getConnection). Connection conn = DriverManager.getConnection (String url,String username,String password); 参数: url : jdbc:mysql://数据库服务器安装电脑的主机IP:端口/哪一个数据库名称 连接本机: jdbc:mysql://localhost:3306/jdbcdemo 如果连接的数据库服务器在本机,并且端口是3306,则可以简写: jdbc:mysql:///jdbcdemo username: 所连接数据库服务器的用户账号(root) password: 所连接数据库服务器的用户密码(admin) 验证已经获取连接:可以在MySQL控制台,使用命令:show processlist; 查看MySQL运行进程.
从Java6(JDBC4.0)开始,可以不再加载注册驱动,直接通过DriverManager获取连接对象.
为啥不再需要加载注册驱动了? 从Java6开始,规范要求每一个JDBC驱动的包,都必须带有META-INF/services/java.sql.Driver文件.
开发建议:依然还是建议手动的加载注册驱动. 如此,可以兼容之前的JDK版本,在JavaWeb中必须手动加载.
JDBC相关的API
操作JDBC的步骤:
1):加载注册驱动. 2):获取连接对象. 3):创建/获取语句对象 4):执行SQL语句 5):释放资源
代码语言:javascript复制Connection接口的常用方法:
Statement createStatement() 创建一个 Statement 对象来将 SQL 语句发送到数据库。
PreparedStatement prepareStatement(String sql) :获取预编译语句对象.
参数:sql,并不是一个静态SQL,而是带有占位符的SQL(?).
void close():关闭连接对象
代码语言:javascript复制Statement接口的常用方法:
用于执行静态 SQL (写死的SQL,可以执行运行的SQL)语句并返回它所生成结果的对象。
int executeUpdate(String sql):可以执行DML(增删改)和DDL语句,如果是执行DDL什么都不返回,执行DML返回受影响的行数.
ResultSet executeQuery(String sql) :执行给定的 DQL语句,该语句执行之后返回一个 ResultSet 对象。
void close():关闭语句对象
代码语言:javascript复制PreparedStatement接口的常用方法:
是Statement的子接口,表示预编译的 SQL 语句的对象.
设置占位符参数(告诉SQL中的?到底表示哪一个值):
void setXxx(int parameterIndex, Xxx value): xxx表示数据类型,比如:String,int,Long等.
parameterIndex:设置第几个占位符?(从1开始).
value:需要设置的参数值.
int executeUpdate():可以执行DML(增删改)和DDL语句,如果是执行DDL什么都不返回,执行DML返回受影响的行数.
ResultSet executeQuery() :执行给定的 DQL语句,该语句执行之后返回一个 ResultSet 对象。
注意:此时不需要传递SQL参数.
void close():关闭语句对象
代码语言:javascript复制ResultSet接口的常用方法:
表示数据库结果集的数据表,通常通过执行查询数据库的语句生成.
ResultSet 对象具有指向其当前数据行的光标。最初,光标被置于第一行之前。next 方法将光标移动到下一行;因为该方法在 ResultSet 对象没有下一行时返回 false,所以可以在 while 循环中使用它来迭代结果集。(类似迭代器操作)
-------------------------------------------------------------------------------------
boolean next(): 先判断光标是否能向下移动,如果可以,则往下移动.
xxx:表示数据类型,比如:int,long,String等,根据当前列的数据类型来选择.
xxx getXxx(int columnIndex) : 获取当前光标行的第N列的数据,从1开始计算.
xxx getXxx(String columnName) :获取当前光标行的指定列名的列的数据,推荐.
void close():关闭结果集对象
创建表和异常处理
创建一张t_student表:id/name/age: SQL: CREATE TABLE t_student(id BIGINT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(20),age INT);
异常处理和关闭资源:
DML操作
在t_student表中,插入,修改和删除学生信息. 此时的操作模板和上述DDL一模一样,仅仅只是SQL语句不一样.
DQL操作
DAO思想
为什么得需要DAO?也就是说DAO出现之后需要解决什么问题? 解决数据库操作的代码重复.
代码重复不影响对与错,但是影响维护成本,因为如果需要修改代码就得修改N个地方. 所以在开放中,我们应该要遵循DRY原则.
操作数组 : 是把数据存储在内存中. 操作数据库:是把数据存储在数据库文件中(硬盘).
需求:我现在需要定义一个数据来存储数据. 在封装ArrayList之前,每一个客户端往数组中保存数据,都得去检查容量和扩容操作,如此就重复了. 解决方案:把数组的相关操作封装到ArrayList类中,把容量检查和扩容存储在add方法中,此后,客户端就只管直接调用方法即可,不在关系繁琐的重复操作了.
什么是DAO:主要就包括CRUD(增删改查操作). DAO(Data Access Object)是一个数据访问接口,数据访问:顾名思义就是与数据库打交道。夹在业务逻辑与数据库资源中间。
在核心J2EE模式中是这样介绍DAO模式的:为了建立一个健壮的J2EE应用,应该将所有对数据源的访问操作抽象封装在一个公共API中。 用程序设计的语言来说,就是建立一个接口,接口中定义了此应用程序中将会用到的所有事务方法。 在这个应用程序中,当需要和数据源进行交互的时候则使用这个接口,并且编写一个单独的类来实现这个接口在逻辑上对应这个特定的数据存储。
代码语言:javascript复制作图的DAO设计的示意图中,分析:
首先:以及解决了客户端功能代码重复问题.
-------------------------------------------------------------------
提出新的问题: 设计save和get方法.
void save(String name,Integer age);
问题:如果需要保存的学生有多个信息,此时参数就有N多.
设计方法时,参数最好不要超过5,6个.
问题如何解决?
String get(Long id):根据学生的主键来查询学生信息
此时因为需要返回学生的多个信息,此时的返回类型设计是不合理的.
问题如何解决?
解决方案:使用封装思想,把学生的多个信息封装成一个对象.
保存操作:
void save(Student stu);
查询操作:
Student get(Long id)
DAO设计
代码语言:javascript复制DAO的设计规范:
DAO组件包含DAO接口和DAO实现类以及DAO的测试类:
分包规范:
package 域名倒写.模块名称.组件名;
com.it.smis.domain; 存储的domain文件
com.it.smis.dao; 存储dao接口文件
com.it.smis.dao.impl; 存储dao实现类文件
com.it.smis.test; 临时存储测试类
起名规范:
domain类 : 描述对象的,一把使用英文单词来表示:Xxx,比如:Employee.
DAO接 口: IXxxDAO/IXxxDao, 如:IEmployeeDAO/IEmployeeDao.
DAO实现类: XxxDAOImpl/XxxDaoImpl, 如:EmployeeDAOImpl,EmployeeDaoImpl. 注意:实现类一定要实现DAO接口.
DAO测试类: 根据DAO接口生成测试类, XxxDAOTest/XxxDaoTest,如:EmployeeDAOTest,EmplyeeDaoTest.
创建DAO对象规范:
1):DAO对象起名,统统叫做xxxDAO.
2):面向接口编程,把DAO对象赋给DAO接口类型.
IEmployeeDAO employeeDAO= new EmployeeDAOImpl();
DAO操作步骤: 1:先创建一张表. 2:根据表的结构,创建domain对象. 3):创建DAO接口,并提供DAO方法(CRUD). 4):创建DAO实现类,覆盖接口中的方法,但是暂时不实现. 5):根据DAO接口生成DAO测试类. 6):完成DAO实现类中的方法,并测试通过. 7):思考和总结.