day05-DAO设计&JDBC基础
2020-03-25 本文已影响0人
建国同学
一、JDBC
1.什么是持久化
持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用。
- 内存中的数据 > 硬盘上加以”固化”
- 实现过程大多通过各种关系数据库(mysql)来完成,也可以存储在磁盘文件、XML数据文件中
2.JDBC作用:
- 在Java中,数据库存取技术只能通过JDBC访问数据库:
JDBC访问数据库的形式主要有两种:
1)直接使用JDBC的API去访问
2).间接地使用JDBC的API去访问数据库服务器:Hibernate, MyBatis等.(底层依然是JDBC)
JDBC.png
3.JDBC(Java DataBase Connectivity):
- 用于执行SQL语句的Java API
- Java6开始:JDBC4.0: (了解),JDBC4.0有一个新特性-无需加载注册驱动.
Java7开始:JDBC4.1: - java.sql包装的就是JDBC的API
- 使用哪个厂商的数据库就导入其驱动jar包
- 代码中使用到的全部都是java.sql的包
- 面向接口编程:
JDBC的接口 变量 = new MySQL的实现();
new Oracle的实现();
二、获取数据库连接
1.准备环境:
- 导入驱动jar包到lib文件夹
- 选择jar,[buil path],把jar添加到classpath路径.
2.获取JDBC连接对象/Connection对象.
- 操作步骤(贾琏):
/**
*
* 获取JDBC连接对象/Connection对象
*/
@Test
public void testGetConnection() throws Exception {
// 1.加载驱动(注册驱动)告诉程序,使用的数据库是mysql
Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接对象jdbc:mysql://localhost:3306/jdbcdemo
// jdbc[固定写法]mysql[是协议]//localhost:3306[表示连接的哪一台服务器上面的端口为3306的(程序)sql服务器]
// jdbcdemo表示要连接的mysql服务器上面的数据库
Connection connection = DriverManager.getConnection(
// 如果连接的是本机上的数据库,并且端口号为3306 可以省略不写
"jdbc:mysql://localhost:3306/javaweb" // url地址 省略:///javaweb"
, "root" // 账号root
, "admin");// 密码password
System.out.println(connection);
}
forName加载的驱动.png
三、JDBC常用的API
-
操作JDBC的步骤口诀:
-->贾琏欲执事:
1:加载注册驱动.
2:获取连接对象.
3:创建/获取语句对象.
4:执行SQL语句.
5:释放资源. -
常用的API
1.Statement接口:
执行静态SQL语句并返回它所生成结果.
常用方法:
int executeUpdate(String sql):执行DDL/DML语句.
若当前SQL是DDL语句,则返回0.
若当前SQL是DML语句,则返回受影响的行数.
ResultSet executeQuery(String sql):执行DQL语句,返回结果集.
close():释放资源
------------------------------------------
2.Connection接口:
表示JDBC的连接对象.
常用方法:
Statement createStatement():创建一个静态的语句对象.
PreparedStatement prepareStatement(String sql):创建一个预编译语句对象.
此时参数sql:表示带有占位符(?)的SQL语句的模板.
close():释放资源
------------------------------------------
3.PreparedStatement接口:
是Statemen接口的子接口-->享有Statement中的方法.
表示预编译的 SQL 语句的对象
常用方法:
void setXxx(int parameterIndex,Xxx value):设置第几个占位符的真正参数值.
int executeUpdate():执行DDL/DML语句. 注意:没有参数
若当前SQL是DDL语句,则返回0.
若当前SQL是DML语句,则返回受影响的行数.
ResultSet executeQuery():执行DQL语句,返回结果集.
close():释放资源
Xxx表示数据类型,比如String,int,long,Date等.
------------------------------------------
4.ResultSet接口:
通过执行DQL语句查询之后的结果对象.
封装了查询之后的所有数据.
ResultSet 对象具有指向其当前数据行的光标。最初,光标被置于第一行之前。next 方法将光标移动到下一行;因为该方法在 ResultSet 对象没有下一行时返回 false,所以可以在 while 循环中使用它来迭代结果集
常用方法:
boolean next():判断当前光标是否能向下移动,如果能向下移动返回true,并同时将光标移动到下一行.
Xxx getXxx(int columnIndex):取出当前光标所在行的第columnIndex列的数据(columnIndex从1开始算).
Xxx getXxx(String columnName):取出当前光标所在行的列名为columnName列的数据,columnName可以是别名.
Xxx表示数据类型,比如String,int,long,Date等. 推荐使用列名来取数据.
close():释放资源
四、创建表和异常处理
/**
*
* 创建表
*/
@Test
public void testDDL() throws Exception {
// 0.准备sql语句
Connection connection = null;
Statement statement = null;
try {
String sql = " CREATE TABLE `t_student` (`id` bigint(20) PRIMARY KEY AUTO_INCREMENT,`name` varchar(20),`age` int(11))";
// 1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接
connection = DriverManager.getConnection("jdbc:mysql:///javaweb", "root", "admin");
// 3.创建statement对象用来发送sql到mysql服务器
statement = connection.createStatement();
// 4.执行sql
statement.executeUpdate(sql);
} catch (Exception e) {
e.printStackTrace();
} finally {
// 5.释放资源
try {
statement.close();
connection.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
五、DAO思想和实现
1.DAO思想:
-
DAO(Data Access Object)是一个数据访问接口,数据访问:顾名思义就是与数据库打交道。
夹在业务逻辑与数据库资源中间。 -
为了解决功能重复问题.
-
----->编写一个数组的工具类:ArrayList.
把所有和数组相关的CRUD操作封装在ArrayList类中.
以后,客户端需要什么功能,就只需要创建ArrayList对象,并调用相应的方法即可(如下图).
DAO思想
2.DAO的规范
-
域名倒写.项目模块名.组件;
-
DAO 对象的名字:xxxDAO
-
DAO 接口: IXxxDAO : :仅仅是表示对Employee对象的CRUD的封装
-
DAO 实现类: XxxDAOImpl :仅仅表示IEmployeeDAO的实现
-
DAO测试类: XxxDAOTest :表名就是XxxDAO组件的测试类,应该测试DAO组件中的所有方法.
-
面向接口编程:IEmployeeDAO dao = new EmployeeDAOImpl();
3.DAO实现
-DML:PreparedStatement 类的 executeUpdate()方法 执行sql
-DQL:PreparedStatement 类的 executeQuery()方法 执行sql
- 1):先建立模型对象:domain
package cn.wolfcode.sims.domain;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Setter @Getter @ToString
public class Student {
private Long id;
private String name;
private int age;
}
- 2):编写DAO接口.
package cn.wolfcode.sims.dao;
import java.util.List;
import cn.wolfcode.sims.domain.Student;
public interface IStudentDAO {
/**
* 插入学生信息
* @param stu 学生信息
*/
void insert(Student stu);
/**
* 根据ID 删除学生信息
* @param id 学生的id
*/
void deleteById(Long id);
/**
* 根据ID 修改学生的信息
* @param id , stu 要修改的内容和要修改的条件
*/
void updateById(Student stu);
/**
* 根据id 修改学生信息
* @param id 学生的id
* @return 学生的信息
*/
Student selectById(Long id);
/**
* 查询所有学生信息
* @return 返回所有学生对象的结果集
*/
List<Student> listAll();
}
- 3):定义DAO实现类.
- 4):生产DAO测试类.
- 5):实现DAO实现类.
package cn.wolfcode.sims.dao.impl;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import cn.wolfcode.sims.dao.IStudentDAO;
import cn.wolfcode.sims.domain.Student;
/**
* DAO的实现
*
*/
public class StudentDAOImpl implements IStudentDAO {
/**
* 插入
*/
@Override
public void insert(Student stu) {
String sql = "insert into t_student(name,age) value(?,?)";
Connection connection = null;
PreparedStatement ps = null;
try {
// 1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接对象
connection = DriverManager.getConnection("jdbc:mysql:///javaweb?characterEncoding=utf-8", "root", "admin");
// 3.获取预编译语句对象
ps = connection.prepareStatement(sql);
// 3.5 设置参数
ps.setString(1, stu.getName());;
ps.setInt(2, stu.getAge());;
// 4.执行sql 这里一定注意不传参数
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 5.释放资源
try {
ps.close();
} catch (Exception e2) {
e2.printStackTrace();
}
try {
connection.close();
} catch (Exception e3) {
e3.printStackTrace();
}
}
}
/**
* 删除
*/
@Override
public void deleteById(Long id) {
String sql = "delete from t_student where id = ? ";
......
// 3.5设置参数
ps.setLong(1, id);
/**
* 更新
*/
@Override
public void updateById(Student stu) {
String sql = "update t_student set name = ? , age = ? where id = ? ";
.....
// 3.5设置参数
ps.setString(1, stu.getName());
ps.setInt(2, stu.getAge());
ps.setLong(3, stu.getId());
/**
* 查询单个
*/
@Override
public Student selectById(Long id) {
String sql = "select id,name,age from t_student where id = ?";
ResultSet rs= null;
.....
// 4.设置参数
ps.setLong(1, id);
// 5.执行sql
rs = ps.executeQuery();
if (rs.next()) {
Student student = new Student();
// 把resultSet中内容封装到对象中
student.setId(rs.getLong("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));
return student;
}
......
rs.close();
-
/**
* 查询所有
*/
@Override
public List<Student> listAll() {
String sql = "select * from t_student ";
ResultSet rs= null;
// 创建list对象
List<Student> list = new ArrayList();
......
// 4.执行sql
rs = ps.executeQuery();
while (rs.next()) {
// 查出一条创建一个对象
Student student = new Student();
// 把resultSet中内容封装到对象中
student.setId(rs.getLong("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));
// 把对象装到list中
list.add(student);
}
......
rs.close();
- 6):在DAO测试类中测试DAO方法.
package cn.wolfcode.sims.test;
import static org.junit.Assert.*;
import java.util.List;
import org.junit.Test;
import cn.wolfcode.sims.dao.IStudentDAO;
import cn.wolfcode.sims.dao.impl.StudentDAOImpl;
import cn.wolfcode.sims.domain.Student;
public class StudentDAOTest {
// 定义一个父类接口类型的变量实现多态
private IStudentDAO studentDAO = new StudentDAOImpl();
@Test
public void testInsert() {
Student stu = new Student();
stu.setName("老油条");
stu.setAge(88);
studentDAO.insert(stu);
}
@Test
public void testDeleteById() {
studentDAO.deleteById(4L);
}
@Test
public void testUpdateById() {
Student stu = new Student();
stu.setId(3L);
stu.setName("小油条");
stu.setAge(8);
studentDAO.updateById(stu);
}
@Test
public void testSelectById() {
Student stu = studentDAO.selectById(1L);
System.out.println(stu);
}
@Test
public void testListAll() {
List<Student> list = studentDAO.listAll();
for (Student student : list) {
System.out.println(student);
}
// studentDAO.listA1l() .stream().forEach(System.out::println);
}
}
六、重构设计
1.添加工具类
2.创建配置文件储存信息
重构设计项目结构 配置文件储存信息.png- 工具类
package cn.wolfcode.sims.until;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
public class DBUtil {
private DBUtil() {
super();
}
private static Properties properteis = new Properties();
static {
try {
// 1.读取properteis配置文件
InputStream inputStream = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("db.properties");
// 2.Properties 工具类帮我们获取流中的数据
properteis.load(inputStream);
// 3.加载驱动
Class.forName(properteis.getProperty("dirverClassName"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 获取连接对象方法
public static Connection getConn() {
try {
return DriverManager.getConnection(properteis.getProperty("url"), properteis.getProperty("name"),
properteis.getProperty("password"));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 释放Connection,PreparedStatement,ResultSet资源
public static void release(Connection connection, PreparedStatement ps, ResultSet rs) {
try {
if (rs != null) {
connection.close();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (rs != null) {
ps.close();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (rs != null) {
rs.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 释放Connection,PreparedStatement资源
public static void release(Connection connection, PreparedStatement ps) {
release(connection, ps, null);
}
}