美文网首页
JDBC二执行SQL语句与获取结果

JDBC二执行SQL语句与获取结果

作者: 衣忌破 | 来源:发表于2019-08-09 21:38 被阅读0次

    使用JDBC主要有三步:
    连接数据库 => 执行SQL语句 => 获得结果

    这一篇聊聊如何利用Connection进行CRUD即第二和第三步。期间会引入部分设计模式不断重构代码,最终实现类似JDBCTemplate的模板类,方便其他类继承或组合以提高开发效率。

    主要内容:

    • 基础示例
    • 抽取重复代码(JdbcUtils工具类)
    • CRUD
    • 异常处理
    • 模板方法模式重构
    • 策略模式重构

    基础示例

    整个过程:通过DriverManager得到Connection,由Connection得到PreparedStatement,preparedStatement执行sql返回结果集。

    image.png

    数据库表结构

    image.png
    public class Basic {
        @Test
        public void testJdbc() throws SQLException, ClassNotFoundException {
            // 1.注册驱动
            Class.forName("com.mysql.jdbc.Driver");
    
            // 2.建立连接
            String url = "jdbc:mysql://192.168.136.128:3306/test";
            String user = "root";
            String password = "root";
            Connection conn = DriverManager.getConnection(url, user, password);
    
            // 3.创建sql模板
            String sql = "select * from t_user where id = ?";
            PreparedStatement preparedStatement = conn.prepareStatement(sql);
    
            // 4.设置模板参数
            preparedStatement.setInt(1, 5);
    
            // 4.执行语句
            ResultSet rs = preparedStatement.executeQuery();
    
            // 5.处理结果
            while (rs.next()) {
                System.out.println(rs.getObject(1) + "\t" + rs.getObject(2) + "\t"
                        + rs.getObject(3) + "\t" + rs.getObject(4));
            }
    
            // 6.释放资源
            rs.close();
            preparedStatement.close();
            conn.close();
        }
    }
    
    image.png

    抽取重复代码

    上面示例代码,有两个问题:

    • 获取Connection的步骤太复杂,需要封装
    • 资源释放太随意,不够规范

    尤其第二点,一定要重视。数据库的连接数是有限的,如果不及时释放,会导致其他请求无法访问。应该把释放资源的操作放在finally中,保证资源一定会被关闭。

    Basic

    public class Basic {
            //请注意,这里抛了异常
        @Test
        public void testJdbc() throws SQLException {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                // 1.获取连接
                conn = JdbcUtils.getConnection();
    
                // 2.创建sql模板
                String sql = "select * from t_user where id = ?";
                ps = conn.prepareStatement(sql);
    
                // 3.设置模板参数
                ps.setInt(1, 5);
    
                // 4.执行语句
                rs = ps.executeQuery();
    
                // 5.处理结果
                while (rs.next()) {
                    System.out.println(rs.getObject(1) + "\t" + rs.getObject(2) + "\t"
                            + rs.getObject(3) + "\t" + rs.getObject(4));
                }
            } finally {
                // 6.释放资源
                JdbcUtils.free(rs, ps, conn);
            }
        }
    }
    

    JdbcUtils 1.0版

    public class JdbcUtils {
    
        private static Properties props = null;
    
        // 只在JdbcUtils类被加载时执行一次!
        static {
            // 给props进行初始化,即加载jdbc.properties文件到props对象中
            try {
                InputStream in = JdbcUtils.class.getClassLoader()
                        .getResourceAsStream("jdbc.properties");
                props = new Properties();
                props.load(in);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
    
            // 加载驱动类
            try {
                Class.forName(props.getProperty("driver"));
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
        }
    
        // 获取连接
        public static Connection getConnection() throws SQLException {
            // 得到Connection
            return DriverManager.getConnection(props.getProperty("url"),
                    props.getProperty("username"),
                    props.getProperty("password"));
        }
    
        // 释放连接
        public static void free(ResultSet rs, Statement st, Connection conn) {
            try {
                if (rs != null)
                    rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (st != null)
                        st.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    if (conn != null)
                        try {
                            conn.close();
                        } catch (SQLException e) {
                            e.printStackTrace();
                        }
                }
            }
        }
    }
    

    CRUD

    目录结构

    image.png

    UserDao

    public interface UserDao {
        int addUser(User user) throws SQLException;
        int update(User user) throws SQLException;
        int delete(User user) throws SQLException;
        User getUser(int Id) throws SQLException;
        User findUser(String name, int age) throws SQLException;
    }
    

    UserDaoJdbcImpl

    public class UserDaoJdbcImpl implements UserDao {
    
        public int addUser(User user) throws SQLException {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                conn = JdbcUtils.getConnection();
                String sql = "insert into t_user(name,age, birthday) values (?,?,?) ";
                ps = conn.prepareStatement(sql);
                ps.setString(1, user.getName());
                ps.setInt(2, user.getAge());
                ps.setDate(3, new java.sql.Date(user.getBirthday().getTime()));
                return ps.executeUpdate();
            } finally {
                JdbcUtils.free(rs, ps, conn);
            }
        }
    
        public int delete(User user) throws SQLException {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                conn = JdbcUtils.getConnection();
                String sql = "delete from t_user where id=?";
                ps = conn.prepareStatement(sql);
                ps.setInt(1, user.getId());
                System.out.println(sql);
                return ps.executeUpdate(sql);
            } finally {
                JdbcUtils.free(rs, ps, conn);
            }
    
        }
    
        public int update(User user) throws SQLException {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                conn = JdbcUtils.getConnection();
                String sql = "update t_user set name=?, age=?, birthday=? where id=? ";
                ps = conn.prepareStatement(sql);
                ps.setString(1, user.getName());
                ps.setInt(2, user.getAge());
                ps.setDate(3, new java.sql.Date(user.getBirthday().getTime()));
                ps.setInt(4, user.getId());
                return ps.executeUpdate();
            } finally {
                JdbcUtils.free(rs, ps, conn);
            }
        }
    
        public User findUser(String name, int age) throws SQLException {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            User user = null;
            try {
                conn = JdbcUtils.getConnection();
                String sql = "select id, name, birthday  from t_user where name=? and age=?";
                ps = conn.prepareStatement(sql);
                ps.setString(1, name);
                ps.setInt(2, age);
                rs = ps.executeQuery();
                while (rs.next()) {
                    user = new User();
                    user.setId(rs.getInt("id"));
                    user.setAge(rs.getInt("age"));
                    user.setName(rs.getString("name"));
                    user.setBirthday(rs.getDate("birthday"));
                }
            } finally {
                JdbcUtils.free(rs, ps, conn);
            }
            return user;
        }
    
        public User getUser(int userId) throws SQLException {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            User user = null;
            try {
                conn = JdbcUtils.getConnection();
                String sql = "select id, name, age, birthday from t_user where id=?";
                ps = conn.prepareStatement(sql);
                ps.setInt(1, userId);
                rs = ps.executeQuery();
                while (rs.next()) {
                    user = new User();
                    user.setId(rs.getInt("id"));
                    user.setAge(rs.getInt("age"));
                    user.setName(rs.getString("name"));
                    user.setBirthday(rs.getDate("birthday"));
                }
            } finally {
                JdbcUtils.free(rs, ps, conn);
            }
            return user;
        }
    }
    

    DAOTest

    public class DAOTest {
        public static void main(String[] args) throws SQLException {
            UserDao userDao = new UserDaoJdbcImpl();
            User user = new User();
            user.setAge(19);
            user.setName("little ming");
            user.setBirthday(new Date());
            userDao.addUser(user);
        }
    }
    
    image.png

    异常处理

    上面的CRUD并没有捕获异常,而是直接往外抛。这会带来两个后果:

    • SQLException是编译时异常,Service在调用DAO时必须处理异常,否则编译不通过。如何处理?要么继续抛,交给Controller处理(意义不大),要么try catch(Service层代码很臃肿,不美观)。

    • DAO接口有声明异常SQLException,这等于向外界暴露DAO层是JDBC实现。而且针对该接口只能用关系型数据库,耦合度太高了。后期无法切换DAO实现。

    比较好的做法是,将SQLException转为运行时异常抛出,Service层可处理也可不处理。

    我们需要自定义一个DaoException:

    public class DaoException extends RuntimeException {
        public DaoException() {
        }
    
        public DaoException(String message) {
            super(message);
        }
    
        public DaoException(Throwable cause) {
            super(cause);
        }
    
        public DaoException(String message, Throwable cause) {
            super(message, cause);
        }
    }
    

    UserDaoJdbcImpl(捕获编译时异常,转为运行时异常)

    public class UserDaoJdbcImpl implements UserDao {
    
        public int addUser(User user) {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                conn = JdbcUtils.getConnection();
                String sql = "insert into t_user(name,age, birthday) values (?,?,?) ";
                ps = conn.prepareStatement(sql);
                ps.setString(1, user.getName());
                ps.setInt(2, user.getAge());
                ps.setDate(3, new java.sql.Date(user.getBirthday().getTime()));
                return ps.executeUpdate();
            } catch (SQLException e) {
                            //转为DaoException(运行时异常)抛出,Service层可以不处理                         
                throw new DaoException(e.getMessage(), e);
            } finally {
                JdbcUtils.free(rs, ps, conn);
            }
        }
    
        public int delete(User user) {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                conn = JdbcUtils.getConnection();
                String sql = "delete from t_user where id=?";
                ps = conn.prepareStatement(sql);
                ps.setInt(1, user.getId());
                System.out.println(sql);
                return ps.executeUpdate(sql);
            } catch (SQLException e) {
                throw new DaoException(e.getMessage(), e);
            } finally {
                JdbcUtils.free(rs, ps, conn);
            }
    
        }
    
        public int update(User user) {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                conn = JdbcUtils.getConnection();
                String sql = "update t_user set name=?, age=?, birthday=? where id=? ";
                ps = conn.prepareStatement(sql);
                ps.setString(1, user.getName());
                ps.setInt(2, user.getAge());
                ps.setDate(3, new java.sql.Date(user.getBirthday().getTime()));
                ps.setInt(4, user.getId());
                return ps.executeUpdate();
            } catch (SQLException e) {
                throw new DaoException(e.getMessage(), e);
            } finally {
                JdbcUtils.free(rs, ps, conn);
            }
        }
    
        public User findUser(String name, int age) {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            User user = new User();
            try {
                conn = JdbcUtils.getConnection();
                String sql = "select id, name, birthday  from t_user where name=? and age=?";
                ps = conn.prepareStatement(sql);
                ps.setString(1, name);
                ps.setInt(2, age);
                rs = ps.executeQuery();
                while (rs.next()) {
                    user.setName(rs.getString("name"));
                    user.setBirthday(rs.getDate("birthday"));
                }
            } catch (SQLException e) {
                throw new DaoException(e.getMessage(), e);
            } finally {
                JdbcUtils.free(rs, ps, conn);
            }
            return user;
        }
    
        public User getUser(int userId) {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            User user = new User();
            try {
                conn = JdbcUtils.getConnection();
                String sql = "select id, name, age, birthday from t_user where id=?";
                ps = conn.prepareStatement(sql);
                ps.setInt(1, userId);
                rs = ps.executeQuery();
                while (rs.next()) {
                    user.setId(rs.getInt("id"));
                    user.setAge(rs.getInt("age"));
                    user.setName(rs.getString("name"));
                    user.setBirthday(rs.getDate("birthday"));
                }
            } catch (SQLException e) {
                throw new DaoException(e.getMessage(), e);
            } finally {
                JdbcUtils.free(rs, ps, conn);
            }
            return user;
        }
    }
    

    模板方法模式重构

    上面的CRUD代码太繁琐了!如果还有StudentDaoJdbcImpl、TeacherDaoJdbcImpl,那么同样的代码要写好多遍。所以,必须要重构。大体思路是:相同的代码抽取到父类AbstractDao。观察UserDao:

    image.png

    增删改除了方法名不同,其他都一样,可以归为一类;查询单独一类。

    我们先考虑如何重构增删改方法(以delete为观察点)。

    image.png

    我们发现,只有sql模板和设置模板参数的代码不同。可以把sql和参数抽取成父类方法的形参。

    AbstractDao

    public abstract class AbstractDao {
        // 增删改
        public int update(String sql, Object...args) {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                conn = JdbcUtils.getConnection();
                // sql由调用者传入
                ps = conn.prepareStatement(sql);
                // 遍历设置模板参数
                for (int i = 0; i < args.length; i++){
                    ps.setObject(i + 1, args[i]);
                }
                return ps.executeUpdate();
            } catch (SQLException e) {
                throw new DaoException(e.getMessage(), e);
            } finally {
                JdbcUtils.free(rs, ps, conn);
            }
        }
    }
    

    UserDaoImpl

    public class UserDaoImpl extends AbstractDao implements UserDao {
        //增
        public int addUser(User user) {
            String sql = "insert into t_user(name, age, birthday) values (?,?,?) ";
            Object[] args = new Object[]{user.getName(), user.getAge(),
                    user.getBirthday()};
            //调用父类AbstractDao的方法
            return super.update(sql, args);
        }
    
        //删
        public int update(User user) {
            String sql = "update t_user set name=?, age=?, birthday=? where id=? ";
            Object[] args = new Object[]{user.getName(), user.getAge(),
                    user.getBirthday(), user.getId()};
            return super.update(sql, args);
        }
    
        //改
        public int delete(User user) {
            String sql = "delete from t_user where id=?";
            Object[] args = new Object[]{user.getId()};
            return super.update(sql, args);
        }
            //待实现
        public User getUser(int Id) {
            return null;
        }
            //待实现
        public User findUser(String name, int age) {
            return null;
        }
    }
    

    示意图

    image.png

    也就是说,AbstractDao的作用仅仅是“组装sql语句并执行”,不涉及差异性代码

    UserDao/StudentDao/TeacherDao...等有差异的代码仅仅是sql和参数,交给具体实现类编写。

    接下来,我们考虑一下如何抽取查询方法。

    查询最麻烦的地方在于结果集映射。比如,UserDaoImpl查询得到User,StudentDaoImpl查询得到Student。

    image.png
    • 返回值:用Object接受
    • sql和模板参数:效仿update抽取即可
    • 结果集映射:???

    我们发现,父类无法制定一个通用代码满足所有子类的结果集映射,因为只有子类自己知道映射规则。所以,我们只能把结果集映射的权利交还给子类去实现。子类如果需要查询,就必须自己实现AbstractDao的rowMapper方法。

    AbstractDao

    public abstract class AbstractDao {
        // 增删改
        public int update(String sql, Object...args) {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                conn = JdbcUtils.getConnection();
                // sql由调用者传入
                ps = conn.prepareStatement(sql);
                // 遍历设置模板参数
                for (int i = 0; i < args.length; i++){
                    ps.setObject(i + 1, args[i]);
                }
                return ps.executeUpdate();
            } catch (SQLException e) {
                throw new DaoException(e.getMessage(), e);
            } finally {
                JdbcUtils.free(rs, ps, conn);
            }
        }
    
        //查询
        public Object query(String sql, Object[] args) {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                conn = JdbcUtils.getConnection();
                // sql由调用者传入
                ps = conn.prepareStatement(sql);
                // 遍历设置模板参数
                for (int i = 0; i < args.length; i++)
                    ps.setObject(i + 1, args[i]);
                rs = ps.executeQuery();
                Object obj = null;
                // 结果集映射,子类必须实现抽象方法rowMapper
                if (rs.next()) {
                    obj = rowMapper(rs);
                }
                return obj;
            } catch (SQLException e) {
                throw new DaoException(e.getMessage(), e);
            } finally {
                JdbcUtils.free(rs, ps, conn);
            }
        }
    
        // 定义成抽象方法,让子类去实现
        abstract protected Object rowMapper(ResultSet rs);
    }
    

    UserDaoImpl

    public class UserDaoImpl extends AbstractDao implements UserDao {
        //增
        public int addUser(User user) {
            String sql = "insert into t_user(name, age, birthday) values (?,?,?) ";
            Object[] args = new Object[]{user.getName(), user.getAge(),
                    user.getBirthday()};
            //调用父类AbstractDao的方法
            return super.update(sql, args);
        }
    
        //删
        public int update(User user) {
            String sql = "update t_user set name=?, age=?, birthday=? where id=? ";
            Object[] args = new Object[]{user.getName(), user.getAge(),
                    user.getBirthday(), user.getId()};
            return super.update(sql, args);
        }
    
        //改
        public int delete(User user) {
            String sql = "delete from t_user where id=?";
            Object[] args = new Object[]{user.getId()};
            return super.update(sql, args);
        }
          
            //查询
        public User getUser(int id) {
            String sql = "select id, name, age, birthday from t_user where id=?";
            Object[] args = new Object[]{id};
            Object user = super.query(sql, args);
            return (User) user;
        }
    
            //查询
        public User findUser(String name, int age) {
            String sql = "select id, name, age, birthday from t_user where name=? and age=?";
            Object[] args = new Object[]{name, age};
            Object user = super.query(sql, args);
            return (User) user;
        }
    
        //UserDaoImpl的结果集映射器
        protected Object rowMapper(ResultSet rs) {
            User user = null;
            try {
                user = new User();
                user.setId(rs.getInt("id"));
                user.setAge(rs.getInt("age"));
                user.setName(rs.getString("name"));
                user.setBirthday(rs.getDate("birthday"));
            } catch (SQLException e) {
                throw new DaoException("mapping error");
            }
            return user;
        }
    }
    

    示意图

    image.png

    觉得不好理解?换个角度:

    image.png

    至此,模板方法模式重构结束。但是,代码仍然存在隐患。


    策略模式重构

    我们来分析一个问题:假设现在UserDao增加了一个新方法:

    public interface UserDao {
        int addUser(User user);
        int update(User user);
        int delete(User user);
        User getUser(int Id);
        User findUser(String name, int age);
        //新增查询方法:根据年龄查询
        List<User> selectUsers(int age);
    }
    

    返回值是List<User>,而UserDaoImpl中实现的映射方法rowMapper()只能封装User对象:

    public class UserDaoImpl extends AbstractDao implements UserDao {
            //利用rowMapper封装bean
        public User getUser(int id) {
            String sql = "select id, name, age, birthday from t_user where id=?";
            Object[] args = new Object[]{id};
            Object user = super.query(sql, args);
            return (User) user;
        }
            //无法利用rowMapper封装List
        public List<User> selectUsers(int age) {
            String sql = "select id, name, age, birthday from t_user where age=?";
            Object[] args = new Object[]{age};
            List<User> list = super.query(sql, args);
            return list;
        }
    
        //UserDaoImpl的结果集映射器
        protected Object rowMapper(ResultSet rs) {
            User user = null;
            try {
                user = new User();
                user.setId(rs.getInt("id"));
                user.setAge(rs.getInt("age"));
                user.setName(rs.getString("name"));
                user.setBirthday(rs.getDate("birthday"));
            } catch (SQLException e) {
                throw new DaoException("mapping error");
            }
            return user;
        }
    }
    

    也就是说,根据返回值的不同(String,User,List<User>)每个查询方法的“映射规则”有所不同。

    image.png

    应该把“映射规则”单独抽取出来,和sql、args一样,在调用父类方法时传入。比如调用getUser()和selectUser()传入的sql、args不同,映射规则也不同。如此一来,sql模板、模板参数、映射规则都高度灵活,可定制。

    image.png

    但是我们很清楚,所谓的“映射规则”其实就是一个方法,比如原先的rowMapper()方法:

     //UserDaoImpl的结果集映射器
        protected Object rowMapper(ResultSet rs) {
            User user = null;
            try {
                user = new User();
                user.setId(rs.getInt("id"));
                user.setAge(rs.getInt("age"));
                user.setName(rs.getString("name"));
                user.setBirthday(rs.getDate("birthday"));
            } catch (SQLException e) {
                throw new DaoException("mapping error");
            }
            return user;
        }
    

    在JS中,可以把function作为参数传递,然后在另一个方法内部执行。

    image.png

    但是Java不行...怎么办?

    没关系,我们之前学习动态代理时其实早就接触过这种思想:直接传方法不行?那我就把这个方法塞进一个对象里,通过对象去调用方法(把需要代理对象执行的代码写在InvocationHandler对象的invoke方法中,再把invocationHandler塞进代理对象供它调用)。

    所以,这次也照做就行了。只不过这种模式其实叫策略模式,而且一般是传入接口的实现类。

    image.png

    好了,现在子类已经不需要实现父类的抽象方法了(一个规则无法满足不同返回值映射),改为由子类实现RowMapper接口传入匿名对象的方式,所以AbstractDao中的抽象方法可以删除。也就是说AbstractDao已经没有抽象方法了。于是我把它声明为普通类(可以new),并改名为MyJDBCTemplate。而且,使用MyJDBCTemplate时,我决定不再使用继承,而是选择组合方式(组合比继承灵活)。

    image.png

    RowMapper

    public interface RowMapper {
        //映射结果集
        Object mapRow(ResultSet rs) throws SQLException;
    }
    

    MyJDBCTemplate

    public class MyJDBCTemplate {
        // 增删改
        public int update(String sql, Object...args) {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                conn = JdbcUtils.getConnection();
                // sql由调用者传入
                ps = conn.prepareStatement(sql);
                // 遍历设置模板参数
                for (int i = 0; i < args.length; i++){
                    ps.setObject(i + 1, args[i]);
                }
                return ps.executeUpdate();
            } catch (SQLException e) {
                throw new DaoException(e.getMessage(), e);
            } finally {
                JdbcUtils.free(rs, ps, conn);
            }
        }
    
        //查询,RowMapper是接口类型,需要传入接口的实现类对象
        public List<Object> query(String sql, Object[] args, RowMapper rowMapper) {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            List list = new ArrayList();
            try {
                conn = JdbcUtils.getConnection();
                // sql由调用者传入
                ps = conn.prepareStatement(sql);
                // 遍历设置模板参数
                for (int i = 0; i < args.length; i++)
                    ps.setObject(i + 1, args[i]);
                rs = ps.executeQuery();
                Object obj = null;
                // 映射规则由子类传入
                while (rs.next()) {
                    Object o = rowMapper.mapRow(rs);
                    list.add(o);
                }
                return list;
            } catch (SQLException e) {
                throw new DaoException(e.getMessage(), e);
            } finally {
                JdbcUtils.free(rs, ps, conn);
            }
        }
    }
    
    

    UserDaoImpl

    
    public class UserDaoImpl implements UserDao {
        MyJDBCTemplate jdbcTemplate = new MyJDBCTemplate();
    
        //增
        public int addUser(User user) {
            String sql = "insert into t_user(name, age, birthday) values (?,?,?) ";
            Object[] args = new Object[]{user.getName(), user.getAge(),
                    user.getBirthday()};
            //调用jdbcTemplate的update方法
            return jdbcTemplate.update(sql, args);
        }
    
        //删
        public int update(User user) {
            String sql = "update t_user set name=?, age=?, birthday=? where id=? ";
            Object[] args = new Object[]{user.getName(), user.getAge(),
                    user.getBirthday(), user.getId()};
            //调用jdbcTemplate的update方法
            return jdbcTemplate.update(sql, args);
        }
    
        //改
        public int delete(User user) {
            String sql = "delete from t_user where id=?";
            Object[] args = new Object[]{user.getId()};
            //调用jdbcTemplate的update方法
            return jdbcTemplate.update(sql, args);
        }
    
            //查询单个
        public User getUser(int id) {
            String sql = "select id, name, age, birthday from t_user where id=?";
            Object[] args = new Object[]{id};
            //调用jdbcTemplate的query方法,传入sql,args,RowMapper匿名对象
            List list = jdbcTemplate.query(sql, args, new RowMapper() {
                public Object mapRow(ResultSet rs) throws SQLException {
                    User user = new User();
                    user.setId(rs.getInt("id"));
                    user.setAge(rs.getInt("age"));
                    user.setName(rs.getString("name"));
                    user.setBirthday(rs.getDate("birthday"));
                    return user;
                }
            });
            return (User)list.get(0);
        }
    
        public User findUser(String name, int age) {
            String sql = "select id, name, age, birthday from t_user where name=? and age=?";
            Object[] args = new Object[]{name, age};
            //调用jdbcTemplate的query方法,传入sql,args,RowMapper匿名对象
            List list = jdbcTemplate.query(sql, args, new RowMapper() {
                public Object mapRow(ResultSet rs) throws SQLException {
                    User user = new User();
                    user.setId(rs.getInt("id"));
                    user.setAge(rs.getInt("age"));
                    user.setName(rs.getString("name"));
                    user.setBirthday(rs.getDate("birthday"));
                    return user;
                }
            });
            return (User)list.get(0);
        }
        
            //查询多个
        public List selectUsers(int age) {
            String sql = "select id, name, age, birthday from t_user where age=?";
            Object[] args = new Object[]{age};
            //调用jdbcTemplate的query方法,传入sql,args,RowMapper匿名对象
            List list = jdbcTemplate.query(sql, args, new RowMapper() {
                public Object mapRow(ResultSet rs) throws SQLException {
                        User user = new User();
                        user.setId(rs.getInt("id"));
                        user.setAge(rs.getInt("age"));
                        user.setName(rs.getString("name"));
                        user.setBirthday(rs.getDate("birthday"));
                        return user;
                }
            });
            return list;
        }
    }
    

    测试

    image.png

    当然,上面的所谓JDBCTemplate是非常粗糙的,还存在很多不严谨的地方,就当是个玩具。有兴趣的朋友可以去看看Spring的JDBCTemplate。

    相关文章

      网友评论

          本文标题:JDBC二执行SQL语句与获取结果

          本文链接:https://www.haomeiwen.com/subject/qjwrjctx.html