帅气的毛毛侠

导航

Spring学习之路:jdbcTemplate的简单练习

一、介绍

  Hibernate是对jdbc的重度包装,用户感觉不到sql的操作,全用HSQL;mybatis是对jdbc的中度包装,依旧要写一些sql,精髓是在于sql的组装;jdbcTemplate为轻度组装,它只是将数据库的连接和关闭包装了,但是没有比mybatis智能(体现在未能将查询出来的结果自动设置到model类中),更别说hibernate了

  本次的练习是从jdbctemplate最初的形式开始,一步步地向真正开发实战中使用的形式靠近。具体内容如下:

    1⃣️、使用DriverManagerDataSource连接数据库

    2⃣️、对数据库的操作(增、删、改)

    3⃣️、使用spring管理jdbcTemplate,这样会减少很多的代码

    4⃣️、使用C3P0数据池管理连接:在实际的工作环境中DriverManagerDataSource是不会去使用的,因为每次查询都要打开连接,效率太差;在真实的开发中必须要考虑更换数据库的情况,所以最好的方式是将数据库连接信息独立出来保存在一个属性文件中。

    5⃣️、加入jdbcDAOSupport支持:虽然可以直接利用jdbcTemplate进行数据库的操作,但在大部分的dao实现中,很少有这样的人去做,往往让DAO子类既实现了DAO接口,又同时去继承一个jdbcTemplate的抽象类。自动注入过程应该交给一个统一的类来进行处理,所以就定义了一个JdbcDAOSupport类,但是这个类除了负责处理jdbcTemplate类的对象之外,还可以负责数据库的自动关闭,即如果你想要让你的开发数据库可以自动关闭,就必须要继承jdbcdaosupport类。

二、练习  

  (1)使用DriverManagerDataSource连接数据库

    public static DriverManagerDataSource getDBManager()throws Exception{
        DriverManagerDataSource dbManager=new DriverManagerDataSource();// org.springframework.jdbc.datasource.DriverManagerDataSource
dbManager.setDriverClassName("oracle.jdbc.driver.OracleDriver");
dbManager.setPassword("tiger");
        dbManager.setUrl("jdbc:oracle:thin:@localhost:1521:orcl");
        dbManager.setUsername("scott");
        Connection conn=dbManager.getConnection();
        System.out.println(conn);
        return dbManager;
    }

  (2)完成数据库的CRUD操作

    首先了解JdbcTemplate这个类:

      • 构造方法:除了无参构造方法之外,还可以直接传入一个数据源:public JdbcTemplate(DataSource data);
      • 设置数据源:public void setDataSource(DataSource data);
      • 普通更新操作:public int update(String sql,Object...args);
      • 更新并取得id:public int update(PreparedStatementCreator psc,KeyHolder generatedKeyHolder) throws DataAccessException;
      • 查询全部:public <T> List<T> queryForList(String sql,Object[] args,RowMapper<T> rowMapper) throws DataAccessException.
      • 查询单列:public <T> List<T> queryForList(String sql,Object[] args,Class<T> elementsType) throws DataAccessException.
      • 查询单个数据:public <T> queryForObject(String sql,Object[] args,Class<T> requiredType) throws DataAccessException.

    下面介绍这些方法的使用:

      1、普通更新操作

    public static boolean update() throws Exception {
        JdbcTemplate template=new JdbcTemplate();
        template.setDataSource(getDBManager());
        String sql="update myemp set job=? where empno=?";
        int count=template.update(sql,"CXY",7369);
        return count>0;
    }

      2、更新并取得id

    //更新,并取得id,id在建表时应该是自增长类型
    public static void updateAndGetID() throws Exception{
        JdbcTemplate template=new JdbcTemplate();
        template.setDataSource(getDBManager());
        final String sql="update emp set job=? where empno=?";
        KeyHolder key=new GeneratedKeyHolder();
        int count=template.update(new PreparedStatementCreator() {
            @Override
            public PreparedStatement createPreparedStatement(Connection conn)
                    throws SQLException {
                PreparedStatement pstmt=conn.prepareStatement(sql);
                pstmt.setString(1, "CKW");
                pstmt.setInt(2, 7369);
                return pstmt;
            }
        },key);
        System.out.println("当前的id是:"+key.getKey());
        if(count>0)System.out.println("执行成功!");
        else System.out.println("执行不成功!");
    }

      3、查询全部,设置到vo时要手动设置,这点比较麻烦,可以使用反射自动设置。

    //查询全部操作,将数据库中的所有数据查询出来
    public static void getAll() throws Exception{
        JdbcTemplate template=new JdbcTemplate();
        template.setDataSource(getDBManager());
        String sql="select empno,ename,job,mgr,hiredate,sal,comm,deptno from myemp where rownum<=?";
        List<Emp> list=template.query(sql,new RowMapper<Emp>(){
            @Override
            public Emp mapRow(ResultSet rs, int rowCount) throws SQLException {
                System.out.println("返回的当前数据行:"+rowCount);
                Emp emp=new Emp();
                emp.setEmpno(rs.getInt("empno"));
                emp.setEname(rs.getString("ename"));
                emp.setComm(rs.getInt("comm"));
                emp.setDeptno(rs.getInt("deptno"));
                emp.setHiredate(rs.getDate("hiredate"));
                emp.setJob(rs.getString("job"));
                return emp;
            }
        },10);
        System.out.println(list);
    }

    使用反射来自动设置内容,需要注意的是sql语句中的字段顺序要与vo类中的setXxx顺序要一致,方法输入某个类的字面常量以及要设置的值,返回设置好数据的一个vo类的实例:

  public static Object invokeSetMethods(Class<?> classType,String... args) throws Exception{
        Method[] m=classType.getDeclaredMethods();
        Object obj=classType.newInstance();
        int index=0;
        for (Method method : m) {
            if(method.toString().contains("set")){
                method.invoke(obj,args[index++]);
            }
        }
        return obj;
   }

 

    4、查询单列 

    //查询单列数据
    public static void demo5() throws Exception{
        JdbcTemplate template=new JdbcTemplate();
        template.setDataSource(getDBManager());
        String sql="select empno from myemp where rownum<=?";
        List<Integer> list=template.queryForList(sql, new Object[]{5}, Integer.class);
        System.out.println(list);
    }

      5、查询单个数据

    //查询单个数据
    public static void demo6() throws Exception{
        JdbcTemplate temp=new JdbcTemplate();
        temp.setDataSource(demo1());
        String sql="select count(*) from myemp where rownum<=?";
        int i=temp.queryForObject(sql, new Object[]{8}, Integer.class);
        System.out.println(i);
    }

   

  (3)使用Spring来管理JdbcTemplate

     模拟业务层实现入下所示,使用xml中配置的bean进行注入:

@Component
public class DAOImpl implements IDAO {
    private JdbcTemplate jt;
    @Autowired  
    public DAOImpl(JdbcTemplate jt){
        this.jt=jt;
    }
    
    @Override
    public boolean doCreate(Emp emp) {
        String sql="update myemp set job=? where empno=?";
        int count=jt.update(sql,emp.getJob(),emp.getEmpno());
        return count>0;
    }
}

 

    在xml中要配置DriverManagerDataSource的bean和JdbcTemplate的bean

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
        <property name="username" value="scott"/>
        <property name="password" value="tiger"/>
    </bean>
    <bean id="jdbcTamplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean> 

 

  (4)使用c3p0来管理jdbc的连接

    首先创建database.properties

db.driver=oracle.jdbc.driver.OracleDriver
db.url=jdbc:oracle:thin:@172.16.237.129:1521:orcl
db.user=scott
db.password=tiger

pool.max=10
pool.min=10
pool.init=5
pool.idle=5

    在xml中替换练习(3)的配置:

    <context:property-placeholder location="classpath:database.properties"/><!--读取属性文件,路径是在classpath,练习中为src下可以读取到-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${db.driver}"/>
        <property name="jdbcUrl" value="${db.url}"/>
        <property name="user" value="${db.user}"/>
        <property name="password" value="${db.password}"/>
        <!-- 最大可用连接数 -->
        <property name="maxPoolSize" value="${db.max}"/>
        <!-- 最小维持连接数 -->
        <property name="minPoolSize" value="${db.min}"/>
        <!-- 初始化连接数 -->
        <property name="initialPoolSize" value="${db.init}"/>
        <!-- 最大等待连接 -->
        <property name="maxIdleTime" value="${db.password}"/>
    </bean>  
    <bean id="jdbcTamplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean> 

  (5)JdbcDaoSupport的支持

    将DAOImpl改写成如下代码,红色部分显示了与之前的不同之处:

@Component
public class DAOImpl extends JdbcDaoSupport implements IDAO {
    
    @Autowired
    public DAOImpl(JdbcTemplate jt){
        super.setJdbcTemplate(jt);
    }
    
    @Override
    public boolean doCreate(Emp emp) {
        String sql="update myemp set job=? where empno=?";
        int count=super.getJdbcTemplate().update(sql,emp.getJob(),emp.getEmpno());
        return count>0;
    }
}

 

 

 

 

小结与问题:

  虽然JdbcTemplate的手动书写练习(2)代码比较多,但是在项目中测试的时候可以派上用场,不用修改xml中的内容使得混乱。

  练习(2)中的“更新并取得id”这个函数,取得的是怎么样的id并没有很好的概念。

 

转载请说明出处~ 

 

posted on 2017-03-05 11:45  帅气的毛毛侠  阅读(1054)  评论(0编辑  收藏  举报