通用Dao封装
第一型封装:
1.封装主要方法
创建一个BaseDao类,包括insert,update,delete,select方法
public class BaseDao { //每个方法要使用的变量,定义在属性中 private String url = "jdbc:mysql://127.0.0.1:3306/test2108?characterEncoding=utf8"; private String user = "root"; private String password = "root"; private static Connection conn; private PreparedStatement stmt; private ResultSet rs; private ResultSetMetaData rsmd; //加载驱动只执行一次 static { try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //所有表的通用增删改查方法 /** * 向表中插入数据,使用预编译方式插入数据 ,数据库的连接不能共享的,每次调用方法都要创建一个新的连接 * @param sql 要执行的insert的SQL语句 * @param values 预编译参数值的数组,数组中值的顺序和SQL语句中?的顺序相同 * @return 受影响的行数 */ public int insert(String sql,Object[] values) { int result = 0; //步骤 还是JDBC的编写步骤 try { getConnection(); stmt = conn.prepareStatement(sql); for(int i = 0;i<values.length;i++) { stmt.setObject(i+1, values[i]); } result = stmt.executeUpdate(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if(conn!=null) { try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } return result; } /** * 更新表中的数据,使用预编译方式 * @param sql update语句 * @param values 预编译参数值数组 * @return 受影响的行号 */ public int update(String sql,Object[] values) { return insert(sql,values); } public int delete(String sql,Object[] values) { return insert(sql,values); } /** * 按条件查询 * @param sql * @param values * @return 返回结果是一个数组,问题是查询的字段如果太多,要按顺序对应查找 */ public List<Map> select(String sql,Object[] values) { List<Map> list = new ArrayList<Map>(); getConnection(); try { stmt = conn.prepareStatement(sql); for(int i = 0;i<values.length;i++) { stmt.setObject(i+1, values[i]); } rs = stmt.executeQuery(); rsmd = rs.getMetaData(); //1. 先获得结果集列的数量 int columnCount = rsmd.getColumnCount(); //rs结果集中的数据 存储到 List<Map> 结构的集合中 while(rs.next()) { Map<String,Object> map = new HashMap<String,Object>(); for(int i = 0;i<columnCount;i++) { //获得结果集中所有的列名 String columnName = rsmd.getColumnLabel(i+1); map.put(columnName, rs.getObject(columnName)); } list.add(map); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if(conn!=null) { try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } return list; } /** * 按id查询 * @param sql * @param id * @return */ public Map selectById(String sql,Object id) { Map map = new HashMap(); getConnection(); try { stmt = conn.prepareStatement(sql); stmt.setObject(1, id); rs = stmt.executeQuery(); rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); if(rs.next()) { for(int i = 0;i<columnCount;i++) { map.put(rsmd.getColumnLabel(i+1), rs.getObject(rsmd.getColumnLabel(i+1))); } } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if(conn!=null) { try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } return map; } public Connection getConnection() { try { conn = DriverManager.getConnection(url,user,password); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return conn; } public static void main(String[] args) { BaseDao dao = new BaseDao(); /* String sql = "insert into employee(first_name,job_id,salary) values(?,?,?)"; Object[] values = new Object[] {"test01","testjob","11111"}; dao.insert(sql, values); */ /* String sql = "update employee set first_name=?,department_id=? where employee_id=?"; Object[] values = new Object[] {"test02",5001,125}; dao.update(sql, values); */ /* String sql = "delete from employee where employee_id = ?"; Object[] values = new Object[] {125}; dao.delete(sql, values); */ /* String sql = "delete from employee where employee_id in (?,?)"; Object[] values = new Object[] {123,124}; dao.delete(sql, values); */ String sql = "select first_name fn,salary sal,department_id from employee where employee_id = ?"; Map map = dao.selectById(sql, 100); System.out.println(map.get("department_id")); } }
2.提供配置文件
为Dao封装类提供一个配置文件,将数据库的连接信息都写在配置文件中,当程序运行时先读取配置文件的内容,用户可以对配置文件进行修改。
java中使用的配置文件有两种:xml配置文件和properties配置文件 xml配置文件:表示结构化的数据,但是编写和读取时,比较麻烦 properties配置文件:编写和读取比较容易,不能配置结构化的数据,配置数据时将数据配置成键值对的形式
步骤:
-
在src目录下建立一个file类型的文件,文件后缀为properties
-
将使用的数据录入到properties中
-
使用util包的 ResourceBundle 类的 getBundle(String str) 方法,返回一个ResourceBundle对象,然后通过getString(String str)操作这个对象得到配置文件中对应键的值
ResourceBundle
#util包中的ResourceBundle类 getBundle(String str):获得一个ResourceBundle对象,可以通过这个对象查询配置文件中的数据;str代表文件的路径,默认的路径是项目的src文件夹; getString(String str):以字符串的形式,返回文件中对应键的值;参数代表键
示例:
public class Test { public static void main(String[] args) { //ResourceBundle 是专门读取properties配置文件的类 //getBundle("db"); 参数properties文件的为 位置+名字 //直接从类路径 读取 如果db.properties放在了com.oracle包中,那么写法:com.oracle.db ResourceBundle bundle = ResourceBundle.getBundle("db"); System.out.println(bundle.getString("password")); } }
在类目录下添加了一个配置文件,使用了配置文件后的代码
//每个方法要使用的变量,定义在属性中 private static String url ; private static String user ; private static String password ; private static String driver ; private static Connection conn; private PreparedStatement stmt; private ResultSet rs; private ResultSetMetaData rsmd; //加载驱动只执行一次 , 读取一次配置文件 static { try { ResourceBundle bundle = ResourceBundle.getBundle("db"); url = bundle.getString("url"); user = bundle.getString("user"); password = bundle.getString("password"); driver = bundle.getString("driver"); Class.forName(driver); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
配置文件:
url=jdbc:mysql://127.0.0.1:3306/test2108?characterEncoding=utf8 user=root password=root driver=com.mysql.jdbc.Driver
每个表封装单独Dao
Dap类要写很多(一张表一个),将SQL语句封装到每个Dap的方法中,用户使用更加方便
1.为每个表创建Vo类
#Vo类 用来存储数据的类,一个类实例就是一条记录,尽量保证类名和表名一致,数据库列的名字和类属性的名字最好相同,类型要保持一致 属性一般用private修饰,然后使用方法来设置属性和读取属性
示例:
public class Employee { private int employeeId; private String firstName; private String lastName; private Date hireDate; private String jobId; private double salary; private int departmentId; public int getEmployeeId() { return employeeId; } public void setEmployeeId(int employeeId) { this.employeeId = employeeId; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public Date getHireDate() { return hireDate; } public void setHireDate(Date hireDate) { this.hireDate = hireDate; } public String getJobId() { return jobId; } public void setJobId(String jobId) { this.jobId = jobId; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } public int getDepartmentId() { return departmentId; } public void setDepartmentId(int departmentId) { this.departmentId = departmentId; } }
2.为Dao类们创建接口
定义一个接口用以规范统一多个Dao类; 标准规范,在接口中定义了所有的Dao方法结构,所有Dao都要实现这个接口
Dao类中应该有的方法
insert(Object obj); update(Object obj); delete(Object obj); insert(Object obj);
示例:
/** * 包括 增 删 改 查 方法的标准规范 * @author 86159 **/ public interface IDao<Entity,PK> { public int insert(Entity e); /** * 更新表数据,参数传入对象的属性值 全部更新到对应的表中 * @param e * @return */ public int update(Entity e); /** * 单条删除 * @param id * @return */ public int delete(PK id); /** * 多条删除 * @param ids * @return */ public int delete(PK[] ids); /** * 按主键查询 * @param id * @return */ public Entity selectByPrimaryKey(PK id); /** * @param obj * @return */ public List<Entity> select(Map map); /** * 带分页的条件查询 * @param map * @param pageNo * @param pageSize * @return */ public List<Entity> selectForPage(Map map,int pageNo,int pageSize); /** * 在分页时,需要总页数,而总页数通过 总记录数和每页显示的记录数 进行计算的,该方法就是获得总记 录数的方法 * @param map * @return */ public int getCount(Map map); }
3.编写一个所有Dao的父类
编写一个BaseDao类,用来完成所有Dao类都要进行的操作,并且把通用的数据和方法存储在父类中 第一种方法生成的Dao类可以用作所有Dao类的父类
4.总结
每个Dao类 要继承BaseDao,实现IDao接口 为什么要继承BaseDao? 因为BaseDao中有执行SQL语句的方法 ;BaseDao中定义了所有Dao中要用到的属 性,包括Connection、PreparedStatement等。 为什么要实现IDao接口?因为每个Dao的方法都要统一结构,做到标准规范。
示例
public class EmployeeDao extends BaseDao implements IDao<Employee,Integer>{ @Override public int insert(Employee e) { // TODO Auto-generated method stub return 0; } @Override public int update(Employee e) { // TODO Auto-generated method stub return 0; } @Override public int delete(Integer id) { // TODO Auto-generated method stub return 0; } @Override public int delete(Integer[] ids) { // TODO Auto-generated method stub return 0; } @Override public Employee selectByPrimaryKey(Integer id) { // TODO Auto-generated method stub return null; } @Override public List<Employee> select(Map map) { // TODO Auto-generated method stub return null; } @Override public List<Employee> selectForPage(Map map, int pageNo, int pageSize) { // TODO Auto-generated method stub return null; } @Override public int getCount(Map map) { // TODO Auto-generated method stub return 0; } public static void main(String[] args) { EmployeeDao dao = new EmployeeDao(); } }