欢迎光临散文网 会员登陆 & 注册

SSM框架:@Transaction实现事务,登录功能,回滚,单词,重名验证,昵称【诗书画唱】

2021-03-24 22:18 作者:诗书画唱  | 我要投稿

趣话谈:下面我要讲的是“事务”功能的实现,其是“事务”就是“要死一起死,要活一起活”,“有福同享,有难同当”的"极端"家伙,好孩子别学“事务”哦!(●ˇ∀ˇ●)


概括:

个人理解:实现注册的功能的代码的部分的话,为了直观说明事务的作用,我这里举的例子比较的特殊,这里就是举要传2个对象的例子(当然平时做注册的功能的时候一般是传1个对象,这里传2个对象是为了更直观地说明事务,同时是满足一些客户的奇葩需求的,有些奇葩客户等等就是要求传2个对象,如果传1个对象其实也是要用且用了事务的,只是有时难看出来,每个service都是一个事务)。

exclude:不包括 

这段配置的意思是:不扫描controller控制器的注解

这个部分的代码的作用是:配置事务管理器

关于昵称可以相同的重名验证 

在实现“事务”的功能和作用时不可以不添加@Transaction注解

因为自己实现了“事务”的功能,所以在执行了注册一个用户的时候,再遇到“除0异常”,那么就会发生“回滚”,取消之前注册的用户。

事务的话其实可以用于银行转账等的业务功能的实现等等

项目访问路径和运行效果

Oracle数据库代码

PS:知道单词的意思有时很重要和关键,所以我自己特意把自己把每个项目中我遇到的我认为重要的单词和对应的单词的意思都去记录。
单词:

transaction:事务[trænˈzækʃn]


exclude:不包括 

transaction:事务[trænˈzækʃn]

代码示例



代码示例 START

package com.SSHC.bean;


import java.util.Date;


public class Userinfo {

    private Integer id;

    private String act;

    private String pwd;

    private Date birth;

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

public String getAct() {

return act;

}

public void setAct(String act) {

this.act = act;

}

public String getPwd() {

return pwd;

}

public void setPwd(String pwd) {

this.pwd = pwd;

}

public Date getBirth() {

return birth;

}

public void setBirth(Date birth) {

this.birth = birth;

}

}

package com.SSHC.controller;


import javax.annotation.Resource;

import javax.servlet.http.HttpSession;


import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.ModelAttribute;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.SessionAttributes;


import com.SSHC.bean.Userinfo;

import com.SSHC.service.PubService;


@Controller

public class LoginController {

@Resource

private PubService pubService;

@RequestMapping("lg")

    public String doLogin(@ModelAttribute("SpringWeb") Userinfo u

    ,HttpSession session,Model m){

    u = pubService.login(u);

    if(u != null && u.getId() > 0) {

    //将u放到session中去

    session.setAttribute("_user", u);

        return "index";

    } else {

    m.addAttribute("msg","登录失败");

    return "login";

    }

    }

}

package com.SSHC.dao;


import java.util.List;


import org.springframework.stereotype.Repository;


import com.SSHC.bean.Userinfo;

@Repository

public interface UserinfoDao {

    List<Userinfo> selectAll();

    Userinfo selectByActAndPwd(Userinfo u);

}

<?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">

<!-- namespace不能乱写,必须写成IUserinfoDao接口的全路径 -->

<mapper namespace="com.SSHC.dao.UserinfoDao">

    <resultMap type="Userinfo" id="rmUserinfo">

        <id property="id" column="ID"/>

    <result property="act" column="ACT"/>

    <result property="pwd" column="PWD"/>

    <result property="birth" column="BIRTH"/>

    </resultMap> 

    <select id="selectAll" resultMap="rmUserinfo">

        select * from userinfo

    </select> 

    <!-- Userinfo selectByActAndPwd(String act,String pwd) -->

    <select id="selectByActAndPwd" resultMap="rmUserinfo"

        parameterType="Userinfo">

        select * from userinfo where act = #{act} 

        and pwd = #{pwd}

    </select>

</mapper>


package com.SSHC.service;


import java.util.List;


import javax.annotation.Resource;


import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;


import com.SSHC.bean.Userinfo;

import com.SSHC.dao.UserinfoDao;

@Service

@Transactional

public class PubService {

//属性名就是接口名的首字母改成小写

@Resource

    private UserinfoDao userinfoDao;

    

    //登录方法

    public Userinfo login(Userinfo u){

    return userinfoDao.selectByActAndPwd(u);

    }

}

oracle_drivername=oracle.jdbc.driver.OracleDriver

oracle_url=jdbc:oracle:thin:@localhost:1521:orcl

oracle_username=X

oracle_password=sshcPwd

log4j.rootLogger=DEBUG,Console

#Console

log4j.appender.Console=org.apache.log4j.ConsoleAppender

log4j.appender.Console.layout=org.apache.log4j.PatternLayout

log4j.appender.Console.layout.ConversionPattern=%d[%t] %-5p [%c] - %m%n

log4j.logger.java.sql.ResultSet=INFO

log4j.logger.org.apache=INFO

log4j.logger.java.sql.Connection=DEBUG

log4j.logger.java.sql.Statement=DEBUG

log4j.logger.java.sql.PreparedStatement=DEBUG


<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  

    "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>  

    <typeAliases>

        <package name="com.SSHC.bean"/>

    </typeAliases>

</configuration>


<?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:mvc="http://www.springframework.org/schema/mvc"

    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-4.1.xsd

        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd

        http://www.springframework.org/schema/tx 

        http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

    <!-- 配置扫描注解,不扫描带有@Controller注解的类 -->

    <context:component-scan base-package="com.SSHC">

        <context:exclude-filter type="annotation"

            expression="org.springframework.stereotype.Controller" />

    </context:component-scan>

    <!-- 引入db.properties文件 -->

    <bean id="propertyConfigurer" 

        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

        <property name="location" value="classpath:db.properties"/>

    </bean>

    <!--数据库连接池配置-->

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 

        destroy-method="close">  

        <property name="driverClassName" value="${oracle_drivername}"/>

        <property name="url" value="${oracle_url}"/>

        <property name="username" value="${oracle_username}"/>

        <property name="password" value="${oracle_password}"/>

    </bean>

    <!-- 创建sqlSessionFactory对象 -->

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

        <!-- 指定数据源 -->

        <property name="dataSource" ref="dataSource"/>

        <!-- 指定mybatis框架主配置文件的位置 -->

        <property name="configLocation" value="classpath:mybatis.xml"/>

        <!-- 自动扫描mapping.xml文件,**表示迭代查找 ,,也可在mybatis.xml中单独指定xml文件 -->

        <property name="mapperLocations" value="classpath:com/SSHC/dao/*.xml"/>

    </bean> 

    <!-- 自动扫描com/SSHC/dao下的所有dao接口,并实现这些接口,

                 可直接在程序中使用dao接口,不用再获取sqlsession对象 -->

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

        <!-- basePackage 属性是映射器接口文件的包路径。

                        你可以使用分号或逗号 作为分隔符设置多于一个的包路径-->

        <property name="basePackage" value="com/SSHC/dao"/>

        <!-- 因为会自动装配 SqlSessionFactory和SqlSessionTemplate

                        所以没有必要去指定SqlSessionFactory或 SqlSessionTemplate

                        因此可省略不配置;

                        但是,如果你使用了一个以上的 DataSource,那么自动装配可能会失效。

                        这种情况下,你可以使用sqlSessionFactoryBeanName或sqlSessionTemplateBeanName属性

                        来设置正确的 bean名称来使用 -->

         <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>

    </bean>

    <!-- 配置事务管理器 -->

    <bean id="transactionManager"

        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

        <property name="dataSource" ref="dataSource" />

    </bean>

    <!--  使用声明式事务 transaction-manager:引用上面定义的事务管理器 -->

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

</beans>


<%@page import="com.SSHC.bean.Userinfo"%>

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%

    String path = request.getContextPath();

    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

    Userinfo u = (Userinfo)session.getAttribute("_user");

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

    <head>

        <base hreff="<%=basePath%>">

        <title></title>

        <meta http-equiv="pragma" content="no-cache">

        <meta http-equiv="cache-control" content="no-cache">

        <meta http-equiv="expires" content="0">

        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

        <meta http-equiv="description" content="This is my page">

    </head>

    <body>

        <h1>登录成功<%=u.getAct() %></h1>

    </body>

</html>

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%

    String path = request.getContextPath();

    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

    <head>

        <base hreff="<%=basePath%>">

        <title></title>

        <meta http-equiv="pragma" content="no-cache">

        <meta http-equiv="cache-control" content="no-cache">

        <meta http-equiv="expires" content="0">

        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

        <meta http-equiv="description" content="This is my page">

        <style type="text/css">

            *{

                font-size: 50px;

            }

        </style>

    </head>

    <body>

        <form action="lg" method="post">

            <label>账号:</label><input type="text" name="act"/>

            <br>

            <label>密码:</label><input type="password" name="pwd"/>

            <br>

            <input type="submit" value="登录" />

        </form>

        <div>${msg }</div>

    </body>

</html>


<?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:mvc="http://www.springframework.org/schema/mvc"

    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-4.1.xsd

        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">                       

    <!-- 扫描@Controller注解 -->

    <context:component-scan base-package="com.SSHC.controller">

        <context:include-filter type="annotation"

            expression="org.springframework.stereotype.Controller" />

    </context:component-scan>

    <!-- 默认注册RequestMappingHandlerMapping和RequestMappingHandlerAdapter类 -->

    <mvc:annotation-driven />

    <!-- jsp引用外部js,css等静态资源的解决方法(和上面的标签必须同时出现,否则无法访问url) -->

    <mvc:default-servlet-handler />

    <!-- 配置视图名称解析器 -->

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" 

            id="internalResourceViewResolver">

        <!-- 前缀 -->

        <!-- 将所有的jsp文件存放在/WEB-INF/my/目录下 -->

        <property name="prefix" value="/WEB-INF/" />

        <!-- 后缀 -->

        <property name="suffix" value=".jsp" />

        <!-- 优先级设定 -->

        <property name="order" value="10"></property>

    </bean> 

    <!-- http://localhost:8080/SSM2/toLogin -->

    <mvc:view-controller path="/toLogin" view-name="login"/> 

</beans>

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%

    String path = request.getContextPath();

    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

    <head>

        <base hreff="<%=basePath%>">

        <title></title>

        <meta http-equiv="pragma" content="no-cache">

        <meta http-equiv="cache-control" content="no-cache">

        <meta http-equiv="expires" content="0">

        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

        <meta http-equiv="description" content="This is my page">

    </head>

    <body>

        <h1>测试成功</h1>

    </body>

</html>

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

  <display-name>SSM2</display-name>

  <!-- springcore框架配置 -->

  <listener>

    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

  </listener>

  <!-- controller中文乱码处理,注意一点:要配置在所有过滤器的前面 -->

  <filter>

    <filter-name>CharacterEncodingFilter</filter-name>

    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

    <init-param>

      <param-name>encoding</param-name>

      <param-value>utf-8</param-value>

    </init-param>

  </filter>

  <filter-mapping>

    <filter-name>CharacterEncodingFilter</filter-name>

    <url-pattern>/*</url-pattern>

  </filter-mapping>

  <!-- springmvc框架配置 -->

  <servlet>

      <servlet-name>springmvc</servlet-name>

      <servlet-class>

          org.springframework.web.servlet.DispatcherServlet

      </servlet-class>

      <load-on-startup>1</load-on-startup>

  </servlet>

  <servlet-mapping>

      <servlet-name>springmvc</servlet-name>

      <url-pattern>/</url-pattern>

  </servlet-mapping>

  <welcome-file-list>

    <welcome-file>index.html</welcome-file>

    <welcome-file>index.htm</welcome-file>

    <welcome-file>index.jsp</welcome-file>

    <welcome-file>default.html</welcome-file>

    <welcome-file>default.htm</welcome-file>

    <welcome-file>default.jsp</welcome-file>

  </welcome-file-list>

</web-app>


项目访问路径和运行效果:

http://localhost:8080/SSM2/toLogin



Oracle数据库代码:

 --drop table Userinfo                

create table Userinfo(

    id number primary key,

    act varchar2(30) not null,

   pwd varchar2(30) not null,

   birth date

);


--drop sequence seq_Userinfo

create sequence seq_Userinfo

start with 1       --起始值是1

increment by 1     --增长的值   

maxvalue 999999999 --序列号的最大值

minvalue 1         --序列号的最小值

nocycle            --是否循环

cache 10;          --预存



insert into Userinfo values(seq_Userinfo.nextval,'黑黑','pwd1',to_date('2020-06-06','yyyy-mm-dd'));

insert into Userinfo values(seq_Userinfo.nextval,'红红','pwd2',to_date('2020-06-07','yyyy-mm-dd'));

insert into Userinfo values(seq_Userinfo.nextval,'蓝蓝','pwd3',to_date('2020-06-08','yyyy-mm-dd'));


insert into Userinfo values(seq_Userinfo.nextval,'666','pwd4',to_date('2020-06-06','yyyy-mm-dd'));

insert into Userinfo values(seq_Userinfo.nextval,'999','pwd5',to_date('2020-06-10','yyyy-mm-dd'));

insert into Userinfo values(seq_Userinfo.nextval,'888','pwd6',to_date('2020-06-11','yyyy-mm-dd'));


insert into Userinfo values(seq_Userinfo.nextval,'诗书画唱','pwd4',to_date('2020-06-06','yyyy-mm-dd'));

insert into Userinfo values(seq_Userinfo.nextval,'三连','pwd5',to_date('2020-06-10','yyyy-mm-dd'));

insert into Userinfo values(seq_Userinfo.nextval,'关注','pwd6',to_date('2020-06-11','yyyy-mm-dd'));

insert into Userinfo values(seq_Userinfo.nextval,'诗书画唱1','pwd4',to_date('2020-06-06','yyyy-mm-dd'));

insert into Userinfo values(seq_Userinfo.nextval,'诗书画唱2','pwd4',to_date('2020-06-06','yyyy-mm-dd'));

insert into Userinfo values(seq_Userinfo.nextval,'诗书画唱3','pwd4',to_date('2020-06-06','yyyy-mm-dd'));

insert into Userinfo values(seq_Userinfo.nextval,'诗书画唱4','pwd4',to_date('2020-06-06','yyyy-mm-dd'));

insert into Userinfo values(seq_Userinfo.nextval,'诗书画唱5','pwd4',to_date('2020-06-06','yyyy-mm-dd'));

--select * from Userinfo 


代码示例 END



边看教程视频边记录的学习笔记 START

个人理解:实现注册的功能的代码的部分的话,为了直观说明事务的作用,我这里举的例子比较的特殊,这里就是举要传2个对象的例子(当然平时做注册的功能的时候一般是传1个对象,这里传2个对象是为了更直观地说明事务,同时是满足一些客户的奇葩需求的,有些奇葩客户等等就是要求传2个对象,如果传1个对象其实也是要用且用了事务的,只是有时难看出来,每个service都是一个事务)。


这段配置的意思是:不扫描controller控制器的注解(扫描排除controller控制器的注解的其他文件)

这段配置的意思是:不扫描controller控制器的注解

exclude:不包括 



这个部分的代码的作用是:配置事务管理器
在实现“事务”的功能和作用时不可以不添加@Transaction注解

因为自己实现了“事务”的功能,所以在执行了注册一个用户的时候,再遇到“除0异常”,那么就会发生“回滚”,取消之前注册的用户。

因为自己实现了“事务”的功能,所以在执行了注册一个用户的时候,再遇到“除0异常”,那么就会发生“回滚”,取消之前注册的用户。

事务的话其实可以用于银行转账等的业务功能的实现等等。


边看教程视频边记录的学习笔记 END


关于昵称可以相同的重名验证 START


关于昵称可以相同的重名验证 END





SSM框架:@Transaction实现事务,登录功能,回滚,单词,重名验证,昵称【诗书画唱】的评论 (共 条)

分享到微博请遵守国家法律