整合SSH(Spring+Struts+Hibernate)

0.前言, 由于工作需要故来学习SSH的整合,structs其实相当于(把view和controller结合起来,没有像现在的前后端分离,请求会发送给Action处理,在structs.xml映射地址和类) Hibernate(就是处理数据库的,几乎自动化,也可以写sql语句)

  1. Struts:Struts 是一个基于 MVC(Model-View-Controller)设计模式的 Web
    应用程序框架。它提供了一个请求处理流程,将请求的参数进行解析,并根据配置文件中的映射规则将请求转发给相应的控制器(Action)。Struts
    还提供了一些标签库和表单验证等功能,简化了开发过程。

  2. Spring:Spring 是一个轻量级的开源框架,用于构建企业级 Java 应用程序。它提供了依赖注入(Dependency
    Injection)、面向切面编程(Aspect-Oriented Programming)等核心功能。在 SSH 框架中,Spring
    负责管理对象的生命周期、依赖关系以及事务管理等。

  3. Hibernate:Hibernate 是一个 Java ORM(Object-Relational Mapping)框架,用于将 Java
    对象与数据库表进行映射。它提供了一种面向对象的方式来操作数据库,屏蔽了底层的数据库细节。通过 Hibernate,开发人员可以使用面向对象的方式进行数据库操作,提高了开发效率。

1.直接gitee下载了项目进行研究

https://gitee.com/yjcode/Spring_Struts_Hibernate_Register/tree/master

2.项目结构
在这里插入图片描述
3.项目初期遇到循环依赖的问题,一个tomcat部署了2个有相同依赖的项目

解决方法:删除多个部署的项目变成下面的样子(或者一个也可以)

在这里插入图片描述
4.项目依赖 spring3+struts2.5+hibernate3.6

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-hibernate -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-hibernate</artifactId>
  <version>1.2.9</version>
</dependency>
<!-- 添加Hibernate依赖 -->
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-core</artifactId>
  <version>3.6.10.Final</version>
</dependency>
<!-- 添加javassist -->
<dependency>
  <groupId>javassist</groupId>
  <artifactId>javassist</artifactId>
  <version>3.12.0.GA</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>3.2.9.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aop</artifactId>
  <version>3.2.9.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-beans</artifactId>
  <version>3.2.9.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>3.2.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jdbc</artifactId>
  <version>3.2.9.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>3.2.9.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-test</artifactId>
  <version>3.2.9.RELEASE</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-test</artifactId>
  <version>3.2.9.RELEASE</version>
  <scope>compile</scope>
</dependency>
<!--struts依赖-->
<dependency>
  <groupId>org.apache.struts</groupId>
  <artifactId>struts2-core</artifactId>
  <version>2.5.14.1</version>
</dependency>
<dependency>
  <groupId>org.apache.struts</groupId>
  <artifactId>struts2-spring-plugin</artifactId>
  <version>2.5.20</version>
</dependency>

<!--数据库 mysql 驱动-->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.0.7</version>
</dependency>
<!--切面依赖-->
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjrt</artifactId>
  <version>1.7.4</version>
</dependency>
<dependency>
  <groupId> org.aspectj</groupId >
  <artifactId> aspectjweaver</artifactId >
  <version> 1.6.11</version >
</dependency>

5.怎么使用

1.写structs配置文件,后期可以使用注解优化

 //class对应的是bean的名字/类的全限定名称com.jamsee.XXClassName

//result对应的是函数返回String的标志 或者数据
//name对应可以访问 http://localhost:8090/listProduct 或者listProduct.action
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
//测试成功

在这里插入图片描述

2.怎么在页面使用EL表达式,并且循环遍历

${products[1].id}
<s:iterator value="products" var="p">
    <tr>
        <td>${p.id}</td>
        <td>${p.name}</td>
        <td>${p.price}</td>
        <td><a href="editProduct?product.id=${p.id}">edit</a></td>
        <td><a href="deleteProduct?product.id=${p.id}">delete</a></td>
    </tr>
</s:iterator>

//会调用action的方法,完成成员的变化,思路确实比较清晰,可是我要的数据如果是一次性的呢?不放在成员里面呢? 可以每次删除设置为空
在这里插入图片描述

3.怎么国际化(一直困扰我的问题,怎么已经从中文切换到英文,其实应该是前端做的,但是后端来做该怎么做)
//遇到的坑,直接创建国际化文本文件,一系列操作还是乱码,我直接写个类插入到成员变量里面,页面直接可以使用,后期可以改造成为自动注入解决乱码问题

在这里插入图片描述

在这里插入图片描述

public class ProductAction3 extends ActionSupport {
    ResourceBundle rb;
    @Override
    public String execute() throws Exception {
        Locale defaultLocale = Locale.getDefault();
        System.out.println("default country:" + defaultLocale.getCountry());
        System.out.println("default language:" + defaultLocale.getLanguage());
        //自定义本地化信息
        Locale currentLocale = new Locale("zh", "CN");
        // 定位到国际化文件,国际化资源文件名由basename+Locale组成:如MessagesBundle_zh_CN.properties,basename为任意合法名字
        ResourceBundle rb = ResourceBundle.getBundle("messages",currentLocale, new UTF8Control());
        //读取文件中的值
         System.out.println(rb.getString("k1"));
         System.out.println(rb.getString("k2"));
        this.setRb(rb);
        return SUCCESS;
    }

    public ResourceBundle getRb() {
        return rb;
    }

    public void setRb(ResourceBundle rb) {
        this.rb = rb;
    }
}

//工具类

/**
 * @author jams
 * @Type UTF8Control.java
 * @Desc
 * @date 2023/12/18 17:12
 */
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.*;

public class UTF8Control extends ResourceBundle.Control {

    @Override
    public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException {
        String bundleName = toBundleName(baseName, locale);
        String resourceName = toResourceName(bundleName, "properties");
        InputStream stream = null;
        if (reload) {
            URL url = loader.getResource(resourceName);
            if (url != null) {
                URLConnection connection = url.openConnection();
                if (connection != null) {
                    // 使用 UTF-8 编码读取资源文件
                    connection.setUseCaches(false);
                    stream = connection.getInputStream();
                }
            }
        } else {
            // 使用 UTF-8 编码读取资源文件
            stream = loader.getResourceAsStream(resourceName);
        }
        if (stream != null) {
            try (Reader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) {
                return new PropertyResourceBundle(reader);
            }
        }
        return super.newBundle(baseName, locale, format, loader, reload);
    }
}

/**
 * Revision history
 * -------------------------------------------------------------------------
 * <p>
 * Date Author Note
 * -------------------------------------------------------------------------
 * 2023/12/18 用户名 create
 */ 

//list.jsp写
<s:property value=“rb.getString(‘k1’)” /> // 得到国际化的文本,后端工具传过来的请求
//问题: 后端怎么知道是哪个国家? 答案: 请求的全部数据放ctx中,传请求过来可以拿到,代码如下
//前端
href=“product.action?locale=en_US”
href=“product.action?locale=zh_CN”

@Override
public String execute() throws Exception {
    ActionContext ctx = ActionContext.getContext();
    
    // 获取前端传递的区域信息
    String localeString = ctx.getParameters().get("locale").getValue();
    
    // 解析区域信息,设置 Locale 对象
    String[] localeParts = localeString.split("_");
    Locale currentLocale = new Locale(localeParts[0], localeParts[1]);
    
    // 定位到国际化文件,国际化资源文件名由basename+Locale组成:如MessagesBundle_zh_CN.properties,basename为任意合法名字
    ResourceBundle rb = ResourceBundle.getBundle("messages", currentLocale, new UTF8Control());
    
    // 读取文件中的值
    String k1 = rb.getString("k1");
    String k2 = rb.getString("k2");
    
    this.setRb(rb);
    
    return SUCCESS;
}
    

4.hibernate怎么使用?
//写配置文件的表和字段名和类型,不存在表会自动创建,其实高版本可以使用@Table来指定的,更方便

	<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="pojo">
    <class name="Product" table="product_h">
        <id name="id" column="id">
            <generator class="native">
            </generator>
        </id>
        <!--version元素必须紧挨着id后面  -->
      <!--  <version name="version" column="ver" type="int"></version>-->
        <property name="name"/>
        <property name="price" column="price"/>
        <!--<many-to-one name="category" class="Category" column="cid" />
        <set name="users" table="user_product" lazy="false">
            <key column="pid" />
            <many-to-many column="uid" class="User" />
        </set>-->
    </class>

</hibernate-mapping>

//继承一下HibernateTemplate,增删改查方法如下

  @Component("productDAOImpl")
public class ProductDAOImpl extends HibernateTemplate implements ProductDAO2{
    @Autowired
    private SessionFactory sf;
    public List<Product> list() {
        return find("from Product");  //sql语句在这里写真香!!! 不过会sql注入攻击
    }

    @Override
    public void add(Product p) {
        save(p);
    }

    @Override
    public Product getP(Class<Product> productClass, int id) {
        return (Product)get(productClass,id);
    }

    @Override
    public void deleteP(Product p) {
        delete(p);
    }

    @Override
    public void updateP(Product p) {
        update(p);
    }


}

//使用自己的sql进行查询(下面事务可以不写,因为我们在spring开启了)

@Autowired
private SessionFactory sessionFactory;

public List<Product> customQuery() {
    //相当于预编译语句
    String sql = "SELECT * FROM products WHERE price > :price";
    Session session = sessionFactory.getCurrentSession();
    Transaction tx = null;
    List<Product> products = null;

    try {
        tx = session.beginTransaction();
        //这里开始看
        SQLQuery query = session.createSQLQuery(sql);
        query.addEntity(Product.class);
        query.setParameter("price", 100);
        products = query.list();
        tx.commit();
    } catch (Exception e) {
        if (tx != null) {
            tx.rollback();
        }
        e.printStackTrace();
    } finally {
        session.close();
    }

    return products;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/254661.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大数据服务与低代码开发:赋能创新与效率的双剑合璧

在科技飞速发展的当下&#xff0c;数据已经渗透到了企业的方方面面&#xff0c;成为了企业决策和业务发展的重要依据。海量数据的处理和分析&#xff0c;对于企业来说既是机遇&#xff0c;也是挑战。传统的数据处理方式往往无法满足快速变化的市场需求&#xff0c;而繁琐的开发…

AI摄影绘画与PS优化:重塑数字艺术的未来

文章目录 《AI摄影绘画与PS优化从入门到精通》内容简介作者简介楚天 目录前言/序言 在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;已经渗透到我们生活的各个领域&#xff0c;包括艺术创作。AI摄影绘画和Photoshop&#xff08;PS&#xff09;优化是这个领…

Numpy、Pandas常用函数

目录 Numpy 核心功能 常用函数 运算实例 Pandas 核心功能 常用函数 统计汇总函数 数据清洗函数 数据筛选 绘图与元素级函数 时间序列函数 其他函数 Numpy 官方文档&#xff1a;NumPy: the absolute basics for beginners — NumPy v1.26 Manual NumPy&#xff0…

vue3 +TS + vite + SVG

如何在如题的项目中使用svg&#xff1f; 我当时首先想到的是 搬运vue2 中svg的使用方式&#xff0c;安装svg-sprite-loader 和做相应的封装。(vue2 svg)你会发现 行不通&#xff0c;因为本项目使用的是vite 构建的无法使用Webpack所以如下代码不执行的 // 自动化加载 // webp…

Mysql高可用|索引|事务 | 调优

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 文章目录 前言sql语句的执行顺序关键词连接名字解释sql语句 面试坑点存储引擎MYSQL存储引擎 SQL优化索引索引失效索引的数据结构面试坑点 锁事务四大特性事务的隔离级别MVCC 读写分离面试坑…

大师学SwiftUI第12章 - 手势 Part 1

手势识别器 手势是用户在屏幕上执行的动作&#xff0c;如点击、滑动或捏合。这些手势很难识别&#xff0c;因为屏幕上只能返回手指的位置。为此&#xff0c;Apple提供了手势识别器。手势识别器完成所有识别手势所需的计算。所以我们不用处理众多的事件和值&#xff0c;只需在等…

公共字段自动填充——后端

场景&#xff1a;当处理一些请求时&#xff0c;会重复的对数据库的某些字段进行赋值&#xff08;如&#xff1a;在插入和更新某个物品时&#xff0c;需要更新该物品的更新时间和更新者的信息&#xff09;&#xff0c;这样会导致代码冗余。 如&#xff1a; 思路&#xff1a; 自…

避免付费搜索广告系列与有机搜索广告系列之间出现关键词蚕食现象

自然搜索&#xff08;搜索引擎优化&#xff09;和付费搜索&#xff08;或按点击付费&#xff09;具有足够的技术复杂性和战略方面。 关键词蚕食是一个可能使它们变得更加困难的问题——如果你的搜索引擎优化 &#xff08;SEO&#xff09; 和按点击付费 &#xff08;PPC&#x…

【Python】获取B站粉丝列表保存至数据库中

分析网络请求&#xff0c;获取到有粉丝接口的数据url 可以在响应信息处看到粉丝的信息 通过浏览器也可以直接请求到具体的JSON信息 通过独立的标签我们可以看到接口数据&#xff0c;但是要注意如果不是查看自己登录账户的接口那么就无法查询到所有粉丝的数据&#xff0c;默认只…

Python通过函数名调用函数的几种场景

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 除了执行系统命令外&#xff0c;我们有时还需要动态地执行一些python代码&#xff0c;有经验的朋友就会知道可以使用内置函数eval实现这一需求&#xff0c;如eval(“…

Appcelerator打包ipa有哪些优势

大家好&#xff0c;我是咕噜-凯撒&#xff0c;我们得先知道Appcelerator是啥&#xff0c;Appcelerator&#xff08;现在更名为Axway Titanium&#xff09;是一个跨平台的移动应用开发框架通过提供一种简化和加速移动应用开发的方式帮助你构建高质量的跨平台应用程序。那使用App…

【基础篇】YOLO系列训练环境(GPU)搭配篇

🚀Pytorch环境配置(Windows) 🔨 Anaconda安装 此处下载安装即可 ⭐温馨提示:安装路径不能含有中文,建议不要安在c盘(很占内存) 环境变量配置 编辑系统环境变量 -> 环境变量 -> 系统变量 新建并添加以下路径 打开cmd,输入conda&

设计模式—装饰模式

与其明天开始&#xff0c;不如现在行动&#xff01; 文章目录 装饰模式—穿衣服&#x1f48e;总结 装饰模式—穿衣服 装饰模式&#xff08;Decorator&#xff09;可以动态的给对象添加一些额外的职责。 Component是定义一个对象接口&#xff0c;可以给这些对象动态地添加职责。…

【深度学习目标检测】十、基于yolov5的火灾烟雾识别(python,目标检测)

YOLOv5是目标检测领域一种非常优秀的模型&#xff0c;其具有以下几个优势&#xff1a; 1. 高精度&#xff1a;YOLOv5相比于其前身YOLOv4&#xff0c;在目标检测精度上有了显著的提升。YOLOv5使用了一系列的改进&#xff0c;如更深的网络结构、更多的特征层和更高分辨率的输入图…

Vditor - Markdown编辑器使用

1、安装 yarn add vditor2、代码 import vditor/dist/index.css; import React, { useEffect } from react; import Vditor from vditor; import ./index.less;const App ({ setVditorValue, vditorValue }: any) > {const [vd, setVd] React.useState<Vditor>();…

Redis-网络模型

参考资料 &#xff1a;极客时间 Redis&#xff08;亚风&#xff09; 前置知识 系统隔离 为了避免⽤户应⽤导致冲突甚⾄内核崩溃&#xff0c;⽤户应⽤与内核是分离的&#xff1a; 进程的寻址空间会划分为两部分&#xff1a;内核空间、⽤户空间 • ⽤户空间只能执⾏受限的命令&…

激活函数-SwiGLU

SwiGLU SiLU 函数是一种神经网络中的激活函数&#xff0c;全称是 Sigmoid Linear Unit, 也被称为 Swish 函数。它由 Google Brain 在 2017 年提出&#xff0c;是一种非线性激活函数&#xff0c;能够有效地对神经网络的输入进行非线性变换。 定义 f ( x ) x ∗ σ ( x ) f(x)…

vue3使用vue-router嵌套路由(多级路由)

文章目录 1、Vue3 嵌套路由2、项目结构3、编写相关页面代码3.1、编写route文件下 index.ts文件3.2、main.ts文件代码&#xff1a;3.3、App.vue文件代码&#xff1a;3.4、views文件夹下的Home文件夹下的index.vue文件代码&#xff1a;3.5、views文件夹下的Home文件夹下的Tigerhh…

生命在于学习——TV电视盒子渗透测试抓包设置

一、前言 封面图是示例图&#xff0c;因为涉及到保密&#xff0c;所以本次测试的电视盒子不放出外观和设置界面。 这一次要测试电视盒子&#xff0c;大家也都知道&#xff0c;市面上的电视盒子大部分都是Android&#xff0c;当然&#xff0c;要使用笔记本去抓电视盒子的数据包…

圣诞节来了,为大家送上专属圣诞树

Hello大家好&#xff0c;我是Dream。 今天给大家分享一下我很早之前做过的圣诞树&#xff0c;分享给大家&#xff0c;希望可以帮助到大家度过一个浪漫的圣诞节~ Python打造专属于你的圣诞树落叶雪花背景音乐浪漫弹窗 五合一版圣诞树 一、背景故事圣诞节风波❤️❤️❤️ 二、五…