1. 事务属性
1.1 事务传播属性
配套视频:【编程不良人】快速入门Spring,SpringBoot、SpringCloud学不好完全是因为Spring没有掌握!_哔哩哔哩_bilibili
# propagation: 传播 REQUIRED: 需要事务,如果外部存在事务,则融入当前事务; 【常用】 如果外部没有事务,则开启新的事务 使用:默认为REQUIRED,主要用于增删改方法) SUPPORTS: 支持事务,如果外部存在事务,则融入当前事务; 【常用】 如果外部没有事务,不开启新的事务 使用:主要用于查询方法,一般查询方法都配置上SUPPORTS,保证事务的正常传播 REQUIRES_NEW: 每次开启新的事务,如果外部存在事务,外部事务挂起,自己开启新的事务运行,运行结束后恢复外部事务,外层事务继续执行(外层事务如果存在需要等待,内外相当于两个连接对象,互不影响,存在等待阻塞状态) 【常用,银行数据系统,交易记录】 NOT_SUPPORTED: 不支持事务,如果外部存在事务,则外部事务挂起,自己以非事务方式运行,执行完成恢复外部事务运行 【常用】 NEVER: 不支持事务,存在事务报错 【不常用】 MANDATORY: 强制事务,没有事务报错 【不常用】 NESTED: 嵌套事务,事务之间可以嵌套运行,部分数据库不支持,如MySQL、Oracle 【不常用】
1.2 事务的隔离级别
配套视频:【编程不良人】快速入门Spring,SpringBoot、SpringCloud学不好完全是因为Spring没有掌握!_哔哩哔哩_bilibili
# isolation: 事务隔离级别 以下由低到高: DEFAULT: 使用数据库默认的隔离级别 [推荐] READ_UNCOMMITTED: 读未提交 一个客户端读到了另一个客户端没有提交的数据 脏读现象 READ_COMMITTED : 读提交 一个客户端只能读到另一个客户端提交的数据 避免脏读现象 【oracle默认隔离级别,MySQL不会出现脏读现象】 REPEATABLE_READ : 可重复读 主要是用来避免不可重复读现象出现(在一次事务中一方更新,导致两次查询结果不一致这种情况叫不可重复读) 行锁 【mysql默认隔离级别】 SERIALIZABLE: 序列化读 主要是用来避免幻影读现象出现(在一次事务中一方插入,导致两次查询结果不一致这种情况叫幻影读) 表锁 注意: 隔离级别越高,查询效率越低 一般推荐使用数据库默认隔离级别 MySQL>Oracle
1.3 读写和异常性
# read-only :事务读写性 true 只读 不能执行增删改操作(mysql支持 oralce不支持) false: 可读可写 示例: `true: 本次事务只读 `false: 本次事务非只读 <tx:method name="save*" propagation="REQUIRES_NEW" read-only="true|false" isolation="SERIALIZABLE"/> # rollback-for: 出现什么类型异常回滚 默认出现RuntimeException及其子类异常回滚 示例: rollback-for: 遇到什么类异常回滚 no-rollback-for: 遇到什么类异常不回滚 <tx:method name="save*" rollback-for="" no-rollback-for="" propagation="REQUIRES_NEW" read-only="true" isolation="SERIALIZABLE"/> # no-rollback-for: 出现什么类型异不回滚 java.lang.RuntimeException,也可自定义异常 示例: # timeout: 事务超时性 当设置-1时表示永不超时【默认】 当设置为>=0的正整数时,代表设置了超时时间,单位:秒 【设置=0时,表示不等待】
2. Struts2框架测试
配套视频:【编程不良人】快速入门Spring,SpringBoot、SpringCloud学不好完全是因为Spring没有掌握!_哔哩哔哩_bilibili
2.1 新建maven-webapp项目
main目录下新建java、resources目录
2.2 pom.xml导入依赖
<!--spring核心及相关依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.3.2.RELEASE</version> </dependency> <!--struts2-core--> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.3.16</version> </dependency>
2.3 java目录下新建com.study.action.UserAction.java组件
package com.study.action; import com.opensymphony.xwork2.Action; /** * @ClassName UserAction * @Description TODO * @Author Jiangnan Cui * @Date 2022/4/13 9:43 * @Version 1.0 */ public class UserAction { public String hello(){ System.out.println("hello spring struts2"); return Action.SUCCESS; } }
2.4 resources下新建struts.xml,管理Action组件
<?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> <package name="user" extends="struts-default" namespace="/user"> <action name="hello" class="com.study.action.UserAction" method="hello"> <result name="success">/index.jsp</result> </action> </package> </struts>
2.5 在webapp/WEB-INF下的web.xml中添加filter
<!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> <display-name>Archetype Created Web Application</display-name> <!--filter--> <filter> <filter-name>struts</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
2.6 部署Tomcat进行测试
Add Configuration...--> + -->Tomcat Server-->Local,配置相关参数(通过Artifact导入spring_struts2:war exploded),注意自己的8080端口被占用,此处使用8888端口进行测试
启动服务进行测试,出现下面的提示表示项目启动成功:
D:\Software_Development\IDEA_code\apache-tomcat-8.5.73-windows-x64\apache-tomcat-8.5.73\bin\catalina.bat run [2022-04-13 10:27:16,424] Artifact spring_struct2:war exploded: Waiting for server connection to start artifact deployment... Using CATALINA_BASE: "C:\Users\cjn\AppData\Local\JetBrains\IntelliJIdea2020.1\tomcat\Unnamed_spring_struct2" Using CATALINA_HOME: "D:\Software_Development\IDEA_code\apache-tomcat-8.5.73-windows-x64\apache-tomcat-8.5.73" Using CATALINA_TMPDIR: "D:\Software_Development\IDEA_code\apache-tomcat-8.5.73-windows-x64\apache-tomcat-8.5.73\temp" Using JRE_HOME: "D:\Software_Development\JDK" Using CLASSPATH: "D:\Software_Development\IDEA_code\apache-tomcat-8.5.73-windows-x64\apache-tomcat-8.5.73\bin\bootstrap.jar;D:\Software_Development\IDEA_code\apache-tomcat-8.5.73-windows-x64\apache-tomcat-8.5.73\bin\tomcat-juli.jar" Using CATALINA_OPTS: "" ...... Connected to server [2022-04-13 10:27:18,026] Artifact spring_struct2:war exploded: Artifact is being deployed, please wait... ...... [2022-04-13 10:27:20,164] Artifact spring_struct2:war exploded: Artifact is deployed successfully [2022-04-13 10:27:20,164] Artifact spring_struct2:war exploded: Deploy took 2,138 milliseconds
打开网址进行测试:http://localhost:8888/spring_struts2/user/hello
网页呈现效果:
控制台输出内容:
hello spring struts2
出现上述效果表示创建成功!
3. Spring整合Struts2框架
3.1 引入依赖
pom.xml需要额外引入依赖:
-
struts2-spring-plugin
:spring整合struts2 -
servlet-api
:引入监听器ContextLoaderListener
<!--struts2-spring-plugin--> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-spring-plugin</artifactId> <version>2.3.16</version> </dependency> <!--servlet-api--> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency>
3.2 resources下新建spring.xml,管理Action组件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--管理Action组件对象的创建--> <bean id="userAction" class="com.study.action.UserAction" scope="prototype"/> </beans>
3.3 web.xml配置监听器和spring.xml文件位置
<!--配置启动工厂的监听器Listener,使用前需添加servlet-api依赖--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--配置spring配置文件位置--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring.xml</param-value> </context-param>
3.4 修改struts.xml中class对象名称为对象id
<?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> <package name="user" extends="struts-default" namespace="/user"> <action name="hello" class="userAction" method="hello"> <result name="success">/index.jsp</result> </action> </package> </struts>
注意: 配置文件中书写的是工厂中管理的action的bean的id
3.5 部署项目测试
测试效果与2.6效果一致。
3.6 spring整合struts2编码步骤总结
附:自定义监听器MyListener
package com.study.listener; import org.springframework.context.support.ClassPathXmlApplicationContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class MyListener implements ServletContextListener { private ClassPathXmlApplicationContext context ; @Override public void contextInitialized(ServletContextEvent sce) { String springConfig = sce.getServletContext().getInitParameter("springConfig"); System.out.println(springConfig); System.out.println("服务器启动时初始化"); this.context = new ClassPathXmlApplicationContext(springConfig); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("服务器关闭时销毁"); context.close(); } }
4. SSM整合编程
4.1 整合步骤
配套视频:【编程不良人】快速入门Spring,SpringBoot、SpringCloud学不好完全是因为Spring没有掌握!_哔哩哔哩_bilibili
4.2 编码实现
配套视频:【编程不良人】快速入门Spring,SpringBoot、SpringCloud学不好完全是因为Spring没有掌握!_哔哩哔哩_bilibili
一、整合Spring+Mybatis
a. 新建Maven-webapp项目,main下新建java、resources目录,src下新建test目录,并在此路径下新建java、resources目录
b.在pom.xml引入依赖
<!--junit--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!--spring相关--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.3.2.RELEASE</version> </dependency> <!--mybatis--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.4</version> </dependency> <!--mybatis-spring--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.4</version> </dependency> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <!--druid--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.19</version> </dependency> <!--struts相关 2.3.16版本一致--> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.3.16</version> </dependency> <!--struts2-spring-plugin 2.3.16版本一致--> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-spring-plugin</artifactId> <version>2.3.16</version> </dependency> <!--servlet-api--> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <!--jstl--> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!--fastjson--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.62</version> </dependency> <!--log4j--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.10.0</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.25</version> </dependency>
c.新建实体类User
package com.study.entity; import java.util.Date; /** * @ClassName User * @Description TODO * @Author Jiangnan Cui * @Date 2022/4/14 12:33 * @Version 1.0 */ public class User { private String id; private String name; private Integer age; private Date bir; public User() { } public User(String id, String name, Integer age, Date bir) { this.id = id; this.name = name; this.age = age; this.bir = bir; } @Override public String toString() { return "User{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", age=" + age + ", bir=" + bir + '}'; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getBir() { return bir; } public void setBir(Date bir) { this.bir = bir; } }
d.新建DAO接口:UserDAO
package com.study.dao; import com.study.entity.User; import java.util.List; /** * @ClassName UserDAO * @Description TODO * @Author Jiangnan Cui * @Date 2022/4/14 12:36 * @Version 1.0 */ public interface UserDAO { /** * @MethodName insert * @Description 插入用户数据 * @param: user * @Author Jiangnan Cui * @Date 2022/4/14 12:37 */ void insert(User user); /** * @MethodName selectAll * @Description 查询用户所有数据 * @return: java.util.List<com.study.entity.User> * @Author Jiangnan Cui * @Date 2022/4/14 12:37 */ List<User> selectAll(); }
e.新建Mapper配置文件:UserDAOMapper(resources/com/study/mapper目录下)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <!-- mapper为映射的根节点,用来管理DAO接口 namespace指定DAO接口的完整类名,表示mapper配置文件管理哪个DAO接口(包.接口名) mybatis会依据这个接口动态创建一个实现类去实现这个接口,而这个实现类是一个Mapper对象 --> <mapper namespace="com.study.dao.UserDAO"> <!-- id = "接口中的方法名" parameterType = "接口中传入方法的参数类型" 基本类型和String正常使用,引用类型使用类的全限定名(包名.类名) resultType = "返回实体类对象:包.类名" 处理结果集 自动封装 注意:sql语句后不要出现";"号 查询:select标签 多参数查询时注意接口中的参数必须使用@Param注解绑定,select标签中parameterType省略不写 查询所有时,无论查询一个还是多个,最终resultType的值都是要封装的实体类全名(包名.类名) 例:<select id="findById" parameterType="int" resultType="entity.Student"> select id,name,age from student where id=#{id} </select> 增加:insert标签 例:<insert id="insert" parameterType="entity.Student"> insert into student values(#{id},#{name},#{age}) </insert> 修改:update标签 例:<update id="update" parameterType="entity.Student"> update student set name=#{name},age=#{age} where id=#{id} </update> 删除:delete标签 例:<delete id="delete" parameterType="int"> delete from student where id=#{id} </delete> Mybatis框架在执行插入(insert)、更新(update)操作时,默认不允许插入或修改NULL值到数据库中, 要在sql语句的取值处设置一个jdbcType类型(类型全部字母大写)),例如:#{age,jdbcType=INTEGER} --> <!--insert--> <insert id="insert" parameterType="User"> insert into t_user values(#{id},#{name},#{age},#{bir}) </insert> <!--selectAll--> <select id="selectAll" resultType="User"> select id,name,age,bir from t_user </select> </mapper>
f.新建Service接口:UserService
package com.study.service; import com.study.entity.User; import java.util.List; /** * @ClassName UserService * @Description TODO * @Author Jiangnan Cui * @Date 2022/4/14 12:42 * @Version 1.0 */ public interface UserService { /** * @MethodName insert * @Description 插入用户数据 * @param: user * @Author Jiangnan Cui * @Date 2022/4/14 12:37 */ void insert(User user); /** * @MethodName selectAll * @Description 查询用户所有数据 * @return: java.util.List<com.study.entity.User> * @Author Jiangnan Cui * @Date 2022/4/14 12:37 */ List<User> selectAll(); }
g.新建UserService接口实现类:UserServiceImpl,依赖UserDAO组件,需要注入
package com.study.service; import com.study.dao.UserDAO; import com.study.entity.User; import java.util.List; import java.util.UUID; /** * @ClassName UserServiceImpl * @Description TODO * @Author Jiangnan Cui * @Date 2022/4/14 12:42 * @Version 1.0 */ public class UserServiceImpl implements UserService{ //依赖UserDAO private UserDAO userDAO; public void setUserDAO(UserDAO userDAO) { this.userDAO = userDAO; } @Override public void insert(User user) { //处理业务 user.setId(UUID.randomUUID().toString()); userDAO.insert(user); } @Override public List<User> selectAll() { //处理业务 return userDAO.selectAll(); } }
h.编写spring.xml配置文件(resources目录下)
<?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: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/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--创建数据源--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis? useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false"/> <property name="username" value="root"/> <property name="password" value="123456"/> </bean> <!--创建SqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mapperLocations" value="classpath:com/study/mapper/*.xml"/> <property name="typeAliasesPackage" value="com.study.entity"/> </bean> <!--创建DAO组件--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <property name="basePackage" value="com.study.dao"/> </bean> <!--创建事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--基于事务管理器创建事务通知对象,并配置事务细粒度控制--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="insert*"/> <tx:method name="select*" propagation="SUPPORTS"/> </tx:attributes> </tx:advice> <!--配置事务切面--> <aop:config> <aop:pointcut id="pc" expression="within(com.study.service.*ServiceImpl)"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pc"/> </aop:config> <!--管理Service组件对象--> <bean id="userService" class="com.study.service.UserServiceImpl"> <property name="userDAO" ref="userDAO"/> </bean> </beans>
i.在resources目录下新建log4j.properties记录日志信息
## 根日志 ## 日志级别 log4j.rootLogger=ERROR,stdout ## 输出位置 log4j.appender.stdout=org.apache.log4j.ConsoleAppender ## 布局 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout ## 格式 log4j.appender.stdout.layout.conversionPattern=[%p] %d{yyyy-MM-dd} %m%n • ## 子日志 ## 日志级别 log4j.logger.com.study.dao=DEBUG ## 监听spring框架的日志级别 ## log4j.logger.org.springframework=ERROR
j.测试Spring+Mybatis是否整合成功(src/test/java/com/study/test目录下)
package com.study.test; import com.study.service.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @ClassName TestUserService * @Description TODO * @Author Jiangnan Cui * @Date 2022/4/14 13:07 * @Version 1.0 */ public class TestUserService { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); UserService userService = (UserService) context.getBean("userService"); userService.selectAll().forEach(user -> System.out.println("user = " + user)); } }
输出结果:
[DEBUG] 2022-04-14 ==> Preparing: select id,name,age,bir from t_user [DEBUG] 2022-04-14 ==> Parameters: [DEBUG] 2022-04-14 <== Total: 14 user = User{id='1', name='张三', age=10, bir=Fri Apr 01 00:00:00 CST 2022} user = User{id='2', name='李四', age=20, bir=Sat Apr 02 00:00:00 CST 2022} user = User{id='2f278828-6422-432d-ab1b-a727b33c23bc', name='小胖墩', age=3, bir=Mon Apr 11 21:43:57 CST 2022} user = User{id='3', name='王五', age=30, bir=Sun Apr 03 00:00:00 CST 2022} user = User{id='4', name='灰太狼', age=60, bir=Sun Apr 10 09:56:17 CST 2022} user = User{id='5', name='小超超', age=36, bir=Sun Apr 10 09:55:41 CST 2022} user = User{id='586a5f71-836c-4171-a038-4620fe0f9354', name='葫芦娃', age=5, bir=Tue Apr 12 09:45:17 CST 2022} user = User{id='6', name='小呆呆', age=60, bir=Sun Apr 10 09:55:43 CST 2022} user = User{id='7', name='小超超', age=36, bir=Sun Apr 10 09:55:44 CST 2022} user = User{id='8', name='胖嘟嘟', age=50, bir=Sun Apr 10 09:55:39 CST 2022} user = User{id='8a3e8ab8-5abc-44e1-9aec-31f3978d97f2', name='小胖墩', age=3, bir=Tue Apr 12 10:23:33 CST 2022} user = User{id='9', name='小崔', age=25, bir=Sun Apr 10 09:55:52 CST 2022} user = User{id='cd280176-68b2-4ceb-b781-ba2f5e1fbeff', name='小胖墩', age=3, bir=Tue Apr 12 10:21:18 CST 2022} user = User{id='e3863fd3-173c-46f4-a753-c72f7c92ad56', name='小猫咪', age=3, bir=Mon Apr 11 21:36:31 CST 2022}
二、整合Spring+Struts2
a. 配置web.xml(webapp/WEB-INF目录下)
<!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> <display-name>Archetype Created Web Application</display-name> <!--配置工厂配置文件的位置--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring.xml</param-value> </context-param> <!--配置struts2 filter--> <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> <!--配置Spring监听器--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
b.开发Action组件:UserAction,注入Service组件
package com.study.action; import com.opensymphony.xwork2.Action; import com.study.entity.User; import com.study.service.UserService; import java.util.List; /** * @ClassName UserAction * @Description TODO * @Author Jiangnan Cui * @Date 2022/4/14 13:57 * @Version 1.0 */ public class UserAction { //依赖注入只需要SET方法 private UserService userService; public void setUserService(UserService userService) { this.userService = userService; } //接收参数 数据传递 必须同时提供GET、SET方法 private List<User> users; private User user; public List<User> getUsers() { return users; } public void setUsers(List<User> users) { this.users = users; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } /** * @MethodName insert * @Description 插入用户信息 * @return: java.lang.String * @Author Jiangnan Cui * @Date 2022/4/14 14:31 */ public String insert(){ //1.接收参数 //2.调用业务方法 userService.insert(user); //3.处理响应 return Action.SUCCESS; } /** * @MethodName selectAll * @Description 查询所有用户数据 * @return: java.lang.String * @Author Jiangnan Cui * @Date 2022/4/14 14:34 */ public String selectAll(){ //1.收集数据 //2.调用业务 //3.处理响应 this.users = userService.selectAll(); return Action.SUCCESS; } }
c.spring.xml管理Action组件,注入Service组件
<!--管理Action组件对象--> <bean id="userAction" class="com.study.action.UserAction" scope="prototype"> <property name="userService" ref="userService"/> </bean>
d.resources目录下引入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> <package name="user" extends="struts-default" namespace="/user"> <!--selectAll,访问端口:http://localhost:端口号/项目名/user/selectAll 例如:http://localhost:8888/ssm_struts2/user/selectAll --> <action name="selectAll" class="userAction" method="selectAll"> <result name="success">/showAll.jsp</result> </action> <!--insert,访问端口:http://localhost:端口号/项目名/user/insert?user.name=xxx&user.age=xxx&user.bir=xxxx-xx-xx 例如:http://localhost:8888/ssm_struts2/user/insert?user.name=皮卡丘&&user.age=10&user.bir=2022-04-14--> <action name="insert" class="userAction" method="insert"> <result name="success" type="redirect">/user/selectAll</result> </action> </package> </struts>
e.webapp路径下新建showAll.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <%@page pageEncoding="UTF-8" contentType="text/html; UTF-8" isELIgnored="false" %> <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>展示所有用户</title> </head> <body> <h1>用户列表</h1> <c:forEach items="${requestScope.users}" var="user"> ${user.id}----${user.name}----${user.age}----<fmt:formatDate value="${user.bir}" pattern="yyyy-MM-dd"/> <br> </c:forEach> </body> </html>
f.部署Tomcat进行测试
项目启动成功后自动访问页面:
控制台打印输出:
D:\Software_Development\IDEA_code\apache-tomcat-8.5.78\bin\catalina.bat run [2022-04-14 02:45:51,794] Artifact ssm_struts2:war exploded: Waiting for server connection to start artifact deployment... Using CATALINA_BASE: "C:\Users\cjn\AppData\Local\JetBrains\IntelliJIdea2020.1\tomcat\Unnamed_ssm_struts2" Using CATALINA_HOME: "D:\Software_Development\IDEA_code\apache-tomcat-8.5.78" Using CATALINA_TMPDIR: "D:\Software_Development\IDEA_code\apache-tomcat-8.5.78\temp" Using JRE_HOME: "D:\Software_Development\JDK" Using CLASSPATH: "D:\Software_Development\IDEA_code\apache-tomcat-8.5.78\bin\bootstrap.jar;D:\Software_Development\IDEA_code\apache-tomcat-8.5.78\bin\tomcat-juli.jar" Using CATALINA_OPTS: "" ...... Connected to server [2022-04-14 02:45:53,392] Artifact ssm_struts2:war exploded: Artifact is being deployed, please wait... ...... [2022-04-14 02:45:57,901] Artifact ssm_struts2:war exploded: Artifact is deployed successfully [2022-04-14 02:45:57,901] Artifact ssm_struts2:war exploded: Deploy took 4,509 milliseconds
访问路径:http://localhost:8888/ssm_struts2/user/selectAll 查询所有用户信息,显示效果如下:
访问路径:http://localhost:8888/ssm_struts2/user/insert?user.name=皮卡丘&&user.age=10&user.bir=2022-04-14 插入用户信息,显示效果如下:
附:最终项目结构
5. Spring的注解式开发
配套视频:【编程不良人】快速入门Spring,SpringBoot、SpringCloud学不好完全是因为Spring没有掌握!_哔哩哔哩_bilibili
5.1 常用注解总结
Spring自2.5版本以后提供了一些注解用来在使用spring时进行快速开发
### 实例化相关注解 # 1. @Component(value="beanid") 修饰范围: 用在类上 注解作用: 通用的创建实例的注解,用来创建当前这个类的实例 value属性: 用来指定创建的对象在工厂中的唯一标识 如果不指定默认创建对象在工厂中的标识为类名首字母小写 # 2. @Repository 修饰范围: 用在类上 注解作用: @component的子类注解专用于DAO组件的创建,通常加在DAO组件上 value属性: 用来指定创建的对象在工厂中的唯一标识 如果不指定默认创建对象在工厂中的标识为类名首字母小写 # 3. @Service 修饰范围: 用在类上 注解作用: @component的子类注解专用于Service组件的创建,通常加在Service组件上 value属性: 用来指定创建的对象在工厂中的唯一标识 如果不指定默认创建对象在工厂中的标识为类名首字母小写 # 4. @Controller 修饰范围: 用在类上 注解作用: @component的子类注解专用于Action组件的创建,通常加在Action组件上 value属性: 用来指定创建的对象在工厂中的唯一标识 如果不指定默认创建对象在工厂中的标识为类名首字母小写 ### 控制对象的创建次数的注解 # 1. @Scope(value="singleton|prototype") 修饰范围: 用在类上 注解作用: 用来控制这个实例在工厂中的创建次数 value属性: singleton为单例,prototype为多例 默认单例 ### 注入相关的注解 # 1. @Autowired(Spring提供) 修饰范围: 用在成员变量或成员变量的GET/SET方法上 注解作用: 用来给类中成员变量赋值 注入原则: 默认根据类型自动注入 # 2. @Resource(JAVAEE提供) 修饰范围: 用在成员变量或成员变量的GET/SET方法上 注解作用: 用来给类中成员变量赋值 注入原则: 默认根据名称自动注入名称找不到根据类型自动注入 ### 控制事务的相关注解 # 1. @Transactional 修饰范围: 用在类上主要用在业务层组件类上或者是方法上 注解作用: 用来给类中方法加入事务,当类上和方法上同时存在该注解时局部优先 注解属性: propagation 用来控制传播属性 Isolation 用来控制隔离级别 timeout 用来设置超时性 rollback-for 用来设置什么异常回滚 norollback-for 用来设置什么异常不会滚 readonly 用来设置事务读写性 # 注意: 如果要使用事务注解在配置文件中必须开启事务注解生效加入如下配置: <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
具体实现:
5.2 新建Maven-webapp项目,添加java、resources目录
5.3 pom.xml导入依赖
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>compile</scope> </dependency> <!--spring核心及相关依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.3.2.RELEASE</version> </dependency>
5.4 编写DAO接口及其实现类
package com.study.dao; /** * @ClassName UserDAO * @Description TODO * @Author Jiangnan Cui * @Date 2022/4/15 15:51 * @Version 1.0 */ public interface UserDAO { void save(String name); } package com.study.dao; import org.springframework.stereotype.Component; import org.springframework.stereotype.Repository; /** * @ClassName UserDAOImpl * @Description TODO * @Author Jiangnan Cui * @Date 2022/4/15 15:52 * @Version 1.0 */ //1.通用注解 //默认@Component(value="userDAOImpl"),即类名首字母小写,简写为@Component("userDAOImpl"),只有一个参数时才可以省略value //指定其他名称是,须通过value指定 //@Component(value = "userDAO") //2.DAO层专用注解 //默认@Repository(value="userDAOImpl"),即类名首字母小写,简写为@Repository("userDAOImpl"),只有一个参数时才可以省略value //指定其他名称是,须通过value指定 @Repository(value = "userDAO") public class UserDAOImpl implements UserDAO{ @Override public void save(String name) { System.out.println("UserDAO: " + name); } }
5.5 编写Service接口及其实现类
package com.study.service; /** * @ClassName UserService * @Description TODO * @Author Jiangnan Cui * @Date 2022/4/15 15:53 * @Version 1.0 */ public interface UserService { void save(String name); String find(String id); } package com.study.service; import com.study.dao.UserDAO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; /** * @ClassName UserServiceImpl * @Description TODO * @Author Jiangnan Cui * @Date 2022/4/15 15:54 * @Version 1.0 */ //1.通用注解 //默认@Component(value="userServiceImpl"),即类名首字母小写,简写为@Component("userServiceImpl"),只有一个参数时才可以省略value //指定其他名称是,须通过value指定 //@Component(value = "userService") //2.Service层专用注解 //默认@Repository(value="userServiceImpl"),即类名首字母小写,简写为@Repository("userServiceImpl"),只有一个参数时才可以省略value //指定其他名称是,须通过value指定 @Service(value = "userService") //Service层需要添加事务,默认属性,查询方法额外添加属性 @Transactional // 默认单例,scope为多例 @Scope(value = "prototype") public class UserServiceImpl implements UserService{ //Service层需要调用DAO层 @Autowired private UserDAO userDAO; @Override public void save(String name) { userDAO.save("UserDAO"); System.out.println("UserService = " + name); } @Override //查询方法需要额外添加事务属性 @Transactional( propagation = Propagation.SUPPORTS, isolation = Isolation.DEFAULT, noRollbackFor = {}, rollbackFor = {}, readOnly = false, timeout = -1 ) public String find(String id) { return id; } }
5.6 编写spring.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- <!–管理DAO组件–>--> <!-- <bean id="userDAO" class="com.study.dao.UserDAOImpl"/>--> <!-- <!–管理Service组件–>--> <!-- <bean id="userService" class="com.study.service.UserServiceImpl"/>--> <!--开启注解扫描--> <context:component-scan base-package="com.study"/> <!--开启事务注解,上面要进行数据源及事务管理配置--> <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven> </beans>
5.7 测试
package com.study.test; import com.study.dao.UserDAO; import com.study.service.UserService; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @ClassName TestSpring * @Description TODO * @Author Jiangnan Cui * @Date 2022/4/15 15:57 * @Version 1.0 */ public class TestSpring { /** * @MethodName TestUserDAO * @Description 测试DAO层注解 * @Author Jiangnan Cui * @Date 2022/4/15 16:23 */ @Test public void TestUserDAO(){ ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); UserDAO userDAO = (UserDAO) context.getBean("userDAO"); System.out.println("userDAO = " + userDAO); userDAO.save("2022年4月15日15:59:50"); } /** * @MethodName TestUserService * @Description 测试Service层注解 * @Author Jiangnan Cui * @Date 2022/4/15 16:23 */ @Test public void TestUserService(){ ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); UserService userService = (UserService) context.getBean("userService"); System.out.println("userService = " + userService); System.out.println(userService.find("1")); UserService userService1 = (UserService) context.getBean("userService"); System.out.println("userService1 = " + userService1); System.out.println(userService1.find("2")); System.out.println(userService==userService1); userService.save("UserService"); } }
输出结果:
userService = com.study.service.UserServiceImpl@19d37183 1 userService1 = com.study.service.UserServiceImpl@1a0dcaa 2 false UserDAO: UserDAO UserService = UserService
6.ssm整合注解式开发
6.1 编码步骤
6.2 代码实现
配套视频:【编程不良人】快速入门Spring,SpringBoot、SpringCloud学不好完全是因为Spring没有掌握!_哔哩哔哩_bilibili
一、整合Spring+Mybatis
a. 新建Maven-webapp项目,main下新建java、resources目录,src下新建test目录,并在此路径下新建java、resources目录
b.在pom.xml引入依赖
<!--junit--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!--spring相关--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.3.2.RELEASE</version> </dependency> <!--mybatis--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.4</version> </dependency> <!--mybatis-spring--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.4</version> </dependency> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <!--druid--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.19</version> </dependency> <!--struts相关 2.3.16版本一致--> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.3.16</version> </dependency> <!--struts2-spring-plugin 2.3.16版本一致--> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-spring-plugin</artifactId> <version>2.3.16</version> </dependency> <!--servlet-api--> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <!--jstl--> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!--fastjson--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.62</version> </dependency> <!--log4j--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.10.0</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.25</version> </dependency>
c.新建实体类User
package com.study.entity; import java.util.Date; /** * @ClassName User * @Description TODO * @Author Jiangnan Cui * @Date 2022/4/14 12:33 * @Version 1.0 */ public class User { private String id; private String name; private Integer age; private Date bir; public User() { } public User(String id, String name, Integer age, Date bir) { this.id = id; this.name = name; this.age = age; this.bir = bir; } @Override public String toString() { return "User{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", age=" + age + ", bir=" + bir + '}'; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getBir() { return bir; } public void setBir(Date bir) { this.bir = bir; } }
d.新建DAO接口:UserDAO
package com.study.dao; import com.study.entity.User; import java.util.List; /** * @ClassName UserDAO * @Description TODO * @Author Jiangnan Cui * @Date 2022/4/14 12:36 * @Version 1.0 */ public interface UserDAO { /** * @MethodName insert * @Description 插入用户数据 * @param: user * @Author Jiangnan Cui * @Date 2022/4/14 12:37 */ void insert(User user); /** * @MethodName selectAll * @Description 查询用户所有数据 * @return: java.util.List<com.study.entity.User> * @Author Jiangnan Cui * @Date 2022/4/14 12:37 */ List<User> selectAll(); }
e.新建Mapper配置文件:UserDAOMapper(resources/com/study/mapper目录下)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <!-- mapper为映射的根节点,用来管理DAO接口 namespace指定DAO接口的完整类名,表示mapper配置文件管理哪个DAO接口(包.接口名) mybatis会依据这个接口动态创建一个实现类去实现这个接口,而这个实现类是一个Mapper对象 --> <mapper namespace="com.study.dao.UserDAO"> <!-- id = "接口中的方法名" parameterType = "接口中传入方法的参数类型" 基本类型和String正常使用,引用类型使用类的全限定名(包名.类名) resultType = "返回实体类对象:包.类名" 处理结果集 自动封装 注意:sql语句后不要出现";"号 查询:select标签 多参数查询时注意接口中的参数必须使用@Param注解绑定,select标签中parameterType省略不写 查询所有时,无论查询一个还是多个,最终resultType的值都是要封装的实体类全名(包名.类名) 例:<select id="findById" parameterType="int" resultType="entity.Student"> select id,name,age from student where id=#{id} </select> 增加:insert标签 例:<insert id="insert" parameterType="entity.Student"> insert into student values(#{id},#{name},#{age}) </insert> 修改:update标签 例:<update id="update" parameterType="entity.Student"> update student set name=#{name},age=#{age} where id=#{id} </update> 删除:delete标签 例:<delete id="delete" parameterType="int"> delete from student where id=#{id} </delete> Mybatis框架在执行插入(insert)、更新(update)操作时,默认不允许插入或修改NULL值到数据库中, 要在sql语句的取值处设置一个jdbcType类型(类型全部字母大写)),例如:#{age,jdbcType=INTEGER} --> <!--insert--> <insert id="insert" parameterType="User"> insert into t_user values(#{id},#{name},#{age},#{bir}) </insert> <!--selectAll--> <select id="selectAll" resultType="User"> select id,name,age,bir from t_user </select> </mapper>
f.新建Service接口:UserService
package com.study.service; import com.study.entity.User; import java.util.List; /** * @ClassName UserService * @Description TODO * @Author Jiangnan Cui * @Date 2022/4/14 12:42 * @Version 1.0 */ public interface UserService { /** * @MethodName insert * @Description 插入用户数据 * @param: user * @Author Jiangnan Cui * @Date 2022/4/14 12:37 */ void insert(User user); /** * @MethodName selectAll * @Description 查询用户所有数据 * @return: java.util.List<com.study.entity.User> * @Author Jiangnan Cui * @Date 2022/4/14 12:37 */ List<User> selectAll(); }
g.新建UserService接口实现类:UserServiceImpl,依赖UserDAO组件,需要注入
package com.study.service; import com.study.dao.UserDAO; import com.study.entity.User; import java.util.List; import java.util.UUID; /** * @ClassName UserServiceImpl * @Description TODO * @Author Jiangnan Cui * @Date 2022/4/14 12:42 * @Version 1.0 */ @Service("userService") @Transational public class UserServiceImpl implements UserService{ //依赖UserDAO @Autowired private UserDAO userDAO; @Override public void insert(User user) { //处理业务 user.setId(UUID.randomUUID().toString()); userDAO.insert(user); } @Override @Transactional(propagation = Propagation.SUPPORTS) public List<User> selectAll() { //处理业务 return userDAO.selectAll(); } }
h.编写spring.xml配置文件(resources目录下)
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!--开启注解扫描--> <context:component-scan base-package="com.study"/> <!--创建数据源对象--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis? useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false"/> <property name="username" value="root"/> <property name="password" value="123456"/> </bean> <!--创建SqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mapperLocations" value="classpath:com/study/mapper/*.xml"/> <property name="typeAliasesPackage" value="com.study.entity"/> </bean> <!--创建DAO组件--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <property name="basePackage" value="com.study.dao"/> </bean> <!--创建事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--开启注解式事务生效--> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>
i.在resources目录下新建log4j.properties记录日志信息
## 根日志 ## 日志级别 log4j.rootLogger=ERROR,stdout ## 输出位置 log4j.appender.stdout=org.apache.log4j.ConsoleAppender ## 布局 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout ## 格式 log4j.appender.stdout.layout.conversionPattern=[%p] %d{yyyy-MM-dd} %m%n ## 子日志 ## 日志级别 log4j.logger.com.study.dao=DEBUG ## 监听spring框架的日志级别 ## log4j.logger.org.springframework=ERROR
j.测试Spring+Mybatis是否整合成功(src/test/java/com/study/test目录下)
package com.study.test; import com.study.service.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @ClassName TestUserService * @Description TODO * @Author Jiangnan Cui * @Date 2022/4/14 13:07 * @Version 1.0 */ public class TestUserService { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); UserService userService = (UserService) context.getBean("userService"); userService.selectAll().forEach(user -> System.out.println("user = " + user)); } }
输出结果:
[DEBUG] 2022-04-15 ==> Preparing: select id,name,age,bir from t_user [DEBUG] 2022-04-15 ==> Parameters: [DEBUG] 2022-04-15 <== Total: 17 user = User{id='1', name='张三', age=10, bir=Fri Apr 01 00:00:00 CST 2022} user = User{id='2', name='李四', age=20, bir=Sat Apr 02 00:00:00 CST 2022} user = User{id='2d237778-835d-477b-9721-fe6f575064b9', name='波比', age=18, bir=Sun Feb 02 00:00:00 CST 2020} user = User{id='2f278828-6422-432d-ab1b-a727b33c23bc', name='小胖墩', age=3, bir=Mon Apr 11 21:43:57 CST 2022} user = User{id='3', name='王五', age=30, bir=Sun Apr 03 00:00:00 CST 2022} user = User{id='4', name='灰太狼', age=60, bir=Sun Apr 10 09:56:17 CST 2022} user = User{id='5', name='小超超', age=36, bir=Sun Apr 10 09:55:41 CST 2022} user = User{id='586a5f71-836c-4171-a038-4620fe0f9354', name='葫芦娃', age=5, bir=Tue Apr 12 09:45:17 CST 2022} user = User{id='6', name='小呆呆', age=60, bir=Sun Apr 10 09:55:43 CST 2022} user = User{id='7', name='小超超', age=36, bir=Sun Apr 10 09:55:44 CST 2022} user = User{id='8', name='胖嘟嘟', age=50, bir=Sun Apr 10 09:55:39 CST 2022} user = User{id='8a3e8ab8-5abc-44e1-9aec-31f3978d97f2', name='小胖墩', age=3, bir=Tue Apr 12 10:23:33 CST 2022} user = User{id='9', name='小崔', age=25, bir=Sun Apr 10 09:55:52 CST 2022} user = User{id='985cd035-dedc-4e84-973a-a5fdaa2b8475', name='喜洋洋', age=8, bir=Tue Oct 10 00:00:00 CST 2000} user = User{id='a6be9263-f05f-415f-855e-33843b22e71d', name='皮卡丘', age=10, bir=Thu Apr 14 00:00:00 CST 2022} user = User{id='cd280176-68b2-4ceb-b781-ba2f5e1fbeff', name='小胖墩', age=3, bir=Tue Apr 12 10:21:18 CST 2022} user = User{id='e3863fd3-173c-46f4-a753-c72f7c92ad56', name='小猫咪', age=3, bir=Mon Apr 11 21:36:31 CST 2022}
二、整合Spring+Struts2
a. 配置web.xml(webapp/WEB-INF目录下)
<!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> <display-name>Archetype Created Web Application</display-name> <!--配置工厂配置文件的位置--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring.xml</param-value> </context-param> <!--配置struts2中核心filter--> <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> <!--配置Spring监听器--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
b.开发Action组件:UserAction,注入Service组件
package com.study.action; import com.opensymphony.xwork2.Action; import com.study.entity.User; import com.study.service.UserService; import java.util.List; /** * @ClassName UserAction * @Description TODO * @Author Jiangnan Cui * @Date 2022/4/14 13:57 * @Version 1.0 */ @Controller @Scope("prototype") public class UserAction { //依赖注入 @Autowired private UserService userService; //接收参数 数据传递 必须同时提供GET、SET方法 private List<User> users;//struts2传值机制:成员变量替换request的作用域 private User user; public List<User> getUsers() { return users; } public void setUsers(List<User> users) { this.users = users; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } /** * @MethodName insert * @Description 插入用户信息 * @return: java.lang.String * @Author Jiangnan Cui * @Date 2022/4/14 14:31 */ public String insert(){ //1.接收参数 //2.调用业务方法 userService.insert(user); //3.处理响应 return Action.SUCCESS; } /** * @MethodName selectAll * @Description 查询所有用户数据 * @return: java.lang.String * @Author Jiangnan Cui * @Date 2022/4/14 14:34 */ public String selectAll(){ //1.收集数据 //2.调用业务 //3.处理响应 this.users = userService.selectAll(); return Action.SUCCESS; } }
c.resources目录下引入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> <package name="user" extends="struts-default" namespace="/user"> <!--selectAll,访问端口:http://localhost:端口号/项目名/user/selectAll 例如:http://localhost:8888/ssm_struts2_annotation/user/selectAll --> <action name="selectAll" class="userAction" method="selectAll"> <result name="success">/showAll.jsp</result> </action> <!--insert,访问端口:http://localhost:端口号/项目名/user/insert?user.name=xxx&user.age=xxx&user.bir=xxxx-xx-xx 例如:http://localhost:8888/ssm_struts2_annotation/user/insert?user.name=唐三&&user.age=20&user.bir=2022-04-15--> <action name="insert" class="userAction" method="insert"> <result name="success" type="redirect">/user/selectAll</result> </action> </package> </struts>
d.webapp路径下新建showAll.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <%@page pageEncoding="UTF-8" contentType="text/html; UTF-8" isELIgnored="false" %> <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>展示所有用户</title> </head> <body> <h1>用户列表</h1> <c:forEach items="${requestScope.users}" var="user"> ${user.id}----${user.name}----${user.age}----<fmt:formatDate value="${user.bir}" pattern="yyyy-MM-dd"/> <br> </c:forEach> </body> </html>
d.部署Tomcat进行测试
项目启动成功后自动访问页面:
控制台打印输出:
D:\Software_Development\IDEA_code\apache-tomcat-8.5.78\bin\catalina.bat run [2022-04-15 08:15:02,252] Artifact ssm_struts2_annotation:war exploded: Waiting for server connection to start artifact deployment... Using CATALINA_BASE: "C:\Users\cjn\AppData\Local\JetBrains\IntelliJIdea2020.1\tomcat\Unnamed_ssm_struts2_annotation" Using CATALINA_HOME: "D:\Software_Development\IDEA_code\apache-tomcat-8.5.78" Using CATALINA_TMPDIR: "D:\Software_Development\IDEA_code\apache-tomcat-8.5.78\temp" Using JRE_HOME: "D:\Software_Development\JDK" Using CLASSPATH: "D:\Software_Development\IDEA_code\apache-tomcat-8.5.78\bin\bootstrap.jar;D:\Software_Development\IDEA_code\apache-tomcat-8.5.78\bin\tomcat-juli.jar" Using CATALINA_OPTS: "" ...... Connected to server [2022-04-15 08:15:04,464] Artifact ssm_struts2_annotation:war exploded: Artifact is being deployed, please wait... ...... [2022-04-15 08:15:21,685] Artifact ssm_struts2_annotation:war exploded: Artifact is deployed successfully [2022-04-15 08:15:21,686] Artifact ssm_struts2_annotation:war exploded: Deploy took 17,222 milliseconds
访问路径:http://localhost:8888/ssm_struts2_annotation/user/selectAll 查询所有用户信息,显示效果如下:
访问路径:http://localhost:8888/ssm_struts2_annotation/user/insert?user.name=唐三&&user.age=20&user.bir=2022-04-15 插入用户信息,显示效果如下:
附:最终项目结构