zoukankan      html  css  js  c++  java
  • JdbcTemplate

    JdbcTemplate

    查询方法小结
    JdbcTemplate中常用查询方法	说明:
    
    Map<String,Object> queryForMap(String sql, Object…args)	
    查询1条记录,封装成一个Map
    
    <T> T queryForObject(String sql, RowMapper<T> rowMapper, Object... args)	
    查询1条记录,封装成一个实体类对象
    
    public <T> T queryForObject(String sql, Class<T> requiredType, Object... args)	
    查询1条记录,封装成指定类型的对象
    
    List<Map<String, Object>> queryForList(String sql, Object…args)	
    查询多条记录,封装成List<Map>
    
    List<T> query(String sql, RowMapper<T> rowMapper, Object... args)	
    查询多条记录,封装成List<T>
    
    JDBC已经能够满足大部分用户最基本的需求,
    但是在使用JDBC时,必须自己来管理数据库资源如:获取
    PreparedStatement,设置SQL语句参数,关闭连接等步骤。
    JDBCTemplate就是Spring对JDBC的封装,目的是使JDBC更加易于使用。
    JDBCTemplate是Spring的一部分。 
    JDBCTemplate处理了资源的建立和释放。
    他帮助我们避免一些常见的错误,比如忘了总要关闭连接。
    他运行核心的JDBC工作流,如Statement的建立和执行,而我们只需要提供SQL语句和提取结果。
    使用JdbcTemplate编程我们只需要做以下步骤:
    1)提供SQL语句和占位符的值
    2)得到封装好的查询结果集
    
    -分类
    在JDBCTemplate中执行SQL语句的方法大致分为3类:
    1. execute :可以执行所有SQL语句,一般用于执行DDL语句。
    2. update :用于执行 INSERT 、 UPDATE 、 DELETE 等DML语句。
    3. queryXxx :用于DQL数据查询语句。
    
    
    -前期流程
    C3P0基于配置文件实现连接池
    1. 准备C3P0连接池
    2. 导入依赖的jar包
     ? spring-beans-4.1.2.RELEASE.jar
     ? spring-core-4.1.2.RELEASE.jar
     ? spring-jdbc-4.1.2.RELEASE.jar
     ? spring-tx-4.1.2.RELEASE.jar
     ? com.springsource.org.apache.commons.logging-1.1.1.jar
    3. 创建 JdbcTemplate 对象,传入连接池对象
    4. 调用 execute 、 update 、 queryXxx 等方法
     ? public JdbcTemplate(DataSource dataSource)
     ? 创建JdbcTemplate对象,方便执行SQL语句
     ? public void execute(final String sql)
     ? execute可以执行所有SQL语句,因为没有返回值,一般用于执行DDL语句。
    
    -JBDCTemplate执行DDL语句
    public class Demo {
     ? public static void main(String[] args) {
     ? ? ? 
     ? ? ? // 创建表的SQL语句
     ? ? ? String sql = "CREATE TABLE product("
     ? ? ?"pid INT PRIMARY KEY AUTO_INCREMENT,"
     ? ? ?"pname VARCHAR(20),"
     ? ? ?"price DOUBLE"
     ? ? ?");";
    
     ? ? ?//通过构造方法创建JdbcTemplate对象,传递数据源对象//通过工具类得到数据源
     ? ? ?JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
     ? ? ? 
         ?//调用execute执行DDL语句
     ? ? ?jdbcTemplate.execute(sql);
      }
    }
    
    -使用步骤
    1.创建JdbcTemplate对象 
    2.编写SQL语句 
    3.使用JdbcTemplate对象的update方法进行增删改
    public int update(final String sql)
    用于执行INSERT、UPDATE、DELETE等DML语句。
    JdbcTemplate的update方法用于执行DML语句。
    同时还可以在SQL语句中使用?占位符,在update方法的Object... args可变参数中传入对应的参数。
    
    -增删改
    使用JdbcTemplate对象的update方法进行增删改
    // JDBCTemplate添加数据
    public static void test01() throws Exception {
     ? ?//通过构造方法创建JdbcTemplate对象,传递数据源对象//通过工具类得到数据源
     ? ?JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
     ? ?
     ? ?String sql = "INSERT INTO product VALUES (NULL, ?, ?);";
     ? ?jdbcTemplate.update(sql, "iPhone3GS", 3333);
     ? ?jdbcTemplate.update(sql, "iPhone4", 5000);
     ? ?jdbcTemplate.update(sql, "iPhone4S", 5001);
     ? ?jdbcTemplate.update(sql, "iPhone5", 5555);
     ? ?jdbcTemplate.update(sql, "iPhone5C", 3888);
     ? ?jdbcTemplate.update(sql, "iPhone5S", 5666);
     ? ?jdbcTemplate.update(sql, "iPhone6", 6666);
     ? ?jdbcTemplate.update(sql, "iPhone6S", 7000);
     ? ?jdbcTemplate.update(sql, "iPhone6SP", 7777);
     ? ?jdbcTemplate.update(sql, "iPhoneX", 8888);
    }
    // JDBCTemplate修改数据
    public static void test02() throws Exception {
     ? ?JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
     ? ?String sql = "UPDATE product SET pname=?, price=? WHERE pid=?;";
     ? ?int i = jdbcTemplate.update(sql, "XVIII", 18888, 10);
     ? ?System.out.println("影响的行数: " + i);
    }
    // JDBCTemplate删除数据
    public static void test03() throws Exception {
     ? ?JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
     ? ?String sql = "DELETE FROM product WHERE pid=?;";
     ? ?int i = jdbcTemplate.update(sql, 7);
     ? ?System.out.println("影响的行数: " + i);
    }
    
    
    -查询
    JDBCTemplate实现查询
    
    queryXxx :用于DQL数据查询语句
    public int queryForInt(String sql)
    执行查询语句,返回一个int类型的值。
    public long queryForLong(String sql)
    执行查询语句,返回一个long类型的数据。
    public  T queryForObject(String sql, Class requiredType)
    执行查询语句,返回一个指定类型的数据。
    public Map queryForMap(String sql)
    执行查询语句,将一条记录放到一个Map中。
    其中键是字符串的列名,值是Object类型
    注:如果返回多条记录会出现异常
    public List> queryForList(String sql)
    执行查询语句,返回一个List集合,List中存放的是Map类型的数据。
    
    1. 创建JdbcTemplate对象
    2. 编写查询的SQL语句
    3. 使用JdbcTemplate对象的queryXxx 方法
    4. 输出结果
    
    --queryForInt
    public static void test02() throws Exception {
        // String sql = "SELECT COUNT(*) FROM product;";
        String sql = "SELECT pid FROM product WHERE price=18888;";
        JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
        int forInt = jdbcTemplate.queryForInt(sql);
        System.out.println(forInt);
    }
    
    --queryForLong
    public static void test03() throws Exception {
        String sql = "SELECT COUNT(*) FROM product;";
        // String sql = "SELECT pid FROM product WHERE price=18888;";
    	JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
        long forLong = jdbcTemplate.queryForLong(sql);
        System.out.println(forLong);
    }
    
    --queryForObject
    public static void test04() throws Exception {
        String sql = "SELECT pname FROM product WHERE price=7777;";
        JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
        String str = jdbcTemplate.queryForObject(sql, String.class);
        System.out.println(str);
    }
    
    --queryForMap
    public static void test05() throws Exception {
        String sql = "SELECT * FROM product WHERE pid=?;";
        JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
        Map map = jdbcTemplate.queryForMap(sql, 6);
        System.out.println(map);
    }
    
    --queryForList
    public static void test06() throws Exception {
        String sql = "SELECT * FROM product WHERE pid<?;";
        JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, 8);
        for (Map<String, Object> map : list) {
        System.out.println(map);
        }
    }
    
    -查询1条记录封装成自定义的类
    JdbcTemplate接口  
    <T> T queryForObject(String sql, RowMapper<T> rowMapper, Object... args)    
    作用:查询一条记录封装成一个实体类对象
    参数:
    1) 查询的SQL语句,有可能有占位符
    2) RowMapper是一个接口,我们需要提供接口的实现类。重写接口中的方法,将结果集封装成一个对象。
    3) 替换占位符的值
    返回值:封装好的对象
    RowMapper接口中的方法 
    T mapRow(ResultSet rs, int rowNum) throws SQLException  
    作用:将结果集中的一行映射成一个T对象
    参数:
    1) 查询到的结果集
    2) 表示当前这条结果集的行号,从0开始编号
    返回值:封装好数据的实体对象
    
    -查询id为1的学生
    使用queryForObject()查询1个学生,
    但queryForObject()必须要指定查询的结果集与JavaBean属性之间的对应关系,
    所以这个方法需要传递一个接口做为参数:RowMapper<T>。
    
    我们需要重写这个方法,指定属性与列之间的映射关系,代码中可以使用匿名内部类。
    
    //查询一条记录封装成Student对象
    @Test
    public void testFindOneStudent() {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
    
    //使用JdbcTemplate对象的queryForObject ()方法查询结果,方法中传入一个接口的匿名内部类
        Student student = jdbcTemplate.queryForObject("select * from student where id=?", new RowMapper<Student>() {
            @Override
            public Student mapRow(ResultSet rs, int i) throws SQLException {
                Student student = new Student();
                student.setId(rs.getInt("id"));
                student.setName(rs.getString("name"));
                student.setGender(rs.getBoolean("gender"));
                student.setBirthday(rs.getDate("birthday"));
                return student;
            }
        }, 2);
        System.out.println(student);
    }
    
    //如果每个JavaBean都需要自己封装每个属性,那开发效率将大打折扣,
    //所以Spring JDBC提供了这个接口的实现类BeanPropertyRowMapper,使用起来更加方便。
    //只需要在构造方法中传入Student.class类对象即可,它会自动封装所有同名的属性。
    
    -使用BeanPropertyRowMapper实现类
    public BeanPropertyRowMapper(Class<T> mappedClass)  
    作用:RowMapper接口的实现类
    参数:一个类对象,用来指定是哪一种实体类。如:Student.class 类型
        
    表的字段名与实体类属性名映射的规则:
    1)表的字段名与类中的属性名相同,表的字段名大小写不区分。
    2)表的字段名如果有多个单词使用下划线隔开,与Java中驼峰命名的属性相对应。
    表字段名    类的属性名
    name或NAME   name
    dept_name   deptName
    
    @Test
    public void testFindOneStudent2() {
        //1)创建JdbcTemplate对象,传入数据源对象。
        JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
        //2)编写SQL语句 
        //3)使用JdbcTemplate对象的queryForObject ()方法查询结果,
        //方法中传入BeanPropertyRowMapper的实现类 new BeanPropertyRowMapper<>(Student.class)
        Student student = jdbcTemplate.queryForObject("select * from student where id=?", 	  new BeanPropertyRowMapper<>(Student.class), 3);
        System.out.println(student);
    }
    
    -聚合函数
    public <T> T queryForObject(String sql, Class<T> requiredType, Object... args)  
    作用:用来返回一个值的方法
    参数:
    1)SQL语句
    2)Class表示类对象,用于指定返回的数据类型。如:String.class表示字符串类型。Integer.class
    3)替换占位符的值
    返回值:指定类型的值
    
    //查询一共有多少个男生,使用queryForObject()方法,指定参数为Integer.class类型
    
    //查询一共有多少个男生
    @Test
    public void testCount() {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
        int count = jdbcTemplate.queryForObject("select count(*) from student where gender=?", Integer.class, true);
        System.out.println(count);
    }
    
    -查询多条记录
    JdbcTemplate接口
    List<Map<String, Object>> queryForList(String sql, Object…args) 
    作用:查询多条记录
    参数:
    1) 要执行的SQL
    2) 占位符的值
    返回值:一个集合,每个元素是Map类型
    此方法也可用于查询多列或表连接的情况
    

    查询所有的男生,使用queryForList()方法查询元素
    注:queryForList这个方法默认返回的List中的每个元素是Map对象

    @Test
    public void testFindList() {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
        List<Map<String, Object>> list = jdbcTemplate.queryForList("select * from student where gender=?", true);
        for (Map<String, Object> map : list) {
            System.out.println(map);
        }
    }
    
    -查询多条记录封装成"List

    如果要封装成List对象怎么办呢?

    这里需要使用query方法来实现,如果使用queryForList方法则需要自己实现RowMapper接口。

    List<T> query(String sql, RowMapper<T> rowMapper, Object... args)   
    作用:将多条记录封装成一个List集合
    参数:
    1) SQL语句
    2) 映射接口,我们提供实现类BeanPropertyRowMapper
    3) 占位符的值
    返回值:一个集合,每个元素是实体类对象
    
    --查询所有的学生
    //查询所有的学生
    @Test
    public void testFindList2() {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
        List<Student> students = jdbcTemplate.query("select * from student", 
         new BeanPropertyRowMapper<>(Student.class));
        for (Student student : students) {
            System.out.println(student);
        }
    }
    
    --案例:JdbcTemplate的应用

    案例需求:

    使用JdbcTemplate实现用户登录,登录成功后显示所有的用户信息。表和数据如下:
    create table user(
        id int primary key auto_increment,
        name varchar(20),
        password varchar(20),
        gender char(1),
        city varchar(20)
    );
     insert into user values(null,'张三','123','男','广州'),(null,'李四','456','男','北京'),(null,'王五','789','女','长沙');
    

    案例步骤:

    1) 创建表结构和数据
    
    2) 创建实体类User,产生toString()方法
    
    3) 编写数据访问类UserDao,实现登录和查询所有用户的方法
    
    4) 登录方法需要捕获EmptyResultDataAccessException异常
    
    5) 编写表示层类,在main函数中,用户输入用户名和密码。
    
    6) 调用UserDao类实现相应的功能
    
    7) 如果登录成功,则显示所有用户信息
    
    8) 如果登录失败,则显示登录失败
    
    /**
     * 数据访问类
     */
    public class UserDao {
     ? ?private JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
     ? ?/**
     ? ? * 登录,如果登录成功,返回User,如果登录失败返回null
     ? ? */
     ? ?public User login(String name, String password) {
     ? ? ? ?try {
     ? ? ? ? ? return jdbcTemplate.queryForObject("select * from user where name=? and password=?",
     ? ? ? ? ? ? ? ? ? ?new BeanPropertyRowMapper<>(User.class), name, password);
     ? ? ?  } catch (DataAccessException e) {
     ? ? ? ? ? ?return null;
     ? ? ?  }
     ?  } 
    
     ? ?/**
     ? ? * 查询所有的用户
     ? ? */
     ? ?public List<User> findAll() {
     ? ? ? ?return jdbcTemplate.query("select * from user", new BeanPropertyRowMapper<>(User.class));
     ?  }
    }
    
    public class DemoLogin {
     ? ?public static void main(String[] args) {
     ? ? ? ?Scanner scanner = new Scanner(System.in);
     ? ? ? ?System.out.println("请输入用户名:");
     ? ? ? ?String name = scanner.nextLine();
     ? ? ? ?System.out.println("请输入密码:");
     ? ? ? ?String pass = scanner.nextLine();
     ? ? ? ?//创建对象
     ? ? ? ?UserDao userDao = new UserDao();
     ? ? ? ?User login = userDao.login(name, pass);
     ? ? ? ?if (login==null) {
     ? ? ? ? ? ?System.out.println("登录失败");
     ? ? ?  }
     ? ? ? ?else {
     ? ? ? ? ? ?System.out.println("欢迎您:" + login.getName());
     ? ? ? ? ? ?System.out.println("所有的用户:");
     ? ? ? ? ? ?List<User> users = userDao.findAll();
     ? ? ? ? ? ?for (User user : users) {
     ? ? ? ? ? ? ? ?System.out.println(user);
     ? ? ? ? ?  }
     ? ? ?  }
     ?  }
    }
    
    

    来源于网络,如有争议联系删除

  • 相关阅读:
    java-date和Calendar运用
    java-date类使用练习(1)
    java-正则表达式
    JAVA-String类的应用
    java-重写equals
    java-抽象类、接口等实际应用 (酒店小案例)
    fuzz系列之libfuzzer
    ZAB协议(转)
    Paxos(转自wiki)
    Zookeeper简介和安装使用
  • 原文地址:https://www.cnblogs.com/zongJianKun/p/10209684.html
Copyright © 2011-2022 走看看