JDBC与反射的基础学习

JDBC

JDBC操作数据库步骤

  1. 加载驱动(JDBC4之后可以省略,需要导入相关数据库的驱动包)
  2. 获取连接
  3. 获取执行sql命令的对象
  4. 执行
  5. 处理结果
  6. 关闭资源

Statement & PreparedStatement
Statement是由JDBC接口提供的一个用于执行静态SQL语句的接口,但是通过Statement执行SQL语句时,会存在SQL注入的风险,因此JDBC还提供了另一个接口PreparedStatement,用于解决这一问题,使用PreparedStatement对象可以对sql语句预编译,从而防止sql注入。

//准备sql语句
String sql = "select * from emp where eno=?";
//获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb", "root", "123456");
//对SQL语句预处理(编译)并获取预处理对象
PreparedStatement ps = conn.prepareStatement(sql);
ps.setObject(1, 1001);
//执行查询
ResultSet rs = ps.executeQuery();
if(rs.next()){
    int no = rs.getInt("eno");
    String name = rs.getString("ename");
    BigDecimal sal = rs.getBigDecimal("sal");
    Date date = rs.getDate("hiredate");//java.sql.Date
    int dno = rs.getInt("dno");
    System.out.println(no+"/"+name+"/"+sal+"/"+date+"/"+dno);
}else{
    System.out.println("未查询到数据");
}
//关闭资源
rs.close();
ps.close();
conn.close();

DAO与VO模式

DAO(Data Access Object):数据访问对象,在实际开发中由于项目的结构复杂,一般会项目进行分层实现,常见的MVC模式为:Model、View、Controller等三层,而对数据的访问操作一般位于Model层,称之为数据模型,因此对操作数据的步骤一般也会在一个特定的位置一并处理,这一层我们称之为DAO层,该层为直接访问数据库,执行相关表的CRUD操作,不参与任何业务逻辑的实现,只负责操作数据库表中的数据

连接池技术与Druid

由于数据库连接是一种资源,这种资源在使用前必须先创建,而这个创建过程是存在时间和空间的开销的,如果每次在执行数据库访问时都创建连接,并且使用完后要关闭连接,这个过程必然是效率低下的;因此,在实际开发中可以考虑在进行数据库操作前,先提前创建并维护一批数据库连接对象,当需要使用时,从这批对象中获取一个连接,用完之后再返还,从而避免了不必要的时间开销,提高程序的运行效率,这种技术在JDBC中称之为连接池技术(Connection Pool).
目前比较常用的连接池技术包含:apache-DBCP、C3P0(Spring/Hibernate框架在使用)、Proxool以及阿里巴巴的Druid(号称全世界最快的连接池)

SQL批处理

当我们需要一次性执行多次sql操作时,JDBC为我们提供了SQL批处理的功能,使用批处理的功能比直接使用循环语句执行sql效率要高,JDBC对于批处理提供了两种方式:基于PreparedStatement的批处理和基于Statement的批处理。
基于PreparedStatement的批处理操作:

Connection conn = DBUtils.getConn();
PreparedStatement ps = conn.prepareStatement("insert into dept(dname,tel) values(?,?)");
for (int i = 0; i < 5000; i++) {
    ps.setString(1, "测试部门"+i);
    ps.setString(2, "100100"+i);
    //添加批处理
    ps.addBatch();
}
//执行批处理操作(返回数组为每一次更新的影响计数行)
int[] i = ps.executeBatch();

基于Statement的批处理操作

Connection conn = DBUtils.getConn();
Statement stat = conn.createStatement();
stat.addBatch("insert into dept(dname,tel) values('策划部','10987')");
stat.addBatch("delete from dept where dno=170");
stat.addBatch("update dept set tel='10010' where dno=100");
int[] i = stat.executeBatch();
for (int j : i) {
    System.out.println(j);
}

反射

反射是java中类的一种自省机制,通过反射可以在运行时获取类中的成分,并且使用,从而提高了java的动态性;java中任何一个类都有一个对应的java.lang.Class对象,这个对象包含了类中的所有成分(属性,构造器,方法,注解等),获取类的Class对象有三种方式:

  1. Class.forName(“类路径”) Class clz = class.forName(“com.softeem.entity.Emp”)
  2. 类名称.class Class clz = Emp.class
  3. 对象引用.getClass() Class clz = emp.getClass()

反射示例:基于反射实现对象拷贝

public class ObjectCopy {

    public static <T> T clone(Object source,Class<T> t){
        T target = null;
        try {
            //获取源对象的Class对象
            Class clz = source.getClass();
            //创建新对象(无数据)
            target = t.newInstance();

            //获取源对象中的所有属性列表
            Field[] fields = clz.getDeclaredFields();
            for (Field f : fields) {
                //获取属性名
                String fname = f.getName();//ename
                //获取源对象的所有get方法,并执行,将其返回值通过调用目标对象的set方法,设置给目标对象 ename  setEname
                //获取当前属性的setter/getter方法名
                String setMethodName = "set"+fname.substring(0,1).toUpperCase()+fname.substring(1);//setEname
                String getMethodName = "get"+fname.substring(0,1).toUpperCase()+fname.substring(1);//setEname

                //获取方法对象
                Method setMethod = clz.getMethod(setMethodName, f.getType());
                Method getMethod = clz.getMethod(getMethodName);

                //调用源对象的getter获取返回值 getName() getDno()
                Object returnValue = getMethod.invoke(source);
                //调用目标对象的setter方法设置值
                setMethod.invoke(target, returnValue);
            }
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        //返回产生的新对象
        return target;
    }

    public static void main(String[] args) {
        Account a = new Account(1, "狗蛋", new BigDecimal(3500));
        Emp e = new Emp(1, "翠花", new BigDecimal("4500"), new Date(), 10);

        Account obj = clone(a,Account.class);
        System.out.println(obj);

        Emp obj2 = clone(e,Emp.class);
        System.out.println(obj2);
    }
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值