spring04和SpringMVC课堂笔记

事务

1编程式事务

2声明式事务

基于注解的声明式事务

1,配置xml文件

<!--1加载properties配置文件信息  -->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!-- 2配置扫描包 -->
    <context:component-scan base-package="com.offcn"></context:component-scan>
    <!-- 3配置数据源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.userName}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
        <property name="driverClass" value="${jdbc.driverClass}"></property>
    </bean>
    <!-- 4配置jdbcTemplate对象 -->
    <bean class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--5配置数据源资源管理器  -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 6开启基于注解的事务支持 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

2.在service层的方法上加@Transactional注解

 3.具体操作

public class Book {
    private String isbn;
    private String book_name;
    private double price;
    public String getIsbn() {
        return isbn;
    }
    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }
    public String getBook_name() {
        return book_name;
    }
    public void setBook_name(String book_name) {
        this.book_name = book_name;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    @Override
    public String toString() {
        return "Book [isbn=" + isbn + ", book_name=" + book_name + ", price=" + price + "]";
    }
    
}
@Repository
public class BookDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    //得到书的价格
    public double selectByBookname(String isbn) {
        String sql="select price from book where isbn=?";
        return jdbcTemplate.queryForObject(sql, Double.class, isbn);
    }
    //使书的库存-1
    public boolean updateStock(String isbn) {
        String sql="update book_stock set stock = stock-1 where isbn=?";
        return jdbcTemplate.update(sql, isbn)>0?true:false;
    }
    //买书者的余额=钱数-书的价格
    public void updateBalance(String username,double price) {
        String sql = "update account set balance = balance-? where username=?";
        jdbcTemplate.update(sql,price,username);
    }
}
@Service
public class BookService {
    @Autowired
    private BookDao bookDao;
    @Transactional
    public void buyBook(String isbn,String username) {
        double price = bookDao.selectByBookname(isbn);
        boolean updateStock = bookDao.updateStock(isbn);
        bookDao.updateBalance(username, price);
        
    }
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:bean.xml")//相当于ApplicationContext context = new ClassPathXmlApplicationContext(“bean.xml”)
public class App {
    @Autowired    
    private BookService bookService;
    @Test
    public void test01() {
        bookService.buyBook("ISBN-001", "Tom");
    }
}

声明式事务的五大属性【拓展】

Propagation:传播机制一个带有事务的方法A运行在另一个带有事务的方法B的内部的时候,内层方法A是使用自己的事务还是使用外层方法B的事务。
              取值: required、requires_new、supports
              Required【默认值】:如果外层方法有事务,就用外层方法的事务.如果外层方法没有事务,内层方法就自己开一个新的事务。
              requires_new: 无论外层方法有没有事务,内层方法都用自己的事务
              Supports: 如果外层方法有事务,就用外层方法的事务.如果外层方法没有事务,内层方法就不用事务了。
              
Isolation:  隔离级别: 针对数据库的并发访问
              Read_uncommited:读未提交
              Read_commited:读已提交
              Repeatable_read:[默认值]可重复读:在一个事务内多次读取的数据表的数据是一致的。
              Serializable: 串行化读
             这四个隔离级别,按着从上到下的顺序,并发度越来越低,但是安全性越来越高。

rollbackFor:回滚属性
            事务默认只是在遇到RuntimeException才会回滚,如果遇到了编译时异常,默认是不会回滚的,如果想让编译时异常回滚,可以设置rollbackFor属性.
      同理,对于运行时异常【RuntimeException】如果不想让它回滚,可以设置norollbackFor属性 Timeout: 超时属性 事务在运行过程中,势必会占用数据库的资源,如果一个事务长时间运行,就会导致数据库的资源长时间被占用,就会影响其它事务的执行,所以为了不让某个事务长时间占用数据库资源,我们可以为事务设置超时属性,当在规定的时间内,如果一个事务还没       有执行成功,就让该事务回滚。这个时间表示多次操作数据库之间的总时间.当多次操作数据库之间的总时间
<timeout设置的时间时,执行成功,否则回滚 readOnly: 只读属性:加快访问速度 True: 在该方法中,就不能对数据库进行增删改操作。 False: 数据库的锁: 共享锁: 排它锁
Propagation:传播机制
当第二个事务里的数据有问题时,第二个事务回滚了,book表的数据不变

第一个事务正常执行了

 

 rollbackFor:回滚属性

运行时异常

 

 

 编译时异常

 

 

Timeout: 超时属性
休眠时间<超时时间时

 

 休眠时间>超时时间时

org.springframework.transaction.TransactionTimedOutException: Transaction timed out: deadline was Thu Dec 19 17:02:15 CST 2019

 

 基于xml的声明式事务

 

 把事务放进切面

SpringMVC的入门

在web.xml文件中配置springmvc的前端控制器
web.xml文件中配置springmvc的前端控制器

 
 

创建springmvc的配置文件,并配置扫描包和内部资源视图解析器

  <!-- 配置内部资源视图解析器
        作用:将逻辑视图转换为物理视图,并转发到该视图
    -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="WEB-INF/pages/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

例子:

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <a href="hello">寻找hello</a>
</body>
</html>

编写Control类

@Controller
public class UserController {
    @RequestMapping("/hello")
    public String success() {
        return "aaa";
    }
}

WEB-INF/pages/aaa.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1>这是aaa页面</h1>
</body>
</html>

问题1

/和/*的区别:

/拦截所有请求,不拦截jsp请求

/*拦截所有请求,包括jsp请求

原因:

处理*.jsp是tomcat做的事,所有项目的小web.xml都是继承大web.xml。DefaultServlet是处理除jsp和servlet外剩下的静态资源,服务器的大web.xml中有一个DefaultServlet是url-pattern=/

springMVC的配置前端控制器url-pattern=/ 。前端控制器中的/禁用了tomcat服务器中DefaultServle的/

那为什么jsp可以访问?

因为前端控制器中没有覆盖服务器中的jspServlet的配置

问题2

服务器的根目录:http://localhost:8080/
项目的根目录:http://localhost:8080/springmvc01/

相对路径:不是以/开头的路径是相对路径
绝对路径:以/开头的路径是绝对路径
      /:到底代表服务器的根目录还是项目的根目录,取决于/是被浏览器端解析还是被服务器端解析
      /被浏览器端解析,代表的是服务器的根目录:
            Response.sendRedirect(“/index.jsp”)
            页面中:html、jsp中使用html标签中/
      /被服务器端解析,代表的是项目的根目录
           Request.getRequestDispatcher(“/”).forward()
           后台配置文件中的/
           Jsp中的jsp所特有的标签: <jsp:forward “/”>
  
 

猜你喜欢

转载自www.cnblogs.com/bai3535/p/12069934.html
今日推荐