看某些同学在那儿做个单表CRUD,半天还不出效果,还那儿调Bug,我的心情啊
就那么一句话,多练,实现多了自然掌握。针对于总有些自认为基础不好的同学,认为是原理没学透,底层没有掌握,所以代码不能出效果, 这时候,我经常跟这些同学打个比喻,来给我解释解释自行车的平衡原理,为什么两条腿在作圆圈运动,两个车轱辘就往前走,还居然不倒?我相信,你百度半天,肯定能找到对应文章,好,你把这些文章组织组织,找个不会骑自行车的人,你让他看,给他讲这个平衡原理,给他看视频,给他说,让他背原理,然后你让他骑,你看他会不会!!!
所以说其实单表CRUD就是经常操作,多写,多出Bug,多DeBug。边实践边总结,那么废话不多说,下面是一贯的怼代码,咱们的目标:不会写代码的厨子不是好司机。让厨子一看也能实现效果
好先来张图说下最终效果的目录结构,一定要瞧好目录结构!!!
要说传统项目就是配置文件最麻烦,但是谁说让你背下来了!!!哎呦。。。
这个工程可以看到一共4个配置文件,6个类文件,还有pom文件一个
pom坐标,这东西你乐意背,你背吧。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.wfb.demo</groupId>
<artifactId>ssh_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<!--看不懂还不百度的,真的,我也没啥好说了-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.37</version>
</dependency>
<!-- 添加Hibernate依赖 -->
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.3.1.Final</version>
</dependency>
<!-- struts2 -->
<!-- https://mvnrepository.com/artifact/org.apache.struts/struts2-core -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.5.14.1</version>
</dependency>
<!-- struts2 spring 整合的核心包-->
<!-- https://mvnrepository.com/artifact/org.apache.struts/struts2-spring-plugin -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>2.5.14.1</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-convention-plugin</artifactId>
<version>2.5.14.1</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>2.5.14.1</version>
</dependency>
<!-- spring -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.6</version>
</dependency>
<!--spring aop包 注释方式使用事务管理 可以不引用-->
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.0</version>
</dependency>
<!-- 添加对数据库的支持 -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.16</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.6.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<!-- 指定端口 -->
<port>8080</port>
<!-- 请求路径 -->
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
其中包括启动就加载的web.xml,
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!--这要是不知道干嘛的,洗洗睡吧,真的-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--hibernate配置级联查询用-->
<filter>
<filter-name>openSessionInView</filter-name>
<filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>openSessionInView</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--struts的核心-->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
还有Spring的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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--包扫描-->
<context:component-scan base-package="cn.wfb"/>
<!--数据库一定设置对-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://192.168.31.210:3306/tests?characterEncoding=utf-8"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">false</prop>
</props>
</property>
<property name="mappingLocations">
<value>classpath:cn/wfb/entity/TScore.hbm.xml</value>
</property>
</bean>
<!-- hibernateTemplate,依赖了sessionFactory -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="scoreDaoImpl" class="cn.wfb.dao.impl.ScoreDaoImpl">
<property name="hibernateTemplate" ref="hibernateTemplate"/>
</bean>
<!-- 3.事务管理器-->
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 4.txAdvice-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="get*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 5.aop-->
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* cn.wfb.service.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
</aop:config>
</beans>
还有Struts的struts.xml
<?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.enable.DynamicMethodInvocation"value="false" /> -->
<!-- 开启开发者模式,作用,页面中报错信息会更加详细,默认false -->
<constant name="struts.devMode" value="true" />
<!-- 指定由spring负责action对象的创建(必选) -->
<constant name="struts.objectFactory" value="spring" />
<!-- 国际化设置,请求参数为utf-8编码(必选) -->
<constant name="struts.i18n.encoding" value="utf-8" />
<!-- 指定被struts2处理的请求后缀类型,如果有多个,用逗号隔开
<constant name="struts.action.extension" value="action" /> -->
<!-- 指定上传文件的大小上限
<constant name="struts.multipart.maxSize" value="209715200" /> -->
<!-- 当配置文件改动后是否重新加载,生产环境下需要设置为false
<constant name="struts.configuration.xml.reload" value="false" /> -->
<!-- 是否使用struts2的开发模式,生产环境下需要设置为false
<constant name="struts.devMode" value="false" /> -->
<!-- 浏览器是否缓存静态内容,生产环境下需要设置为true
<constant name="struts.serve.static.browserCache" value="true" /> -->
<!-- 禁用动态方法调用(即禁用xxx!add.action方式的调用,因为Struts2.1版本开始就不建议这种方式的使用) -->
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<package name="struts2" extends="struts-default,json-default">
<!-- 请求的路径 例如 score_list 对应的Action -->
<action name="score_*" class="scoreAction" method="{1}">
<!-- 允许的几个请求方法名 -->
<allowed-methods>list,add,findOne,update,delete</allowed-methods>
</action>
</package>
</struts>
以及hibernate的映射文件Tscore.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--注意这里设置对应实体类包-->
<hibernate-mapping package="cn.wfb.entity">
<!--类名,表名-->
<class name="TScore" table="t_score" dynamic-insert="true" dynamic-update="true">
<!--hibernate主键生成策略自己百度一下:native, increment,sequence,uuid,assigned,identity -->
<id name="id" column="id">
<generator class="native"/>
</id>
<property name="name" column="name"/>
<property name="subject" column="Subject"/>
<property name="fraction" column="Fraction"/>
</class>
</hibernate-mapping>
下面就是各个类了,好好粘,别弄错了。各位同学们
TScore实体类
package cn.wfb.entity;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* 为什么叫TScore,你想想再问!
*/
@Entity //实体类注解
public class TScore {
@Id //主键注解
private Integer id;
private String name;
private String subject;
private String fraction;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getFraction() {
return fraction;
}
public void setFraction(String fraction) {
this.fraction = fraction;
}
}
dao层接口
package cn.wfb.dao;
import cn.wfb.entity.TScore;
import java.util.List;
public interface ScoreDao {
List<TScore> findAll();
void add(TScore score);
}
dao实现类
package cn.wfb.dao.impl;
import cn.wfb.dao.ScoreDao;
import cn.wfb.entity.TScore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository //这个注解能少吗?
public class ScoreDaoImpl extends HibernateDaoSupport implements ScoreDao {
@Autowired
private HibernateTemplate hibernateTemplate;
@Override
public List<TScore> findAll() {
TScore dept = new TScore(); //可以根据对象条件进行查询
return hibernateTemplate.findByExample(dept);
}
@Override
public void add(TScore score) {
hibernateTemplate.save(score);
}
}
service接口
package cn.wfb.service;
import cn.wfb.entity.TScore;
import java.util.List;
public interface ScoreService {
List<TScore> findAll();
void add(TScore score);
}
service实现类
package cn.wfb.service.impl;
import cn.wfb.dao.ScoreDao;
import cn.wfb.entity.TScore;
import cn.wfb.service.ScoreService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ScoreServiceImpl implements ScoreService {
@Autowired
private ScoreDao scoreDao;
@Override
public List<TScore> findAll() {
return scoreDao.findAll();
}
@Override
public void add(TScore dept) {
scoreDao.add(dept);
}
}
controller类
package cn.wfb.controller;//返回jsp页面采用下面配置
/* Results({}):集合,对应的结果有多个
* Result():一个结果
* name:Action return返回的值
* location:返回结果的页面
*/
import cn.wfb.entity.TScore;
import cn.wfb.service.ScoreService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/*
这种jsp的跳转方式不用了,你要用,自己查资料,这里请求action后返回json字符串,为了前后端分离,哈哈哈
@Results({
@Result(name="success",location="/success.jsp"),
@Result(name="login",location="/login.jsp"),
@Result(name="register",location="/register.jsp")
})*/
@Controller(value = "scoreAction")//用于标注控制层组件(如struts中的action)
@Scope("prototype")//单列模式
@ParentPackage("struts-default")
@Namespace("/")
public class ScoreAction extends ActionSupport {
// 引入Service
@Autowired
private ScoreService scoreService;
//这个实体类和get,set方法是为了接收到请求传入的对象,关于这个需要研究Struts传值问题
//前端采用表单提交方式score.name属性,记得几个属性都要赋值啊。因为数据库属性你自己好好看看!!
private TScore score;
public TScore getScore() {
return score;
}
public void setScore(TScore score) {
this.score = score;
}
@Action(value = "list")
public void list() {
List<TScore> deptList = scoreService.findAll();
//已经不用jsp了,所以考虑返回json数据
write(deptList);
}
@Action(value = "add")
public void add() {
try {
scoreService.add(score);
Map result = new HashMap<>();
result.put("success",true);
result.put("message","add ok");
write(result);
} catch (Exception e) {
e.printStackTrace();
Map result = new HashMap<>();
result.put("success",false);
result.put("message","add error");
write(result);
}
}
/**
* 输出JSON字符串
*
* @param object 写出对象
*/
public void write(Object object) {
//对象转json,并取消循环引用
String jsonString = JSON.toJSONString(object, SerializerFeature.DisableCircularReferenceDetect);
//获取response设置头信息及编码格式
HttpServletResponse response = ServletActionContext.getResponse();
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
try {
//写出
response.getWriter().print(jsonString);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
效果出来了,Bug不要怕,出了Bug我们就可以Debug,多快乐啊,要没有Bug,我们创造Bug,然后集中力量解决Bug!!!这调调熟悉不?
查询,新增,亲测效果如图,童叟无欺。赶紧cv大法试一试吧。马上精通SSH,开心不。
每日论点:
我总能听到,前端好还是后端好,(就跟移动端都死翘翘了一样,哎。。。)。好吧,我只能说,没有后端前端做毛逻辑,前端面对的是产品经理,来看一下,产品经理每天都拽着美术设计干嘛呢~。。
当然产品们跑过来让前端来几套皮肤烘托节日气氛,是常有的事,哈哈哈哈。这时候我奉劝做后端的小伙伴,千万不要鲁莽的评论前端效果的好与坏,反正不是后端写的,还是猥琐发育吧,后端同学们。
折腾完前端的产品经理,碰到出来喝咖啡的后端。。。。
前端光鲜亮丽,后端撅着大腚写逻辑,谁都离不开谁。他们面对产品经理更多一些,毕竟产品耍嘴皮的多不太懂技术。要求图标左右上下的动,有时候还要带旋转效果,再来个奔放红啥的,折腾前端多些。后端被折腾无非就是变态需求来回改,这帮子老改犯的产品。前后端其实都是一帮掉头发的职业玩。。。
支付宝扫一扫得红包
你的支持是我的动力
欢迎关注公众号:魏凡缤Java技术文章