JDBC封装第一类笔记

通用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配置文件:编写和读取比较容易,不能配置结构化的数据,配置数据时将数据配置成键值对的形式

步骤:

  1. 在src目录下建立一个file类型的文件,文件后缀为properties

  2. 将使用的数据录入到properties中

  3. 使用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(); 
    } 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值