• spring项目篇12---网上商城之配置以及工具类的编写


    这个项目用到jdbc技术,研究了一下,为了学习一下,对于执行sql语句,自己进行封装工具类来进行处理,这样便于进一步理解。

    首先我们来看一下搭建的基本项目结构

     我们接下来看一下相关的配置信息:

    首先看一下web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
        <!--解决post乱码问题-->
        <filter>
            <filter-name>encoding</filter-name>
            <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
            <!--设置UTF-8编码-->
            <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>encoding</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        <!--配置servlet的前端控制器-->
        <servlet>
            <servlet-name>mySpringMvc</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!--指定servlet的配置文件,默认情况下servlet的配置文件在/WEB-INF/${servlet-name}-servlet.xml文件-->
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:applicationContext.xml</param-value>
            </init-param>
            <!--这个就是指定项目初识启动时就要初始化-->
            <load-on-startup>1</load-on-startup>
        </servlet>
        <!--配置拦截请求-->
        <servlet-mapping>
            <!--指定控制器-->
            <servlet-name>mySpringMvc</servlet-name>
            <!--拦截所有请求,不包括jsp,但是包括所有js,css,png等-->
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>

    接下来看一下我们的spring 的配置文件applicationContext.xml

        <!--配置注解扫描-->
        <context:component-scan base-package="com.yang" />
        <!--因为配置了静态文件,spring不会自动为我们加载HandlerMapping与HandlerAdapter,因此需要进行初始化-->
        <mvc:annotation-driven />
    
        <!--配置静态文件-->
        <mvc:resources location="WEB-INF/static/images" mapping="/images/**" />
        <mvc:resources location="WEB-INF/static/js" mapping="/js/**" />
        <mvc:resources location="WEB-INF/static/css" mapping="/css/**" />
    
        <!--上传文件配置-->
        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <property name="defaultEncoding" value="UTF-8" />
            <property name="maxUploadSize" value="5120" />
        </bean>
        <!--配置视图解析器-->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/page/" />
            <property name="suffix" value=".jsp" />
        </bean>

    为了进行封装JDBC的增删改查,我们首先先封装一下JDBC查询出的结果集

    首先定义一个接口,定义一下我们的这个结果集如何进行处理IResultSetHandler

    package com.yang.handler;
    
    import java.sql.ResultSet;
    
    /**
     * 定义结果集的处理函数
     *
     * @param <T> 范型,指定处理类型
     */
    public interface IResultSetHandler<T> {
        T handle(ResultSet rs) throws Exception;
    }

    接下来对于单一以及列表的Bean进行处理

    BeanHandler

    package com.yang.handler;
    
    import java.beans.BeanInfo;
    import java.beans.Introspector;
    import java.beans.PropertyDescriptor;
    import java.sql.ResultSet;
    
    /**
     * 设置查询单一类型的结果集处置方法
     *
     * @param <T> 范型
     */
    public class BeanHandler<T> implements IResultSetHandler<T> {
        private Class<T> classType;
    
        // 构造函数,设置当前类型的类
        public BeanHandler(Class<T> classType) {
            this.classType = classType;
        }
    
        // 处理函数
        @Override
        public T handle(ResultSet rs) throws Exception {
            // 结果集有结果开始处理
            if (rs.next()) {
                // 1。实例化一个当前处理类型的对象
                T obj = this.classType.getDeclaredConstructor().newInstance();
                // 2。获取这个类型信息,属性, Object.class就是删除那个默认的class的属性
                BeanInfo beanInfo = Introspector.getBeanInfo(this.classType, Object.class);
                PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
                for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
                    // 从结果集中,获取对应的属性值
                    Object object = rs.getObject(propertyDescriptor.getName());
                    // 利用反射,调用set方法,为对象赋值
                    propertyDescriptor.getWriteMethod().invoke(obj, object);
                }
                return obj;
            }
            return null;
        }
    }

    BeanListHandler

    package com.yang.handler;
    
    
    import java.beans.BeanInfo;
    import java.beans.Introspector;
    import java.beans.PropertyDescriptor;
    import java.sql.ResultSet;
    import java.util.ArrayList;
    import java.util.List;
    
    public class BeanListHandler<T> implements IResultSetHandler<List<T>> {
        private Class<T> classType;
    
        public BeanListHandler(Class<T> classType) {
            this.classType = classType;
        }
    
        @Override
        public List<T> handle(ResultSet rs) throws Exception {
            // 1。初始化一个列表,存储我们的对象
            List<T> list = new ArrayList<>();
            while (rs.next()) {
                // 2。实例化一个当前处理类型的对象
                T obj = this.classType.getDeclaredConstructor().newInstance();
    
                // 3。获取这个类型信息,属性, Object.class就是删除那个默认的class的属性
                BeanInfo beanInfo = Introspector.getBeanInfo(this.classType, Object.class);
                PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
    
                for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
                    // 4。从结果集中,获取对应的属性值
                    Object object = rs.getObject(propertyDescriptor.getName());
                    // 5。利用反射,调用set方法,为对象赋值
                    propertyDescriptor.getWriteMethod().invoke(obj, object);
                }
                // 6。向列表添加对象
                list.add(obj);
            }
            return list;
        }
    }

    我们使用的是德鲁伊连接池,我们直接将其的获取数据库连接以及关闭连接记性封装,避免进行重复操作

    JdbcUtil

    package com.yang.util;
    
    import com.alibaba.druid.pool.DruidDataSourceFactory;
    
    import javax.sql.DataSource;
    import java.io.FileInputStream;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Properties;
    
    public class JdbcUtil {
        // 声明一个数据库资源,方便后续进行操作
        public static DataSource ds = null;
    
        static {
            // 1. 初始化读取资源文件
            Properties properties = new Properties();
            try {
                // 2. 读取mysql的配置信息到内存中
                FileInputStream fileInputStream = new FileInputStream("resources/mysql.properties");
                // 3. 转化配置信息
                properties.load(fileInputStream);
                // 4。 生成德鲁伊数据库连接吃池
                ds = DruidDataSourceFactory.createDataSource(properties);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        // 从数据库连接中获取连接对象
        public static Connection getConn(){
            try{
                return ds.getConnection();
            }catch (Exception e){
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 关闭数据库连接对象,释放资源,数据库连接池关闭对象就会把连接放回池中,而不是关闭
         * @param conn 连接对象
         * @param st  连接语句
         * @param rs  查询结果集
         */
        public  static void close(Connection conn, Statement st, ResultSet rs){
            // 关闭结果集
            if(rs!=null){
                try{
                    rs.close();
                }catch (SQLException e){
                    e.printStackTrace();
                }
            }
            // 关闭查询
            if(st!=null){
                try{
                    st.close();
                }catch (SQLException e){
                    e.printStackTrace();
                }
            }
            // 关闭连接对象
            if(conn!=null){
                try{
                    conn.close();
                }catch (SQLException e){
                    e.printStackTrace();
                }
            }
        }
    
    
    }

    为了对数据的增删改查进行封装,为进一步学习,我们自己进行封装

    CRUDTemplete

    package com.yang.util;
    
    import com.yang.handler.IResultSetHandler;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    
    /**
     * 为了方便学习,自己封装一个JDBC的增删改查的工具类,等同于dbUtil
     */
    public class CRUDTemplate {
        private static Connection conn = null;
        private static PreparedStatement ps = null;
        private static ResultSet rs = null;
    
        static {
            conn = JdbcUtil.getConn();
        }
    
        // 这个执行增删改操作,params必须与sql语句中的位置一一对应
        public static int executeUpdate(String sql, Object... params) {
    
            try {
                assert conn != null;
                ps = conn.prepareStatement(sql);
                // 使用prepareStatement的方法为指定位置添加传入参数
                for (int i = 0; i < params.length; i++) {
                    ps.setObject(i + 1, params[i]);
                }
                return ps.executeUpdate();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 最终关闭资源
                JdbcUtil.close(conn, ps, rs);
            }
            // 如果有报错,则返回0
            return 0;
        }
    
        // 执行查询操作
        public static <T> T executeQuery(String sql, IResultSetHandler<T> rh, Object... params) {
            try {
                // 预执行sql语句
                ps = conn.prepareStatement(sql);
                // 将参数传入预执行语句
                for (int i = 0; i < params.length; i++) {
                    ps.setObject(i + 1, params[i]);
                }
                // 执行sql语句并获取结果集
                rs = ps.executeQuery();
                // 调用传入的结果集处理方法,进行处理
                return rh.handle(rs);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                JdbcUtil.close(conn, ps, rs);
            }
            return null;
        }
    }

    我们首先来看一下user的dao层对象应当如何编写

    IUserDao

    package com.yang.dao;
    
    import com.yang.domain.User;
    
    public interface IUserDao {
        // 保存用户
        boolean save(User user);
    
        // 删除用户,接受值int
        boolean delete(Integer id);
    
        // 更新用户
        boolean update(Integer id, User user);
    
        // 获取用户
        User get(Integer id);
    
        User get(String username);
    }

    接下来看一下UserDao的实现类

    UserDaoImpl

    package com.yang.dao.impl;
    
    import com.yang.dao.IUserDao;
    import com.yang.domain.User;
    import com.yang.handler.BeanHandler;
    import com.yang.handler.IResultSetHandler;
    import com.yang.util.CRUDTemplate;
    
    import java.sql.ResultSet;
    
    public class UserDaoImpl implements IUserDao {
        // 新建用户
        @Override
        public boolean save(User user) {
            // 创建sql语句
            String sql = "insert into user(name, password, avatar_url, sex) values(?,?,?,?)";
            // 使用工具类进行查询
            int result = CRUDTemplate.executeUpdate(sql, user.getUsername(), user.getPassword(), user.getAvatarUrl(), user.getSex());
            return result == 1;
        }
    
        // 根据id删除用户
        @Override
        public boolean delete(Integer id) {
            String sql = "delete from user where id = ?";
            int result = CRUDTemplate.executeUpdate(sql, id);
            return result == 1;
        }
    
        // 根据用户id以及上传的用户信息,进行修改用户信息
        @Override
        public boolean update(Integer id, User user) {
            String sql = "update user set name = ?, password = ?, avatar_url = ?, sex = ? where id = ?";
            int result = CRUDTemplate.executeUpdate(sql, user.getUsername(), user.getPassword(), user.getAvatarUrl(), user.getSex(), id);
            return result == 1;
        }
    
        // 根据id查询单个用户信息
        @Override
        public User get(Integer id) {
            String sql = "select * from user where id = ?";
            return CRUDTemplate.executeQuery(sql, new BeanHandler<User>(User.class), id);
        }
    
        // 根据用户名查询单个用户信息
        @Override
        public User get(String username) {
            String sql = "select * from user where name = ?";
            return CRUDTemplate.executeQuery(sql, new BeanHandler<User>(User.class), username);
        }
    }

    这个就是简单的配置信息,如后续有需要,在添加其他配置。

    github地址:GitHub

    看一下引入的jar包

  • 相关阅读:
    raspberry pi (树莓PI)使用socket向PC发送视频流
    树莓PI交叉编译BOOST库(asio网络例子)
    远程调试树莓PI
    opencv车速检测
    屏蔽同步(JAVA)
    linux常用命令记录
    虚拟机中Ubuntu设置固定IP方法
    java笔记01-反射
    java笔记00-目录
    mysql由于外键关联无法删除数据
  • 原文地址:https://www.cnblogs.com/yangshixiong/p/12234585.html
Copyright © 2020-2023  润新知