JDBC(MySQL)——DAY05(DAO设计模式,JDBC事务处理,阿帕奇工具类)

1.Database Access Object:数据库访问(存取)对象,专门用于业务逻辑层与持久化数据之间,实现持久化数据的访问。专门与数据库打交道的层。 所谓DAO层是从系统分层结构出发,把数据存取操作集中到DAO层,以便于维护和逻辑清晰。

所以设计了DAO之后我们不需要在主函数中去调用数据库操作,而是在Service层进行数据库操作,我们只需要调用Service层的方法就好了。

2.ORM(对象关系映射):使用反射机制实现的使数据库中读出的记录能与实体类对象进行映射的操作;

3.DAO设计时的顺序:

(1)先设定一个统一DAO的接口用来限制功能与降低耦合性;

(2)再编写一个BaseDAO作为抽象基类,实现接口的方法,使用泛型完成一些重复度比较高的操作,并留出一些个性化的方法留给子类来实现;

(3)编写子类,使其继承父类的方法,并可根据泛型指定父类没有指定的类型;

4.这里是我自己编写的DAO模式:

java 复制代码
public interface EmpDAO {
    public Emp selectById(Object id);
    public List<Emp> selectList();
}
java 复制代码
public class BaseDAO<T> {
    private Class<T> persistentClass;
    public BaseDAO() {
        Type genType = this.getClass().getGenericSuperclass();
        if (genType instanceof ParameterizedType) {
            persistentClass = (Class<T>) ((ParameterizedType) genType).getActualTypeArguments()[0];
        }
    }
    public int save(T entity) {
        Class<?> clazz = entity.getClass();
        Field[] fields = clazz.getDeclaredFields();
        Object[] values = new Object[fields.length];
        idType idType = null;
        for(Field field : fields){
            TableId annotation = field.getAnnotation(TableId.class);
            if(annotation != null){
                idType = annotation.value();
                break;
            }
        }
        StringBuilder stringBuilder = new StringBuilder();
        //insert into 表名(字段1,字段2,字段3...)values()
        stringBuilder.append("insert into ");
        stringBuilder.append(persistentClass.getSimpleName());
        stringBuilder.append("(");
        int index =0;
        for(Field field : fields){
            field.setAccessible(true);
            stringBuilder.append(field.getName()).append(",");
            try {
                values[index++] = field.get(entity);
            }catch (IllegalAccessException e){
                e.printStackTrace();
            }
        }
        stringBuilder.setCharAt(stringBuilder.length()-1,')');
        stringBuilder.append("values(");
        for(Field field : fields){
            stringBuilder.append("?").append(",");
        }
        stringBuilder.setCharAt(stringBuilder.length()-1,')');
        int index1 = stringBuilder.indexOf("?");
        if(idType == demo.idType.UUID){
            values[0] = UUID.randomUUID().toString().replace("-","");
        }else if(idType ==demo.idType.AUTO_INCREMENT ){
            stringBuilder.replace(index1,index1+1,"default");
            values = Arrays.copyOfRange(values,1,values.length);
        }
        stringBuilder.setCharAt(stringBuilder.length()-1,')');
        DBUtil.executeUpdatePrepared(stringBuilder.toString(),values);
        return DBUtil.executeUpdatePrepared(stringBuilder.toString(),values);
    }
    public int delete(Object id) {
        StringBuilder stringBuilder = new StringBuilder();
        String simpleName = persistentClass.getSimpleName();
        stringBuilder.append("delete from ");
        stringBuilder.append(simpleName);
        stringBuilder.append(" where id=?");
        return DBUtil.executeUpdatePrepared(stringBuilder.toString(),id);
    }
    public int update(T entity) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("update ");
        stringBuilder.append(persistentClass.getSimpleName().toLowerCase());
        stringBuilder.append(" set ");
        Field[] fields = persistentClass.getDeclaredFields();
        Object[] values = new Object[fields.length];
        try {
            for(int i = 1; i < fields.length; i++){
                fields[i].setAccessible(true);
                stringBuilder.append(fields[i].getName()).append("=?,");
                values[i-1] = fields[i].get(entity);
            }
            fields[0].setAccessible(true);
            values[values.length-1]=fields[0].get(entity);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        stringBuilder.deleteCharAt(stringBuilder.length()-1);
        stringBuilder.append(" where ");
        stringBuilder.append(fields[0].getName()).append("=?");
        return DBUtil.executeUpdatePrepared(stringBuilder.toString(),values);
    }
}
java 复制代码
public class Emp {
    @TableId(idType.AUTO_INCREMENT)
    private Integer id;
    private String name;
    private String gender;
    private Boolean depart;
    private Float sal;
    private Date hiredate;
    public Emp() {}

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Boolean isDepart() {
        return depart;
    }

    public void setDepart(Boolean depart) {
        this.depart = depart;
    }

    public Float getSal() {
        return sal;
    }

    public void setSal(Float sal) {
        this.sal = sal;
    }

    public Date getHiredate() {
        return hiredate;
    }

    public void setHiredate(Date hiredate) {
        this.hiredate = hiredate;
    }

    @Override
    public String toString() {
        return "emp{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", depart=" + depart +
                ", sal=" + sal +
                ", hiredate=" + hiredate +
                '}';
    }
}
java 复制代码
public class DBUtil {
    private static String URL;
    private static String USERNAME;
    private static String PASSWORD;
    private static String DRIVER;
    private static String CONNECTION_POOL_NAME;

    static {
        ResourceBundle rb = ResourceBundle.getBundle("info");
        URL = rb.getString("jdbc.url");
        USERNAME = rb.getString("jdbc.username");
        PASSWORD = rb.getString("jdbc.password");
        DRIVER = rb.getString("jdbc.driver");
        CONNECTION_POOL_NAME = rb.getString("pool.class1");
    }

    public static Connection getConnection() {
        if (CONNECTION_POOL_NAME.equals(DruidDataSource.class.getName())) {
            /*DruidDataSource ds = new DruidDataSource();
            ds.setUrl(URL);
            ds.setUsername(USERNAME);
            ds.setPassword(PASSWORD);
        }*/
            try {
                Class<?> clazz = DruidDataSource.class;
                Object o1 = clazz.getConstructor().newInstance();
                Method setUrl = clazz.getMethod("setUrl", String.class);
                setUrl.invoke(o1, URL);
                Method setUsername = clazz.getMethod("setUsername", String.class);
                setUsername.invoke(o1, USERNAME);
                Method setPassword = clazz.getMethod("setPassword", String.class);
                setPassword.invoke(o1, PASSWORD);
                Method setDriver = clazz.getMethod("setDriverClassName", String.class);
                setDriver.invoke(o1, DRIVER);
                Method getConnection = clazz.getMethod("getConnection");
                clazz.getMethod("setInitialSize", int.class).invoke(o1, 5);
                clazz.getMethod("setMaxActive", int.class).invoke(o1, 20);
                clazz.getMethod("setMinIdle", int.class).invoke(o1, 10);
                return (Connection) getConnection.invoke(o1);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        try {
            Class<?> clazz = HikariDataSource.class;
            Object o2 = clazz.getConstructor().newInstance();
            Method setUrl = clazz.getMethod("setJdbcUrl", String.class);
            setUrl.invoke(o2, URL);
            Method setUsername = clazz.getMethod("setUsername", String.class);
            setUsername.invoke(o2, USERNAME);
            Method setPassword = clazz.getMethod("setPassword", String.class);
            setPassword.invoke(o2, PASSWORD);
            Method setDriver = clazz.getMethod("setDriverClassName", String.class);
            setDriver.invoke(o2, DRIVER);
            Method getConnection = clazz.getMethod("getConnection");
            return (Connection) getConnection.invoke(o2);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public static int[] executeUpdateBatch(String sql,Object[] ... args) {
        Connection conn = getConnection();
        PreparedStatement ps = null;
        try{
            ps = conn.prepareStatement(sql);
            conn.setAutoCommit(false);
            for(Object[] arg : args) {
                int j = 1;
                for(Object o : arg) {
                    ps.setObject(j++, o);
                }
                ps.addBatch();
            }
            int[] re = ps.executeBatch();
            conn.commit();
            close(conn,ps);
            return re;
        }catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public static void close(Connection conn, Statement ps) {
        try {
            conn.close();
            ps.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    public static  int executeUpdatePrepared(String sql,Object ... args){
        Connection conn = getConnection();
        PreparedStatement pstmt = null;
        try{
            pstmt = conn.prepareStatement(sql);
            int i = 1;
            for(Object arg : args){
                pstmt.setObject(i++,arg);
            }
            int m = pstmt.executeUpdate();
            return m;
        }catch (SQLException e){
            throw new RuntimeException(e);
        }finally {
            close(conn,pstmt);
        }
    }
    public static DBObject executeQueryPrepared(String sql,Object ... args){
        Connection conn = getConnection();
        PreparedStatement pstmt = null;
        DBObject obj = null;
        try{
            pstmt = conn.prepareStatement(sql);
            int i = 1;
            for(Object arg : args){
                pstmt.setObject(i++,arg);
            }
            obj = new DBObject(conn,pstmt,pstmt.executeQuery());
        }catch (SQLException e){
            throw new RuntimeException(e);
        }
        return obj;
    }
    public static void close(DBObject obj){
        close(obj.getConn(), obj.getStmt());
    }
}
java 复制代码
public class DBObject {
    Connection conn;
    Statement stmt;
    ResultSet rs;
    public DBObject() {}
    public DBObject(Connection conn, Statement stmt, ResultSet rs) {
        this.conn = conn;
        this.stmt = stmt;
        this.rs = rs;
    }

    public Connection getConn() {
        return conn;
    }

    public void setConn(Connection conn) {
        this.conn = conn;
    }

    public Statement getStmt() {
        return stmt;
    }

    public void setStmt(Statement stmt) {
        this.stmt = stmt;
    }

    public ResultSet getRs() {
        return rs;
    }

    public void setRs(ResultSet rs) {
        this.rs = rs;
    }

}

这就是几个必要的DB工具类,实体类,实现了之后只需要调用BaseDAO和empDAO的方法就好了;

5.JDBC的事务处理:

操作流程:开启事务Connection.setAutoCommit(false);

提交事务Connection.commit;

回滚事务Connection.rollback();

6.保存点SavePoint

Connection.rollback(SavePoint);

7.Apache DbUti工具类的使用:

和我们自己编写的数据库工具类相似,可以使用线程池,也可以直连,可以执行dml,ddl,dql操作,如果是dql操作可以指定获取的结果的类型,比如说map、List这种集合类也是可以的;

API调用:

QueryRunner,主要的工具类,可以传入数据源,也可以不传入数据源;

RunnerSetHandler:类型转换接口,将结果集转换为对应数据类型;

BeanHandler:是ResultSetHandler的实现类,将结果封装为一个java对象中,传入Class类,以指定返回值的类型;

BeanListHandler:是ResultSetHandler的实现类,将结果转换为List,可以将多行的结果集存储在一个实体类List中;

MapHandler:将结果集中的第一行数据封装到一个Map中,Key是String类型,是数据库查询的列名,value是Object,数据库中对应值;

ScalarHandler:将第一行数据的指定列数据返回,可强转为泛型中的数据类型;

MapListHandler:将结果集中的每一行行数据封装为一个map加入到List中;

相关推荐
2401_891482172 小时前
用Python批量处理Excel和CSV文件
jvm·数据库·python
m0_743297422 小时前
使用Flask快速搭建轻量级Web应用
jvm·数据库·python
小年糕是糕手2 小时前
【35天从0开始备战蓝桥杯 -- 补充包】
开发语言·前端·数据结构·数据库·c++·算法·蓝桥杯
Navicat中国2 小时前
构建韧性数据库架构
数据库·数据库架构·navicat
kyrie学java2 小时前
基于 Redis 的分布式登录系统实现总结
数据库·redis·分布式
salipopl2 小时前
mysql数据被误删的恢复方案
数据库·mysql
数据知道2 小时前
MongoDB大数据文档设计:处理超过16MB文档的实用策略
数据库·mongodb
悦数图数据库4 小时前
图数据库如何重塑行业智能决策 | 破局金融数据关联困局 悦数图数据库
数据库·金融
2401_879693874 小时前
Python深度学习入门:TensorFlow 2.0/Keras实战
jvm·数据库·python