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包

原文地址:https://www.cnblogs.com/yangshixiong/p/12234585.html

时间: 2024-12-12 08:49:45

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

spring项目篇13 --- 网上商城之登陆注册

首先我们这次使用的是jwt来实现的登陆认证,首先看一下需要引入的jar包 尤其是commons-codec这个包,一定要引入,否则会报binary那个包的错误,因为找不到方法,另外不要使用那个结尾是20... 就是那个最新的这个包,会出错,找了好半天这个错误... 首先说一下基本思想,就是通过拦截器将我们的login以及rgister与静态文件放行,其余的检测是否携带token,并对token进行检测,合格之后在进行放行. 接下来直接看源码 首先看一下我们的spring配置补充的,因为没有使用r

iOS开发项目篇—12搜索框的封装

iOS开发项目篇—12搜索框的封装 一.在“发现”导航栏中添加搜索框 1.实现代码 1 #import "YYDiscoverViewController.h" 2 3 @interface YYDiscoverViewController () 4 5 @end 6 7 @implementation YYDiscoverViewController 8 9 - (void)viewDidLoad 10 { 11 [super viewDidLoad]; 12 13 //添加搜索框

SSH网上商城环境配置—浅析Hibernate

SSH网上商城虽然只有四天的视频,day01-04,不过边做项目边学习,还真是不容易,到现在为止已经进行了半个月了,才完成了两天的内容.其中光一个环境配置就花了十天左右的时间,包括配置文件添加.Jar包的添加等等.敲代码时再加上对开发环境的陌生,着实费了不少劲,调试也花费了好长时间,不过还好,现在已经熟悉一点了,做起来也顺手一些了,下面就简单汇总一下这里面用到的技术. SSH是集成框架,它是从三层的基础上发展而来的.三层中包括页面显示层.业务逻辑层.数据库操作层,SSH中同样也是,只不过每个层使

spring项目篇2----编写配置文件

我们接下来开始编写我们的权限系统,以便进一步熟悉SSM,接下来按照第一篇起一个maven项目,项目简介如下,接下来看一下配置文件 web.xml <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app xmlns="http:/

spring项目篇14 --- 编写商品展示以及购物车信息

肺炎形势严峻,人心惶惶,愿祖国早日解决,社会早点稳定. 这次主要实现的功能就是商品展示以及购物车,购物车信息保存在mysql数据库中.我们先来看商品数据库层 // IProductDao package com.yang.dao; import com.yang.domain.Product; import java.util.List; public interface IProductDao { // 获取商品 List<Product> getList(); // 获取单个商品 Prod

通过“分布式系统的8大谬误”反思APP的设计 第八篇 谬误8:网络配置都是类似的

谬误8:网络配置都是类似的. 相对于web开放来讲,移动设备总是让人出乎预料.对一个应用来说,可能大多数用户所处的网络配置都类似.不幸的是,这个假设的会在某些情况下导致一些问题. 类似谬误6,不是所有的网络都有相同的配置.例如,某些wifi网络允许设备之间建立点对点的通信,有些却不支持.让移动app与其他设备通信(比方,与桌面软件)可能因此非常困难,即使它们身处同个网络内. TN2152 "传输文件的一些策略"简要总结了一些设备之间,以及远程服务之间通信的技术. 一个web服务最开始可

Memcached的配置,SSH项目中的整合(com.whalin),Memcached工具类,Memcached的代码调用

?? 1 改动pom.xml,加入依赖文件: <dependency> <groupId>com.whalin</groupId> <artifactId>Memcached-Java-Client</artifactId> <version>3.0.2</version> </dependency> 2 加入memcached-context.xml,注意要在web.xml中进行配置 <?xml ver

spring项目篇15 --- 商城小项目创建订单以及查看所有订单

深圳肺炎患者突破80了,现在心里慌慌的,不知什么时候返深啊...既来之,则安之! 今天,这个简单的小项目最后一步,创建订单以及查看所有订单状态,我们的订单只需要点击一下付款即可完成支付,没有接入第三方支付.下面计划开始学习mybatis. 因为大多是业务代码,我们直接看就可以 先看dao层,在创建订单的时候,因为设计多表操作,因此需要开启事务 // IOrderDao package com.yang.dao; import com.yang.domain.Car; import com.yan

spring项目篇3----编写用户展示模块

第一步创建两张数据库表 员工表: 部门表: 第二步: 使用之前配置的mybatis-generator自动从数据库中生成pojo类与mapper映射文件 首先在配置文件中添加我们的表信息 <!--指定生成那个表--> <table tableName="employee" /> <table tableName="department" /> 之后点击运行 在java.com.yang.mapper包中的xml文件需要移动到res