JDBC(Java DataBase Connectivity)
Java数据库连接技术,是一套使用java语言编写的API,为多种关系型数据库提供了统一接口。 数据库厂商使用自己数据库的特点来实现接口。程序员调用接口,实际上底层调用数据库厂商实现的部分。
JDBC实际工作过程与相关接口
(1) 加载驱动,建立连接;
驱动管理类型:DriverManager
static Connection getConnection(url,user,password) // 通过地址,数据库用户名,用户密码 获取连接对象
(2) 获取sql语句执行对象
连接接口:Connection
Statement createStatement() // 获取一个SQL语句编译对象
PreparedStatement prepareStatement(String sql) // 获取一个SQL语句预编译对象
(3) 执行SQl语句
SQL语句对象接口
3.1、Statement:用于编译静态SQL语句(编译多次)
boolean execute(String sql) // 用来执行DDL语言
ResultSet executeQuery(String sql) // 用于执行DQL语言
int executeUpdate(String sql) // 用于执行DML语言
void addBatch(String sql) // 添加批处理
int[] executeBatch() // 执行批处理
3.2、PreparedStatement:用于编译静态SQL语句,是Statement的一个子类型,执行效率比Statement要高(只编译一次)
boolean execute() // 用来执行DDL语言
ResultSet executeQuery() // 用来执行DQL语言
int executeUpdate() // 用于执行DML语言
void addBatch() // 添加批处理
int[] executeBatch() // 执行批处理
(4) 处理结果集
结果集接口:ResultSet;在进行DQL操作时, 查询的所有记录信息封装在ResultSet对象中
boolean next(): 询问结果集对象中是否有下一行记录。如果返回true,光标会自动移到下一行。
还提供了一些数据库类型转java数据类型的方法:
int getInt(int columnIndex)/getInt(String columnName)
double getDouble(int columnIndex)/getDouble(String columnName)
String getString(int columnIndex)/getString(String columnName)
Date getDate(int columnIndex)/getDate(String columnName)
...
(5) 关闭连接
详细步骤
0、创建lib文件夹,将jar包拷贝过来并添加到build path
==>
1、在src下创建db.properties配置文件
url=jdbc:mysql://localhost:3306/bd1705
user=root
password=root
driver=com.mysql.jdbc.Driver
2、添加DBUtil类,包含数据库连接与关闭的方法
public class DBUtil {
private static String url="";
private static String user="";
private static String password;
private static String driver;
/**加载静态资源*/
static {
try {
//创建Properties对象,加载db.properties文件内的数据
Properties prop = new Properties();
InputStream is = DBUtil.class.getClassLoader()
.getResourceAsStream("db.properties");
prop.load(is);//加载流内的数据,封装到prop对象内
url = prop.getProperty("url");
user = prop.getProperty("user");
password = prop.getProperty("password");
driver = prop.getProperty("driver");
//加载驱动
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 连接数据库的方法
* @return 连接对象
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
Connection conn = DriverManager.getConnection(url,user,password);
return conn;
}
/**
* 关闭数据库的方法
* @param conn 要关闭的连接对象
*/
public static void closeConnection(Connection conn) {
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
MVC架构思想
M:model;模型层(业务层,持久层),程序与数据库交互的层次
1、通过ORM设计实体类
2、设计一个接口,提供与数据库交互的各个功能
3、编写此接口的实现类,完善功能逻辑
V:View;视图层(用户所能操作与看到的部分)
C:Controller;控制层(控制用户操作与模型层的逻辑走向)
包的设计
util:工具包;DBUtil.java
entity:实体包;Emp.java
ORM(object relation mapping):对象关系映射表中的一条记录可以看成一个对象类中的一个对象也可以当成某表中的一条
记录,可以通过ORM将数据库中emp表根据其八个字段,定义成一个具有八个成员变量的类型:Emp
private Integer empno;
private String ename;
private String job;
private Integer mgr;
private Date hiredate;
private double sal;
private double comm;
private Integer deptno;
//在插入数据时,部门号为空值时,Integer的默认值为null比int的默认值0更合适
dao(Data Access Object):数据访问对象;EmpDao.java
impl:实现包;EmpDaoImpl.java
3、创建实体类Emp
4、编写dao层接口
public interface EmpDao {
public void saveEmp(Emp emp);
public void deleteEmp(Integer empno);
public void updateEmp(Emp emp);
public Emp findById(Integer empno);
public List<Emp> findAll();
public List<Emp> findByPage(int page,int size);
}
5、编写接口实现类
如通过员工id显示员工信息功能:
public Emp findById(Integer empno) {
Emp emp =null;
Connection conn=null;
try {
conn=DBUtil.getConnection();
String sql="select * from emp where empno=?";
PreparedStatement prep=conn.prepareStatement(sql);
prep.setInt(1, empno);
ResultSet rs=prep.executeQuery();
if(rs.next()){
String ename=rs.getString(2);
String job=rs.getString(3);
int mgr=rs.getInt(4);
Date hiredate=rs.getDate(5);
double sal=rs.getDouble(6);
double comm=rs.getDouble(7);
int deptno=rs.getInt(8);
emp=new Emp(empno, ename, job, mgr, hiredate, sal, comm, deptno);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
DBUtil.closeConnection(conn);
}
return emp;
}
public List<Emp> findAll() {
Connection conn=null;
List<Emp> emps=new ArrayList<>();
Emp emp=null;
try {
conn=DBUtil.getConnection();
String sql="select * from emp ";
PreparedStatement prep=conn.prepareStatement(sql);
ResultSet rs=prep.executeQuery();
while(rs.next()){
int empno=rs.getInt(1);
String ename=rs.getString(2);
String job=rs.getString(3);
int mgr=rs.getInt(4);
Date hiredate=rs.getDate(5);
double sal=rs.getDouble(6);
double comm=rs.getDouble(7);
int deptno=rs.getInt(8);
emp=new Emp(empno, ename, job, mgr, hiredate, sal, comm, deptno);
emps.add(emp);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
DBUtil.closeConnection(conn);
}
return emps;
}
6、创建DaoFactory (使用单例模式封装DAO的实现层)
Calendar的实例化:
Calendar now=Calendar.getInstance();
不使用dao工厂模式时,如果本来使用JDBC实现要换成hibernate来实现,于是需要把DAO的JDBC实现开始全部转换成
Hibernate实现,则需要改变表现层的大量EmpDao dao=new EmpDaoImpl()
单例模式:整个项目在运行时,内存中只有某一个类的唯一一个实例。
1)构造器私有化
2)提供一个静态方法获取实现层的对象
3)定义一个静态成员变量,目的要只加载一次
懒汉式:当真正使用对象时,才创建对象
饿汉式: 不管是否使用对象,都提前创建好
public class DaoFactory {
private static EmpDao dao;
//直接给静态成员变量赋值,饿汉
//private static EmpDao dao1=new EmpDaoImpl();
private DaoFactory(){}
//懒汉模式
public synchronized static EmpDao getInstance(){
if(dao==null){
dao=new EmpDaoImpl();
}
return dao;
}
}
7、测试类
导入JUnit4库
@Test
public void testFindAll() {
EmpDao dao = DaoFactory.getInstance();
List<Emp> list = new ArrayList<Emp>();
list = dao.findAll();
for (Emp e : list) {
System.out.println(e.toString());
}
}