JDBC03----DAO思想
Posted Hermioner
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDBC03----DAO思想相关的知识,希望对你有一定的参考价值。
一. 什么是DAO
在没有使用DAO时,会存在以下问题:
多个地方都要同时CRUD操作时,重复的代码就会很多。比如多个人你都会操作各自的test的时候:
1. 什么是DAO
DAO(Data Access Object):数据存取对象。它位于业务逻辑和持久数据之间,实现对持久化数据的访问。
比如下图中:test1可以认为是业务层,而DB可以认为是持久层,DAO就是这两者之间抽象出来的一层。Test1只需要告诉DAO想干什么,DAO就会帮助取访问DB来实现操作。
不会直接操作DB,而是通过DAO来帮助操作DB了。
二. ORM对象映射关系
1. 什么是ORM
ORM(Object Relational Mapping):对象关系映射。将关系数据库中表中的记录映射为对象,以对象的形式展现。因此,ORM的目的是为了方便开发人员以面向对象的思想来实现对数据库的操作。
2. 对应关系
类-----> 表
对象----->记录(行)
属性------>字段(列)
比如stu表中的id,name,age,可以对应成:
public class Stu { Integer id; String name; Integer age; }
三. Domain
1. 什么是domain
它其实就是一个类,它符合JavaBean规范。一个类当中有字段和字段的getter与setter方法。(mynote:可以理解成在orm的基础上添加了getter和setter方法)
2. 作用
用户和数据库交互的核心中转站。
比如:
string name=resultSet.getString("name");
System.out.println(name);
说明:上面的name是取出数据后存放的变量,但是我们并不是要打印在控制台,我们希望展现在我网页上,因此就需要将取出的数据存放在domain里面。
3. 举例
1 public class Stu { 2 Integer id; 3 String name; 4 Integer age; 5 public Integer getId() { 6 return id; 7 } 8 public void setId(Integer id) { 9 this.id = id; 10 } 11 public String getName() { 12 return name; 13 } 14 public void setName(String name) { 15 this.name = name; 16 } 17 public Integer getAge() { 18 return age; 19 } 20 public void setAge(Integer age) { 21 this.age = age; 22 } 23 24 }
上面就是一个domain类。
四. DAO的使用
1. DAO的命名规范
(1)包命名规范
(2)类名规范
2. DAO开发步骤
- 创建表
- 建立domain包和domain类
- 建立dao包和dao接口
- 建立dao.impl包和dao实现类
- 根据dao接口创建dao测试类
- 编写实现类当中dao的声明的方法体
- 每编写一个dao方法,进行测试功能是否正确
3. 举例-----DML操作
准备一张表:
(1)新建立一个包com.test.jdbctest.domain,并在该包下新建立一个domain类stu.java
1 package com.test.jdbctest.domain; 2 3 public class Stu { 4 private Integer id; 5 private String name; 6 private Integer age; 7 public Integer getId() { 8 return id; 9 } 10 public void setId(Integer id) { 11 this.id = id; 12 } 13 public String getName() { 14 return name; 15 } 16 public void setName(String name) { 17 this.name = name; 18 } 19 public Integer getAge() { 20 return age; 21 } 22 public void setAge(Integer age) { 23 this.age = age; 24 } 25 26 }
(2)新建立一个包com.test.jdbctest.dao,并在该包下新建立一个DAO接口IStu.java
1 package com.test.jdbctest.dao; 2 3 import com.test.jdbctest.domain.Stu; 4 5 public interface IStuDao { 6 void save(Stu student); 7 }
(3)新建立一个包com.test.jdbctest.dao.impl,并在该包下新建立一个DAO接口的实现类StuDaoImpl.java
package com.test.jdbctest.dao.impl; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import com.test.jdbctest.dao.IStuDao; import com.test.jdbctest.domain.Stu; public class StuDaoImpl implements IStuDao{ public void save(Stu student) { String url="jdbc:mysql://localhost:3306/test"; String user="Hermioner"; String password="1234"; Connection connection=null; Statement statement=null; try { Class.forName("com.mysql.jdbc.Driver"); connection=DriverManager.getConnection(url, user, password); statement=connection.createStatement();
//SQL语句拼接 String sql="insert into stu(name,age) values (\'"+student.getName()+"\',\'"+student.getAge()+"\')"; statement.executeUpdate(sql); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { if(statement!=null) { try { statement.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(connection!=null) { try { connection.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
(4)新建立一个包com.test.jdbctest.dao.test,并在该报下新建立一个测试类StuDaoTest.java
package com.test.jdbctest.dao.test; import org.junit.Test; import com.test.jdbctest.dao.IStuDao; import com.test.jdbctest.dao.impl.StuDaoImpl; import com.test.jdbctest.domain.Stu; public class StuDaoTest { @Test public void testSave() { //1.创建一个学生 Stu student=new Stu(); student.setName("zhaosi"); student.setAge(22); //2.把学生保存到数据库中 IStuDao dao=new StuDaoImpl(); dao.save(student);//传入的是对象 } }
运行完以后,表中就会多一条数据(前提id是主键自增的)
note:如果上面不做sql语句拼接的话,那么会插入如下数据:
note: 上面的save方法,不适用dao的话就会在save方法中传入很多的参数,如果使用的话,只需要传入student对象。
4. 举例----DQL操作(get一个,getAll)
释放顺序:先释放结果集、然后statement,然后connection.
(1)修改DAO接口
1 package com.test.jdbctest.dao; 2 3 import java.util.List; 4 import com.test.jdbctest.domain.Stu; 5 6 public interface IStuDao { 7 //获取指定学生 8 Stu get(int id); 9 //获取所有的学生 10 List<Stu> getAll(); 11 }
(2)修改DAO实现
1 package com.test.jdbctest.dao.impl; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.ResultSet; 6 import java.sql.SQLException; 7 import java.sql.Statement; 8 import java.util.ArrayList; 9 import java.util.List; 10 11 import com.test.jdbctest.dao.IStuDao; 12 import com.test.jdbctest.domain.Stu; 13 14 public class StuDaoImpl implements IStuDao{ 15 public Stu get(int id) { 16 String url="jdbc:mysql://localhost:3306/test"; 17 String user="Hermioner"; 18 String password="1234"; 19 Connection connection=null; 20 Statement statement=null; 21 ResultSet resultSet=null; 22 try { 23 Class.forName("com.mysql.jdbc.Driver"); 24 connection=DriverManager.getConnection(url, user, password); 25 statement=connection.createStatement(); 26 String sql="select *from stu where id="+id+""; 27 resultSet=statement.executeQuery(sql); 28 if(resultSet.next()) { 29 Stu student=new Stu(); 30 student.setName(resultSet.getString("name")); 31 student.setAge(resultSet.getInt("age")); 32 student.setId(resultSet.getInt("id")); 33 return student; 34 } 35 } catch (Exception e) { 36 // TODO Auto-generated catch block 37 e.printStackTrace(); 38 }finally { 39 if(resultSet!=null) { 40 try { 41 resultSet.close(); 42 } catch (SQLException e) { 43 // TODO Auto-generated catch block 44 e.printStackTrace(); 45 } 46 } 47 if(statement!=null) { 48 try { 49 statement.close(); 50 } catch (SQLException e) { 51 // TODO Auto-generated catch block 52 e.printStackTrace(); 53 } 54 } 55 if(connection!=null) { 56 try { 57 connection.close(); 58 } catch (SQLException e) { 59 // TODO Auto-generated catch block 60 e.printStackTrace(); 61 } 62 } 63 } 64 return null; 65 } 66 67 public List<Stu> getAll() { 68 String url="jdbc:mysql://localhost:3306/test"; 69 String user="Hermioner"; 70 String password="1234"; 71 Connection connection=null; 72 Statement statement=null; 73 ResultSet resultSet=null; 74 List<Stu> list=new ArrayList<Stu>(); 75 try { 76 Class.forName("com.mysql.jdbc.Driver"); 77 connection=DriverManager.getConnection(url, user, password); 78 statement=connection.createStatement(); 79 String sql="select *from stu"; 80 resultSet=statement.executeQuery(sql); 81 while(resultSet.next()) { 82 Stu student=new Stu(); 83 student.setName(resultSet.getString("name")); 84 student.setAge(resultSet.getInt("age")); 85 student.setId(resultSet.getInt("id")); 86 list.add(student); 87 } 88 return list; 89 } catch (Exception e) { 90 // TODO Auto-generated catch block 91 e.printStackTrace(); 92 }finally { 93 if(resultSet!=null) { 94 try { 95 resultSet.close(); 96 } catch (SQLException e) { 97 // TODO Auto-generated catch block 98 e.printStackTrace(); 99 } 100 } 101 if(statement!=null) { 102 try { 103 statement.close(); 104 } catch (SQLException e) { 105 // TODO Auto-generated catch block 106 e.printStackTrace(); 107 } 108 } 109 if(connection!=null) { 110 try { 111 connection.close(); 112 } catch (SQLException e) { 113 // TODO Auto-generated catch block 114 e.printStackTrace(); 115 } 116 } 117 } 118 return null; 119 } 120 121 122 }
(3)修改DAO测试
1 package com.test.jdbctest.dao.test; 2 3 import java.util.List; 4 5 import org.junit.Test; 6 7 import com.test.jdbctest.dao.IStuDao; 8 import com.test.jdbctest.dao.impl.StuDaoImpl; 9 import com.test.jdbctest.domain.Stu; 10 11 public class StuDaoTest { 12 13 @Test 14 public void testGet() { 15 IStuDao dao=new StuDaoImpl(); 16 Stu student=dao.get(2); 17 System.out.println(student); 18 System.out.println(student.getName()); 19 } 20 21 @Test 22 public void testGetAll() { 23 IStuDao dao=new StuDaoImpl(); 24 List<Stu> list=dao.getAll(); 25 for(int i=0;i<list.size();i++) { 26 System.out.println(list.get(i).getName()); 27 } 28 } 29 30 }
1 com.test.jdbctest.domain.Stu@9629756 2 lisi 3 4 5 zhangsan 6 lisi 7 wangwu 8 zhaosi
好了,DAO的基本使用差不多了解了。但是会发现每多一个操作,就会有大量的重复代码,因此需要进行重构。
五. 代码重构
根据之前的编码情况,可以发现有以下可以进行重构
1. 重构用户名密码
新建立一个类JDBCUtil.java
1 package com.test.jdbctest.util; 2 3 public class JDBCUtil { 4 public static String url="jdbc:mysql://localhost:3306/test"; 5 public static String user="Hermioner"; 6 public static String password="Hermioner"; 7 public static String driverName="com.mysql.jdbc.Driver"; 8 9 }
这样对应的实现来调用这个工具类就好了。
2. DAO封装连接对象
1 package com.test.jdbctest.util; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.SQLException; 6 7 public class JDBCUtil { 8 public static String url="jdbc:mysql://localhost:3306/test"; 9 public static String user="Hermioner"; 10 public static String password="Hermioner"; 11 public static String driverName="com.mysql.jdbc.Driver"; 12 13 static { 14 try { 15 Class.forName(driverName); 16 } catch (ClassNotFoundException e) { 17 // TODO Auto-generated catch block 18 e.printStackTrace(); 19 } 20 } 21 22 /** 23 * 获取Connection对象 24 */ 25 public static Connection getConnection() { 26 try { 27 return DriverManager.getConnection(url, user, password); 28 } catch (SQLException e) { 29 // TODO Auto-generated catch block 30 e.printStackTrace(); 31 } 32 return null; 33 } 34 }
这样,驱动只需要加载一次,就可以使用静态代码块来实现驱动的加载。
note: 一定要静态代码块放在四个成员变量的后面,否则这些变量没有初始化保证。当类被加载时,静态代码块只执行一次。
3. DAO封装关闭资源
JDBUtil.java中添加如下方法:
1 public static void close(Connection connection,Statement statement,ResultSet resultSet) { 2 if(resultSet!=null) { 3 try { 4 resultSet.close(); 5 } catch (SQLException e) { 6 // TODO Auto-generated catch block 7 e.printStackTrace(); 8 } 9 } 10 if(statement!=null) { 11 try { 12 statement.close(); 13 } catch (SQLException e) { 14 // TODO Auto-generated catch block 15 e.printStackTrace(); 16 } 17 } 18 if(connection!=null) { 19 try { 20 connection.close(); 21 } catch (SQLException e) { 22 // TODO Auto-generated catch block 23 e.printStackTrace(); 24 } 25 } 26 }
参考文献
https://ke.qq.com/course/339214
以上是关于JDBC03----DAO思想的主要内容,如果未能解决你的问题,请参考以下文章
关于mysql驱动版本报错解决,Cause: com.mysql.jdbc.exceptions.jdbc4Unknown system variable ‘query_cache_size(代码片段