【ssh框架+mysql :多表并联查询】餐厅点菜例子

本文通过一个餐厅点菜的例子,演示如何使用SSH框架(Struts2、Spring、Hibernate)结合MySQL进行多表并联查询。在场景中,一个客人创建多张订单,每张订单对应多个菜品。SSH框架的四个包(action、service、dao、entity)分工明确,实体类包括主表Order和子表Menu。通过配置文件和数据库操作,实现了数据的增删和孤儿数据的处理,展示了SSH框架在多表查询中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   

   假如一个餐厅中有一个客人A 请了 一大群朋友来吃饭,

开了三张桌子,创建三张订单,就是订单三张表table (父),明细表为:菜单table(子);

炒出来的菜分别往不同的 餐桌上送。

忽然有些朋友有事情要走了,一个订单废弃,炒的菜取消,这个称为:数据孤儿




ssh框架,跟以往一样,分四个包:

action :控制层,service:业务逻辑处理层;

dao :数据库连接层;entity :实体类

不同以往,有2个实体类,一个子,一个父。

改变:我们将不再写mysql,让实体类注入,自动写mysql;


lib目录的 ssh框架 的jar包,请到我之前发的 百度云 下载 或者自行配置。

index.jsp: 主页只有一个 index 用来测试 是否成功。无关紧要。

web.xml 的配置没有变。

代码如下:

order.entity 实体类 Order.java (主表,父表)

@OneToMany(mappedBy="order",cascade={CascadeType.ALL},fetch=FetchType.EAGER)
这个注解联系2个实体类

package order.entity;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

@Entity //实体类注解
@Table(name = "t_order") //告知调用者,sql的表名
public class Order {

	private Integer id;// 主键
	private Integer pCount;// 人数
	private Date pubDate;//日期
	
	
	
	private Set<OrderItem> orderItems = new HashSet<OrderItem>();
	
	@OneToMany(mappedBy="order",cascade={CascadeType.ALL},fetch=FetchType.EAGER)
	public Set<OrderItem> getOrderItems() {
		return orderItems;
	}
	public void setOrderItems(Set<OrderItem> orderItems) {
		this.orderItems = orderItems;
	}
	
	
	
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	
	@Column(name="p_Count",nullable=false)
	public Integer getpCount() {
		return pCount;
	}
	public void setpCount(Integer pCount) {
		this.pCount = pCount;
	}
	
	@Column(name="pub_Date",nullable=false)
	public Date getPubDate() {
		return pubDate;
	}
	public void setPubDate(Date pubDate) {
		this.pubDate = pubDate;
	}

}

OrderItem.java 第二个实体类(从表,点菜表,子表)

@ManyToOne(cascade={CascadeType.ALL},optional=true,fetch=FetchType.EAGER)
这个注解让2个表联系起来。

package order.entity;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "t_order_item")
public class OrderItem {

	private Integer id;//主键
	private String detailDesc;//明细描述
	private Integer price;//单价
	private Integer cCount;//数量
	//错误演示
	//private Integer order_id;
	
	private Order order;
	
	@ManyToOne(cascade={CascadeType.ALL},optional=true,fetch=FetchType.EAGER)
	@JoinColumn(name="orderid")
	public Order getOrder() {
		return order;
	}
	public void setOrder(Order order) {
		this.order = order;
	}
	
	
	
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	
	@Column(name="detail_desc",nullable=false,length=50)
	public String getDetailDesc() {
		return detailDesc;
	}
	public void setDetailDesc(String detailDesc) {
		this.detailDesc = detailDesc;
	}
	
	@Column(name="price",nullable=false)
	public Integer getPrice() {
		return price;
	}
	public void setPrice(Integer price) {
		this.price = price;
	}
	
	@Column(name="c_count",nullable=false)
	public Integer getcCount() {
		return cCount;
	}
	public void setcCount(Integer cCount) {
		this.cCount = cCount;
	}
	
}


order.action 层:OraerAction.java

我们只有一个显示的方法,哈哈。

<span style="font-size:18px;">package order.action;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.ActionSupport;

import order.service.OrderService;

@SuppressWarnings("serial")  //取消类警告的注解
@Controller  //控制层的注解
@Scope("prototype")  //非单例注解
public class OrderAction extends ActionSupport {
	
	@Autowired
	private OrderService orderService;
	
	public String getAllOrder(){
		orderService.getAllOrder();
		return "ok1";
	}

}</span>

order.service层 OrderService.java 接口

<span style="font-size:18px;">package order.service;

import java.util.List;

import order.entity.Order;

public interface OrderService {
	public List<Order> getAllOrder();
}</span>

order.service层 OrderServiceImpl.java 接口

<span style="font-size:18px;">package order.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import order.dao.OrderDao;
import order.entity.Order;

@Transactional
@Service
@Scope("prototype")
public class OrderServiceImpl implements OrderService {

	@Autowired
	private OrderDao orderDao;
	
	@Override
	public List<Order> getAllOrder() {
		
		return orderDao.getAllOrder();
	}

}</span>

orderdao层 OrderDao 接口

<span style="font-size:18px;">package order.dao;

import java.util.List;

import order.entity.Order;

public interface OrderDao {
	public List<Order> getAllOrder();
}</span>


orderdao层 OrderDaoImpl ;

我们在 daoImpl,直接往mysql 建database,建table ,插入数据信息!

package order.dao;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;

import order.entity.Order;
import order.entity.OrderItem;
@Repository  //数据库访问层注解
@Scope("prototype") //非单例注解
public class OrderDaoImpl implements OrderDao {

	@Autowired
	private SessionFactory sessionFactory;
	
	
	//删除主表(  删除儿子    )
	public List<Order> getAllOrder() {
		Session session = sessionFactory.getCurrentSession();
		Order order1 = session.get(Order.class,1);
		session.delete(order1);
		
		return new ArrayList<Order>();
	}
	
	
	//删除从表(删除儿子)
	public List<Order> getAllOrder4() {
		Session session = sessionFactory.getCurrentSession();

		OrderItem o1 = session.get(OrderItem.class,2);
		
		//解除父子关系(1.先老爸不认儿子,2.儿子也不认老爸),从此小孩变成一个孤儿
		o1.getOrder().getOrderItems().remove(o1);
		o1.setOrder(null);
		
		
		session.delete(o1);
		
		
		
		
		return new ArrayList<Order>();
	}
	
	//从 明细表(从表)反过来获取主表信息
	public List<Order> getAllOrder3() {
		Session session = sessionFactory.getCurrentSession();
		OrderItem o1 = session.get(OrderItem.class,2);
		System.out.println("从表信息--描述:"+ o1.getDetailDesc());	
		Order order1 = o1.getOrder();
		System.out.println("主表信息--日期:"+ order1.getPubDate());
		
		return new ArrayList<Order>();
	}
	
	
	//测试从主表获得从表信息
	public List<Order> getAllOrder2() {
		Session session = sessionFactory.getCurrentSession();
		
		//搜索出1条order对象(1个对象),生成出一个left outer join sql语句,返回2条记录,
		//并且hibernate自动把这2条记录,封装到order对象中的orderItems这个set对象里面存放
		Order order1 = session.get(Order.class,1);
		System.out.println("主表信息--日期:"+order1.getPubDate());
		
		Set<OrderItem> orderItems = order1.getOrderItems();
		for (OrderItem item : orderItems) {
			System.out.println("   从表信息--描述:"+ item.getDetailDesc());	
		}
		
		
		
		
		return new ArrayList<Order>();
	}
	
	//测试添加数据
	public List<Order> getAllOrder1() {

		Session session = sessionFactory.getCurrentSession();
		
		//订单
		Order order1 = new Order();
		order1.setpCount(4);
		order1.setPubDate(new Date());
		
		//明细中菜1
		OrderItem o1 = new OrderItem();
		o1.setcCount(15);
		o1.setPrice(13);
		o1.setDetailDesc("炒菜心");
		
		//明细中菜2
		OrderItem o2 = new OrderItem();
		o2.setcCount(15);
		o2.setPrice(13);
		o2.setDetailDesc("麻婆豆腐");
		
		//配置关系
		order1.getOrderItems().add(o1);
		order1.getOrderItems().add(o2);
		o1.setOrder(order1);
		o2.setOrder(order1);
		
		
		//保存
		session.save(order1);
		//session.save(o1);
		//session.save(o2);
		
		return new ArrayList<Order>();
	}

}

要注意:菜单(从表,子表)可以增减,但是餐桌(主表,父类)可不能随便增减!


applicationContext.xml 这个作用巨大哦!

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="    
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd  
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd  
			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
			http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd  
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">

	<!-- 原理:自动注入processor解析器,用来解析注解 -->
	<!-- <context:annotation-config/> -->

	<!-- 自动扫描包,也会自动注入解释器,所以不需要 context:annotation-config -->
	<context:component-scan base-package="order"></context:component-scan>


	<!-- 引入外部属性文件 -->
	<context:property-placeholder location="classpath:jdbc.properties" />

	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
		<!-- 注入连接池,包含了数据库用户名,密码等等信息 -->
		<property name="dataSource" ref="myDataSource" />

		<!-- 配置Hibernate的其他的属性 -->
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.format_sql">true</prop>
				<prop key="hibernate.connection.autocommit">false</prop>
				<!-- 开机自动生成表 -->
				<prop key="hibernate.hbm2ddl.auto">update</prop>
			</props>
		</property>
		<property name="mappingResources">
			<list>
				
			</list>
		</property>
		
		<property name="packagesToScan">
			<list>
				<value>order.*</value>
			</list>
		</property>

	</bean>

	<bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driver}" />
		<property name="jdbcUrl" value="${jdbc.url}" />
		<property name="user" value="${jdbc.user}" />
		<property name="password" value="${jdbc.password}" />
		<!-- 每300秒检查所有连接池中的空闲连接 -->
		<property name="idleConnectionTestPeriod" value="300"></property>
		<!-- 最大空闲时间,900秒内未使用则连接被丢弃。若为0则永不丢弃 -->
		<property name="maxIdleTime" value="900"></property>
		<!-- 最大连接数 -->
		<property name="maxPoolSize" value="2"></property>

	</bean>

	<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>

	<tx:annotation-driven transaction-manager="transactionManager"/>


</beans>
			

jdbc.properties 这个是文本的形态(txt)

用来给不懂代码的人配置不同的sql的,这里还是2套数据库:mysql , oracle 

数据库名:news ,表2个:t_order;t_order_item 

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/news
jdbc.user=root
jdbc.password=


#oracle
jdbc_oracle.driver=oracle.jdbc.driver.OracleDriver
jdbc_oracle.url=jdbc:oracle:thin@127.0.0.1:1521:orcl
jdbc_oracle.user=news
jdbc_oracle.password=

struts.xml 这里有着所有的方法

这里只有:显示成功,删除成功2个

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
	<constant name="struts.objectFactory" value="spring" />

<!-- 第1步:先定义一个包 -->
	<package name="mypck001" extends="struts-default">
		<action name="OrderAction_*" class="orderAction" method="{1}">
			<result name="ok1">/WEB-INF/jsp/index.jsp</result>
			<!-- 希望删除成功后,重新执行1次首页显示内容 -->
			<result name="deleteOK" type="redirectAction">NewsAction_showAllNews.action?message=deleteok&id=${id}</result>
		</action>
		
	</package>
</struts>


web.xml 每次都一样:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>news</display-name>
  <welcome-file-list>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
</web-app>


default.jsp 重定向跳转,调用action层 显示数据方法。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	response.sendRedirect("OrderAction_getAllOrder.action");
%>


运行项目


启动mysql

查询一下,发现mysql已经有了信息



而且 2个表示连接起来的。

说明我们已经完成 多表并联了。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值