spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

时间:2022-12-30 08:17:15

在实战中学习,模仿博客园的部分功能。包括用户的注册,登陆;发表新随笔,阅读随笔;发表评论,以及定时任务等。Entity层设计3张表,分别为user表(用户),essay表(随笔)以及comment表(评论)。表结构如下:

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

项目开发采用Intellij IDEA + maven,整个项目结构如下如下图所示:

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

在项目的pom.xml文件中,导入项目需要的依赖。pom.xml内容如下所示:

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
  1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3 <modelVersion>4.0.0</modelVersion>
4 <groupId>spring_demo2</groupId>
5 <artifactId>com.everSeeker</artifactId>
6 <packaging>war</packaging>
7 <version>1.0</version>
8 <name>com.everSeeker Maven Webapp</name>
9 <url>http://maven.apache.org</url>
10
11 <properties>
12 <spring.version>4.2.4.RELEASE</spring.version>
13 <jetty.version>9.3.7.v20160115</jetty.version>
14 <slf4j.version>1.7.14</slf4j.version>
15 <jersey.version>1.19</jersey.version>
16 </properties>
17
18 <dependencies>
19
20 <!--数据库相关, mysql, mybatis-->
21 <dependency>
22 <groupId>mysql</groupId>
23 <artifactId>mysql-connector-java</artifactId>
24 <version>5.1.38</version>
25 </dependency>
26 <dependency>
27 <groupId>org.mybatis</groupId>
28 <artifactId>mybatis</artifactId>
29 <version>3.3.0</version>
30 </dependency>
31 <dependency>
32 <groupId>org.mybatis</groupId>
33 <artifactId>mybatis-spring</artifactId>
34 <version>1.2.3</version>
35 </dependency>
36
37 <!--数据源配置, dataSource-->
38 <dependency>
39 <groupId>c3p0</groupId>
40 <artifactId>c3p0</artifactId>
41 <version>0.9.1.2</version>
42 </dependency>
43
44 <!--事务相关, transcationManager-->
45 <dependency>
46 <groupId>org.springframework</groupId>
47 <artifactId>spring-jdbc</artifactId>
48 <version>${spring.version}</version>
49 </dependency>
50
51 <!--可以找到使用Spring ApplicationContext特性时所需的全部类,JDNI 所需的全部类,instrumentation组件以及校验Validation 方面的相关类。外部依赖spring-beans, (spring-aop)。-->
52 <!--提供基于注解的配置, 比如@Component, @Service, @Repository, @Controller等-->
53 <dependency>
54 <groupId>org.springframework</groupId>
55 <artifactId>spring-context</artifactId>
56 <version>${spring.version}</version>
57 </dependency>
58 <dependency>
59 <groupId>org.springframework</groupId>
60 <artifactId>spring-context-support</artifactId>
61 <version>${spring.version}</version>
62 </dependency>
63 <dependency>
64 <groupId>org.springframework</groupId>
65 <artifactId>spring-tx</artifactId>
66 <version>${spring.version}</version>
67 </dependency>
68
69 <!--测试-->
70 <dependency>
71 <groupId>junit</groupId>
72 <artifactId>junit</artifactId>
73 <version>4.12</version>
74 <scope>test</scope>
75 </dependency>
76 <dependency>
77 <groupId>org.springframework</groupId>
78 <artifactId>spring-test</artifactId>
79 <version>${spring.version}</version>
80 </dependency>
81
82 <!--任务调度-->
83 <dependency>
84 <groupId>org.quartz-scheduler</groupId>
85 <artifactId>quartz</artifactId>
86 <version>2.2.1</version>
87 </dependency>
88
89 <!--log4j && slf4j-->
90 <dependency>
91 <groupId>org.slf4j</groupId>
92 <artifactId>slf4j-api</artifactId>
93 <version>${slf4j.version}</version>
94 </dependency>
95 <dependency>
96 <groupId>org.slf4j</groupId>
97 <artifactId>slf4j-log4j12</artifactId>
98 <version>${slf4j.version}</version>
99 </dependency>
100 <dependency>
101 <groupId>org.slf4j</groupId>
102 <artifactId>jcl-over-slf4j</artifactId>
103 <version>${slf4j.version}</version>
104 <scope>runtime</scope>
105 </dependency>
106
107 <!--jetty相关-->
108 <dependency>
109 <groupId>org.eclipse.jetty</groupId>
110 <artifactId>jetty-server</artifactId>
111 <version>${jetty.version}</version>
112 </dependency>
113 <dependency>
114 <groupId>org.eclipse.jetty</groupId>
115 <artifactId>jetty-servlet</artifactId>
116 <version>${jetty.version}</version>
117 </dependency>
118 <dependency>
119 <groupId>org.eclipse.jetty</groupId>
120 <artifactId>jetty-webapp</artifactId>
121 <version>${jetty.version}</version>
122 </dependency>
123 <dependency>
124 <groupId>org.eclipse.jetty</groupId>
125 <artifactId>jetty-servlets</artifactId>
126 <version>${jetty.version}</version>
127 </dependency>
128
129 <!--jersey-->
130 <dependency>
131 <groupId>com.sun.jersey</groupId>
132 <artifactId>jersey-core</artifactId>
133 <version>${jersey.version}</version>
134 </dependency>
135 <dependency>
136 <groupId>com.sun.jersey.contribs</groupId>
137 <artifactId>jersey-spring</artifactId>
138 <version>${jersey.version}</version>
139 <exclusions>
140 <exclusion>
141 <artifactId>spring-core</artifactId>
142 <groupId>org.springframework</groupId>
143 </exclusion>
144 <exclusion>
145 <artifactId>spring-beans</artifactId>
146 <groupId>org.springframework</groupId>
147 </exclusion>
148 <exclusion>
149 <artifactId>spring-context</artifactId>
150 <groupId>org.springframework</groupId>
151 </exclusion>
152 <exclusion>
153 <artifactId>spring-web</artifactId>
154 <groupId>org.springframework</groupId>
155 </exclusion>
156 <exclusion>
157 <artifactId>spring-aop</artifactId>
158 <groupId>org.springframework</groupId>
159 </exclusion>
160 </exclusions>
161 </dependency>
162 <dependency>
163 <groupId>com.sun.jersey</groupId>
164 <artifactId>jersey-server</artifactId>
165 <version>${jersey.version}</version>
166 </dependency>
167 <dependency>
168 <groupId>com.sun.jersey</groupId>
169 <artifactId>jersey-servlet</artifactId>
170 <version>${jersey.version}</version>
171 </dependency>
172 <dependency>
173 <groupId>com.sun.jersey</groupId>
174 <artifactId>jersey-json</artifactId>
175 <version>${jersey.version}</version>
176 </dependency>
177
178 <!--用来将POJO序列化为JSON对象-->
179 <dependency>
180 <groupId>org.glassfish.jersey.media</groupId>
181 <artifactId>jersey-media-json-jackson</artifactId>
182 <version>2.22.2</version>
183 </dependency>
184
185 </dependencies>
186
187 <build>
188 <finalName>com.everSeeker</finalName>
189 </build>
190
191 </project>
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

注:以下所有介绍,第一步都是在pom.xml文件中导入相关依赖。之后文章中不再说明。

下面开始详细介绍。

一、Mybatis

1、先做准备工作。在mysql数据库中创建表。

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
 1 create database if NOT EXISTS spring_demo default character set utf8;
2 use spring_demo;
3 show engines;
4
5 create table if not exists user(id int primary key not null auto_increment, username varchar(12) not null, password varchar(20), score int, ranking int, essay_count int, UNIQUE(username)) engine=InnoDB;
6 show table status like 'user'\G;
7
8 create table if not exists essay(id int primary key not null auto_increment, title varchar(40) not null, create_date datetime, user_id int, reading_count int, comment_count int, tag varchar(40), UNIQUE(title)) engine=InnoDB;
9 show table status like 'essay'\G;
10
11 create table if not exists comment(id int PRIMARY KEY NOT NULL AUTO_INCREMENT, content TEXT, user_id int, essay_id int, comment_date DATETIME) ENGINE=InnoDB;
12 show table status like 'comment'\G;
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

sql

2、在entity目录下创建与数据库中表对应的类,以user表为例。

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
 1 package com.everSeeker.entity;
2
3 import java.io.Serializable;
4
5 /**
6 * 对象的序列化 class implements Serializable
7 * 参考文档:http://www.cnblogs.com/xudong-bupt/archive/2013/05/19/3086493.html
8 */
9 public class User implements Serializable {
10 private int id;
11 private String username;
12 private String password;
13 private int score;
14 private int ranking;
15 private int essayCount;
16
17 public User() {}
18
19 public User(String username, String password) {
20 this.username = username;
21 this.password = password;
22 score = 0;
23 ranking = 0;
24 essayCount = 0;
25 }
26
27 public int getId() {
28 return id;
29 }
30
31 public void setId(int id) {
32 this.id = id;
33 }
34
35 public String getUsername() {
36 return username;
37 }
38
39 public void setUsername(String username) {
40 this.username = username;
41 }
42
43 public String getPassword() {
44 return password;
45 }
46
47 public void setPassword(String password) {
48 this.password = password;
49 }
50
51 public int getScore() {
52 return score;
53 }
54
55 public void setScore(int score) {
56 this.score = score;
57 }
58
59 public int getRanking() {
60 return ranking;
61 }
62
63 public void setRanking(int ranking) {
64 this.ranking = ranking;
65 }
66
67 public int getEssayCount() {
68 return essayCount;
69 }
70
71 public void setEssayCount(int essayCount) {
72 this.essayCount = essayCount;
73 }
74
75 @Override
76 public String toString() {
77 return "User [id=" + id + ", username=" + username + ", password=" + password + ", score=" + score +
78 ", rankding=" + ranking + ", essayCount=" + essayCount + "]";
79 }
80 }
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

User.java

3、在dao目录下创建操作数据表的接口,以userDao为例。

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
 1 package com.everSeeker.dao;
2
3 import com.everSeeker.entity.User;
4 import org.apache.ibatis.annotations.Param;
5 import org.springframework.stereotype.Repository;
6
7 @Repository
8 public interface UserDao {
9
10 void addUser(@Param("user") User user);
11
12 User getUserById(int id);
13
14 User getUserByUsername(String username);
15
16 void updateUser(User user);
17
18 void rankingByScore();
19 }
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

UserDao.java

4、为使用mybatis管理操作数据库,首先需要设置spring与mybatis配合使用的相关配置。

mybatis.xml:在本项目中,仅仅用作给实体类配置别名。

spring-mybatis.xml:在本项目中,用来配置数据源dataSource,sqlSessionFactory等。

具体文件内容如下:

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
 1 <?xml version="1.0" encoding="UTF-8" ?>
2 <!DOCTYPE configuration
3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
4
5 <configuration>
6
7 <!--配置实体类的别名-->
8 <typeAliases>
9 <!--以下2种方法选其一即可。 第1种方法:使用typeAlias,为单个类设置别名。-->
10 <typeAlias type="com.everSeeker.entity.User" alias="User" />
11 <typeAlias type="com.everSeeker.entity.Essay" alias="Essay" />
12 <typeAlias type="com.everSeeker.entity.Comment" alias="Comment" />
13 <!--第2种方法:使用package,为包下面的所有类设置别名,默认规则为com.everSeeker.entity.User设置为User,去除前面的包名。-->
14 <!--<package name="com.everSeeker.entity" />-->
15 </typeAliases>
16
17 </configuration>
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

mybatis.xml

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
 1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:tx="http://www.springframework.org/schema/tx"
5 xmlns:p="http://www.springframework.org/schema/p"
6 xsi:schemaLocation="http://www.springframework.org/schema/beans
7 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
8 http://www.springframework.org/schema/tx
9 http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
10
11 <!--数据源配置 c3p0
12 常见的数据源实现类包有2个,一个是apache的DBCP(org.apache.commons.dbcp.BasicDataSource),另一个为C3P0。
13 -->
14 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
15 destroy-method="close">
16
17 <property name="driverClass" value="${db.mysql.driverClass}" />
18 <property name="jdbcUrl" value="${db.mysql.jdbcUrl}" />
19 <property name="user" value="${db.mysql.user}" />
20 <property name="password" value="${db.mysql.password}" />
21
22 <!--连接池中保留的最小连接数。 -->
23 <property name="minPoolSize" value="${db.minPoolSize}" />
24
25 <!--连接池中保留的最大连接数。Default: 15 -->
26 <property name="maxPoolSize" value="${db.maxPoolSize}" />
27
28 <!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
29 <property name="initialPoolSize" value="${db.initialPoolSize}" />
30
31 <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
32 <property name="maxIdleTime" value="${db.maxIdleTime}" />
33
34 <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
35 <property name="acquireIncrement" value="${db.acquireIncrement}" />
36
37 <!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements 属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。
38 如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0 -->
39 <property name="maxStatements" value="${db.maxStatements}" />
40
41 <!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
42 <property name="idleConnectionTestPeriod" value="${db.idleConnectionTestPeriod}" />
43
44 <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
45 <property name="acquireRetryAttempts" value="${db.acquireRetryAttempts}" />
46
47 <!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效 保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试
48 获取连接失败后该数据源将申明已断开并永久关闭。Default: false -->
49 <property name="breakAfterAcquireFailure" value="${db.breakAfterAcquireFailure}" />
50
51 <!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的 时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable
52 等方法来提升连接测试的性能。Default: false -->
53 <property name="testConnectionOnCheckout" value="${db.testConnectionOnCheckout}" />
54 </bean>
55
56 <!-- myBatis配置.
57 classpath和classpath*的区别,参考文档:http://blog.csdn.net/zl3450341/article/details/9306983.
58 classpath只会返回第一个匹配的资源,建议确定路径的单个文档使用classpath;匹配多个文档时使用classpath*.
59 -->
60 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
61 p:dataSource-ref="dataSource"
62 p:configLocation="classpath:mybatis.xml"
63 p:mapperLocations="classpath*:com/everSeeker/*Mapper.xml" />
64
65 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
66 <!--basePackage指定要扫描的包,在此包之下的映射器都会被搜索到。可指定多个包,包与包之间用逗号或分号分隔
67 MapperScannerConfigurer将扫描basePackage所指定包下的所有接口类(包括子包),如果他们在SQL映射文件
68 中定义过,则将他们动态定义为一个Spring Bean. -->
69 <property name="basePackage" value="com.everSeeker.dao" />
70 <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
71 <!--<property name="annotationClass" value="com.everSeeker.dao" />-->
72 </bean>
73
74 </beans>
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

spring-mybatis.xml

在spring-mybatis.xml文件中,引入了db.properties文件中的内容。

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
 1 # Database
2 db.mysql.driverClass = com.mysql.jdbc.Driver
3 db.mysql.jdbcUrl = jdbc:mysql://localhost:3306/spring_demo?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
4 db.mysql.user = root
5 db.mysql.password = 333
6 db.minPoolSize = 10
7 db.maxPoolSize = 100
8 db.initialPoolSize = 20
9 db.maxIdleTime = 60
10 db.acquireIncrement = 5
11 db.maxStatements = 100
12 db.idleConnectionTestPeriod = 60
13 db.acquireRetryAttempts = 30
14 db.breakAfterAcquireFailure = true
15 db.testConnectionOnCheckout = false
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

db.properties

最后,在spring.xml配置文件中载入与mybatis相关的配置文件。

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
 1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:context="http://www.springframework.org/schema/context"
5 xsi:schemaLocation="http://www.springframework.org/schema/beans
6 http://www.springframework.org/schema/beans/spring-beans.xsd
7 http://www.springframework.org/schema/context
8 http://www.springframework.org/schema/context/spring-context.xsd">
9
10 <!-- 加载Spring配置文件 -->
11 <context:property-placeholder location="classpath:db.properties"/>
12 <context:property-placeholder location="classpath:log4j.properties"/>
13
14 <import resource="classpath:spring-mybatis.xml"/>
15
16 <!-- 使用spring annotation自动扫描配置 -->
17 <context:component-scan base-package="com.everSeeker"/>
18 <!-- 自动注入 -->
19 <context:annotation-config/>
20
21 </beans>
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

5、准备工作已经完成,现在就可以通过在**Mapper.xml文件中以直接写sql语句的方式来操作数据库并同时实现dao层中相关类的接口了。以UserDao为例,在resources/com/everSeeker目录下创建对应的UserMapper.xml文件。

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
 1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3
4 <mapper namespace="com.everSeeker.dao.UserDao">
5 <resultMap id="ResultMapUser" type="com.everSeeker.entity.User">
6 <id column="id" property="id"/>
7 <result column="username" property="username"/>
8 <result column="password" property="password"/>
9 <result column="score" property="score"/>
10 <result column="ranking" property="ranking"/>
11 <result column="essay_count" property="essayCount"/>
12 </resultMap>
13
14 <insert id="addUser" parameterType="User">
15 INSERT INTO user(username, password, score, ranking, essay_count) VALUES(#{user.username}, #{user.password}, #{user.score}, #{user.ranking}, #{user.essayCount})
16 </insert>
17
18 <select id="getUserById" parameterType="int" resultMap="ResultMapUser">
19 SELECT * FROM user WHERE id=#{id}
20 </select>
21
22 <select id="getUserByUsername" parameterType="String" resultMap="ResultMapUser">
23 SELECT * FROM user where username=#{username}
24 </select>
25
26 <update id="updateUser" parameterType="User">
27 UPDATE user SET username=#{username}, password=#{password}, score=#{score}, ranking=#{ranking}, essay_count=#{essayCount} where id=#{id}
28 </update>
29
30 <!--在mysql中执行多条语句,可以采用存储过程,如{call proc()};也可以通过连接数据库时设置allowMultiQueries=true来实现-->
31 <update id="rankingByScore">
32 -- { call proc() }
33 SET @row=0;
34 UPDATE user SET ranking=(@row:=@row+1) ORDER BY score DESC;
35 </update>
36 </mapper>
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

6、更多关于mybatis的内容参考:

1) http://www.mybatis.org/mybatis-3/zh/index.html

2) 如果数据表中的column字段和modal(entity)中定义的类的字段不一致,比如数据库中User表有字段t_username,而在类User中定义字段username,则可以使用ResultMap来代替ResultType。详细信息可参考MyBatis中关于resultType和resultMap的区别以及MyBatis魔法堂:ResultMap详解以及MyBatis魔法堂:即学即用篇

二、事务

在spring中实现事务可以很简单。只需要配置好事务管理器,之后给需要事务处理的类或者方法直接通过@Transactional注解即可。

1、在本项目中,通过在spring-mybatis.xml文件中配置事务管理。

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
 1 <!-- 事务管理器配置, 使用jdbc事务 -->
2 <bean id="transactionManager"
3 class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
4 <property name="dataSource" ref="dataSource" />
5 </bean>
6
7 <!-- 使用annotation定义事务,对标注了@Transactional注解的bean进行处理,以织入事务管理切面.
8 默认情况下,自动使用名称为transactionManager的事务管理器。
9 proxy-target-class为true,表示spring将通过创建子类来代理业务类,需要在类路径中添加CGLib.jar类库。-->
10 <tx:annotation-driven transaction-manager="transactionManager"
11 proxy-target-class="true" />
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

2、给需要事务处理的类或者方法通过@Transactional注解。以CommentServiceImpl.java为例,对类中所有方法进行事务处理。publicNewComment方法为发表新的评论,需要在comment表中新增一条评论的记录,之后在essay表中对被评论的随笔评论数+1,同时还需要在user表中对随笔的作者score+10分,这3个操作组合成了一个原子操作,需要进行事务处理。

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
 1 package com.everSeeker.service.impl;
2
3 import com.everSeeker.dao.CommentDao;
4 import com.everSeeker.dao.EssayDao;
5 import com.everSeeker.dao.UserDao;
6 import com.everSeeker.entity.Comment;
7 import com.everSeeker.entity.Essay;
8 import com.everSeeker.entity.User;
9 import com.everSeeker.service.CommentService;
10 import org.springframework.stereotype.Service;
11 import org.springframework.transaction.annotation.Transactional;
12
13 import javax.annotation.Resource;
14
15 @Service("commentService")
16 @Transactional
17 public class CommentServiceImpl implements CommentService {
18 @Resource
19 private CommentDao commentDao;
20 @Resource
21 private EssayDao essayDao;
22 @Resource
23 private UserDao userDao;
24
25 public void publishNewComment(Comment comment) {
26 //comment表中新增一条记录
27 commentDao.addComment(comment);
28 //essay表comment_count+1
29 Essay essay = essayDao.getEssayById(comment.getEssayId());
30 if(essay != null) {
31 essay.setCommentCount(essay.getCommentCount() + 1);
32 essayDao.updateEssay(essay);
33 //user表随笔作者对应的记录score+10
34 User user = userDao.getUserById(essay.getUserId());
35 if(user != null) {
36 user.setScore(user.getScore() + 10);
37 userDao.updateUser(user);
38 }
39 }
40 }
41 }
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

三、JUnit4测试

使用JUnit4可以很方便的进行单元测试。假设我们需要对UserService类中的各个方法进行测试,只需要在test/com/everSeeker/service目录下新建测试类TestUserService即可。

1、在测试类前面新增2个注解:

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = {"/spring.xml"})

@RunWith:加载JUnit4。

@ContextConfiguration:加载spring配置文件,是一个字符串数组,可以加载多个配置文件。

2、在具体方法前新增注解@Test。

TestUserService.java关键内容如下:

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
 1 package com.everSeeker.service;
2
3 import com.everSeeker.dao.UserDao;
4 import com.everSeeker.entity.User;
5 import org.junit.Test;
6 import org.junit.runner.RunWith;
7 import org.springframework.test.annotation.Rollback;
8 import org.springframework.test.context.ContextConfiguration;
9 import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
10 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11
12 import javax.annotation.Resource;
13
14
15 @RunWith(SpringJUnit4ClassRunner.class)
16 @ContextConfiguration(locations = {"/spring.xml"})
17 public class TestUserService extends AbstractTransactionalJUnit4SpringContextTests {
18
19 @Resource
20 private UserService userService;
21
22 @Resource
23 private UserDao userDao;
24
25 /**
26 * AbstractTransactionalJUnit4SpringContextTests默认回滚。如果需要修改为不回滚设置为false即可。
27 * 默认回滚的主要目的是避免产生脏数据。但是如果数据库主键采取自增模式的话,实质上对数据库还是有一点影响。如果主键采取UUID就没这个问题。
28 */

29 @Test
30 @Rollback(false)
31 public void TestAddUser() {
32 User user = new User("ponpon7", "888888");
33 userService.addUser(user);
34 }
35
36 @Test
37 public void TestGetUserByUsername() {
38 System.out.println(userService.getUserByUsername("ppp"));
39 }
40 }
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

四、日志(log4j & slf4j)

1、关键是配置好log4j.properties文件。

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
 1 #更多详情请参考:
2 #http://www.cnblogs.com/pigtail/archive/2013/02/16/2913195.html
3 #http://it.oyksoft.com/log4j/
4
5 #此句为将等级为INFO的日志信息输出到stdout和R这两个目的地,stdout和R的定义在下面的代码,可以任意起名。
6 #等级可分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL,如果配置OFF则不打出任何信息,
7 #如果配置为INFO这样只显示INFO, WARN, ERROR的log信息,而DEBUG信息不会被显示,具体讲解可参照第三部分定义配置文件中的logger。
8 log4j.rootCategory = INFO, R, stdout
9
10 #此句为定义名为stdout的输出端是哪种类型,可以是
11 #org.apache.log4j.ConsoleAppender(控制台),
12 #org.apache.log4j.FileAppender(文件),
13 #org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
14 #org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
15 #org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
16 log4j.appender.stdout = org.apache.log4j.ConsoleAppender
17
18 #此句为定义名为stdout的输出端的layout是哪种类型,可以是
19 #org.apache.log4j.HTMLLayout(以HTML表格形式布局),
20 #org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
21 #org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
22 #org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
23 #具体讲解可参照第三部分定义配置文件中的Layout。
24 log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
25
26 #如果使用pattern布局就要指定的打印信息的具体格式ConversionPattern,打印参数如下:
27 #%m 输出代码中指定的消息
28 #%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
29 #%r 输出自应用启动到输出该log信息耗费的毫秒数
30 #%c 输出所属的类目,通常就是所在类的全名
31 #%t 输出产生该日志事件的线程名
32 #%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”
33 #%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
34 #%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。
35 #[QC]是log信息的开头,可以为任意字符,一般为项目简称。
36 log4j.appender.stdout.layout.ConversionPattern = [%p]-[%t]-[%l]-[%d{yyyyMMdd HH:mm:ss}]%n%m%n
37
38 #将日志信息存入文件中
39 log4j.appender.R = org.apache.log4j.DailyRollingFileAppender
40 log4j.appender.R.Threshold = INFO
41 log4j.appender.R.File = /Users/pingping/Projects/IdeaProjects/cnblogs/spring_demo2/logs/output.log
42 log4j.appender.R.DatePattern = '.'yyyy-MM-dd
43 log4j.appender.R.Append = true
44 log4j.appender.R.layout = org.apache.log4j.PatternLayout
45 log4j.appender.R.layout.ConversionPattern = [%p]-[%t]-[%l]-[%d{yyyyMMdd HH:mm:ss}]%n%m%n
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

更多详细信息可参考:

http://www.cnblogs.com/pigtail/archive/2013/02/16/2913195.html

http://it.oyksoft.com/log4j/

2、直接使用即可,以UserServiceImpl.java为例。

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
 1 package com.everSeeker.service.impl;
2
3 import com.everSeeker.dao.UserDao;
4 import com.everSeeker.entity.User;
5 import com.everSeeker.service.UserService;
6 import org.slf4j.Logger;
7 import org.slf4j.LoggerFactory;
8 import org.springframework.stereotype.Service;
9
10 import javax.annotation.Resource;
11
12 @Service("userService")
13 public class UserServiceImpl implements UserService {
14 @Resource
15 private UserDao userDao;
16
17 private static Logger log = LoggerFactory.getLogger(UserServiceImpl.class);
18
19 public void addUser(User user) {
20 userDao.addUser(user);
21 }
22
23 public User getUserByUsername(String username) {
24 User user = userDao.getUserByUsername(username);
25 log.info("All info about {}: \n{}", username, user);
26 return user;
27 }
28
29 public int checkUser(String username, String password) {
30 log.info("start check username: {}", username);
31 User user = userDao.getUserByUsername(username);
32 if (user == null) {
33 log.warn("username is incorrect!");
34 return 10;
35 }
36 if (!user.getPassword().equals(password)) {
37 log.warn("passowrd is incorrect!");
38 return 100;
39 }
40 log.info("{} has successed checked!", username);
41 return 1;
42 }
43 }
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

五、定时任务(Quartz & spring-task)

主要介绍目前主流的2种在指定时间执行或者按某个频率自动执行的实现方式。

1、spring-task:采用@Scheduled注解方式,配置简单,使用灵活方便。

2、quartz:配置稍微复杂,功能强大。

下面以具体代码详细说明。

首先,新创建spring-task.xml配置文件,具体内容如下:

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
 1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:task="http://www.springframework.org/schema/task"
5 xsi:schemaLocation="http://www.springframework.org/schema/beans
6 http://www.springframework.org/schema/beans/spring-beans.xsd
7 http://www.springframework.org/schema/task
8 http://www.springframework.org/schema/task/spring-task-3.0.xsd"
9 default-lazy-init="false">
10
11 <!--开启定时任务的2种方法,(1)通过spring-task,采用@Scheduled注解方式,配置简单,使用灵活方便;
12 (2)通过quartz,配置稍微复杂,功能强大 -->
14
15 <!--方法一:-->
16 <!--开启task:annotation-driven,spring可以通过注解@Scheduled来开启任务-->
17 <task:executor id="executor" pool-size="5"/>
18 <task:scheduler id="scheduler" pool-size="10"/>
19 <task:annotation-driven executor="executor" scheduler="scheduler"/>
20
21 <!--方法二:-->
22 <!--配置作业类-->
23 <bean id="quartzTask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
24 <property name="targetObject">
25 <bean class="com.everSeeker.task.QuartzTask"/>
26 </property>
27 <property name="targetMethod" value="rankingByScore"/>
28 <property name="concurrent" value="false"/>
29 </bean>
30 <!--配置触发器-->
31 <!--关于cronExpression, 请参考: http://www.cnblogs.com/yaowen/p/3779284.html-->
32 <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
33 <property name="jobDetail" ref="quartzTask"/>
34 <!--每隔10s执行一次-->
35 <property name="cronExpression" value="0/10 * * * * ?"/>
36 </bean>
37 <!--配置调度工厂-->
38 <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
39 <property name="triggers">
40 <list>
41 <ref bean="cronTrigger"/>
42 </list>
43 </property>
44 </bean>
45
46 </beans>
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

在com/everSeeker/task目录下新建2个文件QuartzTask.java以及SpringTask.java,分别用来测试quartz以及spring-task。

QuartzTask.java

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
 1 package com.everSeeker.task;
2
3 import com.everSeeker.dao.UserDao;
4 import org.springframework.stereotype.Service;
5
6 import javax.annotation.Resource;
7
8 @Service
9 public class QuartzTask {
10 @Resource
11 private UserDao userDao;
12
13 public void rankingByScore() {
14 System.out.println("通过quartz, 每隔10s执行一次任务。。。");
15 // userDao.rankingByScore();
16 }
17 }
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

SpringTask.java

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
 1 package com.everSeeker.task;
2
3 import com.everSeeker.dao.UserDao;
4 import org.springframework.scheduling.annotation.Scheduled;
5 import org.springframework.stereotype.Component;
6
7 import javax.annotation.Resource;
8
9 @Component("springTask")
10 public class SpringTask {
11
12 @Resource
13 private UserDao userDao;
14
15 @Scheduled(cron = "0/20 * * * * ?")
16 public void rankingByScoreJob() {
17 System.out.println("通过spring-task,每隔20秒执行一次任务。。。");
18 System.out.println("----------------------------------------");
19 // userDao.rankingByScore();
20 }
21 }
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

六、jetty

jetty需要定义Server, Connector以及至少一个handler, ThreadPool可选。

先定义自己的handler,内容是输出"hello jetty"。

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
 1 public class MyHandler extends AbstractHandler {
2
3 public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
4 throws IOException, ServletException {
5 response.setContentType("text/html;charset=utf-8");
6 response.setStatus(HttpServletResponse.SC_OK);
7 baseRequest.setHandled(true);
8 response.getWriter().println("<h1>Hello jetty</h1>");
9 }
10 }
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

之后在Spring配置文件中将Server,Connector以及Handler配置好即可。

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
 1 # spring-jetty.xml
2 <bean id="jetty_server" class="org.eclipse.jetty.server.Server" init-method="start" destroy-method="stop">
3
4 <!--<property name="threadPool">-->
5 <!--<bean id="defaultThreadPool" class="org.eclipse.jetty.util.thread.QueuedThreadPool">-->
6 <!--<property name="minThreads" value="10"/>-->
7 <!--<property name="maxThreads" value="100"/>-->
8 <!--</bean>-->
9 <!--</property>-->
10
11 <property name="connectors">
12 <list>
13 <bean id="Connector" class="org.eclipse.jetty.server.ServerConnector">
14 <constructor-arg name="server"><ref bean="jetty_server"/></constructor-arg>
15 <property name="port" value="8080"/>
16 </bean>
17 </list>
18 </property>
19
20 <property name="handler">
21 <bean id="handlers" class="org.eclipse.jetty.server.handler.HandlerList">
22 <property name="handlers">
23 <list>
24 <bean class="com.everSeeker.jetty.MyHandler"/>
25 <!--<bean class="com.everSeeker.jetty.RestfulHandler"/>-->
26 <bean class="org.eclipse.jetty.server.handler.DefaultHandler"/>
27 </list>
28 </property>
29 </bean>
30 </property>
31
32 </bean>
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

在网页中打开输入网址, http://localhost:8080,页面显示为"hello jetty"。

更多详情请参考:

http://www.eclipse.org/jetty/documentation/current/index.html

http://hbiao68.iteye.com/blog/2111007

http://www.cnblogs.com/windlaughing/archive/2013/06/07/3125358.html

七、Restful(jersey)

实现Restful的框架很多,本案例采用的是jersey.

首先建立一个jetty服务,并指定要处理jersey资源的包名com.everSeeker.action,然后启动jetty。

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
public class App {
public static void main(String[] args) throws Exception {
Server server = new Server(8080);
ServletHolder servlet = new ServletHolder(ServletContainer.class);
servlet.setInitParameter("com.sun.jersey.config.property.resourceConfigClass", "com.sun.jersey.api.core.PackagesResourceConfig");
servlet.setInitParameter("com.sun.jersey.config.property.packages", "com.everSeeker");
ServletContextHandler handler = new ServletContextHandler(ServletContextHandler.SESSIONS);
handler.setContextPath("/");
handler.addServlet(servlet, "/*");
server.setHandler(handler);
server.start();
server.join();
}
}
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

之后在包com.everSeeker.action下新建Restful类,以UserAction.java为例。

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)
 1 @Component
2 @Path("/user")
3 public class UserAction {
4
5 /**
6 * 如果userService不采用getBean方式获得的话,即直接写成private UserService userService,会报空指针错误。
7 * 通过debug方式查看会发现,userService=null,没有注入成功,原因暂时还不知道,请高手告知。
8 */
9 @Resource
10 private UserService userService = SpringContextUtils.getApplicationContext().getBean(UserServiceImpl.class);
11
12 /**
13 * @GET : get请求
14 * @Path : 路径,由于类的路径为/user,所以该方法的路径为/user/{username}
15 * @Produces : 返回类型。该方法为文本。
16 * @Consumes : 可以接受的类型。
17 */
18 @GET
19 @Path("{username}")
20 @Produces(MediaType.TEXT_PLAIN)
21 public String getByUsername(@PathParam("username") String username) throws Exception {
22 return userService.getUserByUsername(username).toString();
23 }
24
25 /**
26 * 返回的类型为json。需要将类User转换为json格式。本案例采用的转换方式为jackson, 在pom.xml中有说明。
27 */
28 @GET
29 @Path("json/{username}")
30 @Produces(MediaType.APPLICATION_JSON)
31 public User getUserByUsername(@PathParam("username") String username) throws Exception {
32 return userService.getUserByUsername(username);
33 }
34 }
spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)

更多信息请参考:

https://jersey.java.net/nonav/documentation/latest/index.html

http://www.zhaochao.net/index.php/2015/12/07/5/

http://waylau.com/jersey-2-spring-4-rest/

代码清单请见个人github。地址:https://github.com/ponpon7/spring_demo2

http://www.cnblogs.com/everSeeker/p/5188840.html

spring学习总结(mybatis,事务,测试JUnit4,日志log4j&slf4j,定时任务quartz&spring-task,jetty,Restful-jersey等)的更多相关文章

  1. spring 学习(一):使用 intellijIDEA 创建 maven 工程进行 Spring ioc 测试

    spring学习(一):使用 intellijIDEA 创建 maven 工程进行 Spring ioc 测试 ioc 概念 控制反转(Inversion of Control,缩写为IOC),是面向 ...

  2. spring学习 8-面试&lpar;事务,解决线程安全&rpar;

    1.介绍一下Spring的事物管理 参考:Spring 学习7 -事务 2.Spring如何处理线程并发问题    Spring使用ThreadLocal解决线程安全问题 参考:Spring学习11- ...

  3. spring mvc与mybatis事务整合

    之前公司用的是mybatis,但事务管理这块是用ejb的CMT容器管理的事务.基本原理是ejb请求进来,业务代码会创建一个mybatis的session然后放入当前线程,之后所有的方法操作涉及到数据库 ...

  4. spring学习笔记---数据库事务并发与锁详解

    多事务运行并发问题 在实际应用中,往往是一台(或多台)服务器向无数客户程序提供服务,当服务器查询数据库获取数据时,如果没有采用必要的隔离机制,可能会存在数据库事务的并发问题,下面是一些常见的并发问题分 ...

  5. 多事务运行并发问题spring学习笔记——数据库事务并发与锁详解

    多事务运行并发问题 在实际应用中,往往是一台(或多台)服务器向无数客户程序提供服务,当服务器查询数据库获取数据时,如果没有采用必要的隔离机制,可能会存在数据库事务的并发问题,下面是一些常见的并发问题分 ...

  6. Spring学习总结(12)——Druid连接池及监控在spring配置

    Druid连接池及监控在spring配置如下: <bean id="dataSource" class="com.alibaba.druid.pool.DruidD ...

  7. Struts2&plus;Spring&plus;Mybatis&plus;Junit 测试

    Struts2+Spring+Mybatis+Junit 测试 博客分类: HtmlUnit Junit Spring 测试 Mybatis  package com.action.kioskmoni ...

  8. spring&comma;mybatis事务管理配置与&commat;Transactional注解使用&lbrack;转&rsqb;

    spring,mybatis事务管理配置与@Transactional注解使用[转] spring,mybatis事务管理配置与@Transactional注解使用 概述事务管理对于企业应用来说是至关 ...

  9. spring&comma;mybatis事务管理配置与&commat;Transactional注解使用

    spring,mybatis事务管理配置与@Transactional注解使用[转]   spring,mybatis事务管理配置与@Transactional注解使用 概述事务管理对于企业应用来说是 ...

随机推荐

  1. linux问题

    make:进入目录'/opt/FriendlyARM/tiny4412/05android/android-4.1.2'target Dex: framework trouble writing ou ...

  2. F2工作流引擎Web层全新扁平化UI上线

    特点:引入Bootstrap开源UI样式和fontawesome图标集 扁平化样式使用界面更舒服,按钮主题可快速定义更换,对于集成到业主系统UI图标更加丰富. 以下截取部分图片展示,更多请联系作者登录 ...

  3. scala中的抽象类

    scala中也有和java,c#类似的抽象类,抽象类会有部分实现,也有没有实现的方法定义.抽象类最大的特征是不能直接实例化.下面我们看个例子. abstract class Animal { def ...

  4. Xcon2014 &amp&semi;&amp&semi; Geekpwn2014

    目录 . 链接器与加载器技术在保护壳上的应用 . android应用市场中的大规模漏洞挖掘 . android模拟躲避检测和应对 . 内核链表的奥秘 . 信号的可发现性 -- wifi之外我们还能做什 ...

  5. cojs QAQ的矩阵 题解报告

    题目描述非常的清晰 首先我们考虑(A*B)^m的求法,这个部分可以参考BZOJ 杰杰的女性朋友 我们不难发现(A*B)^m=A*(B*A)^(m-1)*B A*B是n*n的矩阵,而B*A是k*k的矩阵 ...

  6. Natas Wargame Level25 Writeup&lpar;头部注入&plus;POST&sol;GET注入&rpar;

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAArsAAAC8CAYAAAB4+WYTAAAABHNCSVQICAgIfAhkiAAAIABJREFUeF

  7. jquery延迟加载(懒加载)插件

    Lazy Load 是一个用 JavaScript 编写的 jQuery 插件. 它可以延迟加载长页面中的图片. 在浏览器可视区域外的图片不会被载入, 直到用户将页面滚动到它们所在的位置. 这与图片预 ...

  8. h5新增内容

    1.新的input type值 email url search tel color range number date month week time datetime datetime-local ...

  9. WPF 我的初学必备技能

    0.控件 0.1.内容控件(Content Controls) 0.2.条目控件(Items Controls) 0.3.文本控件(Text Controls) 0.4.范围控件(Range Cont ...

  10. C&num;窗体读取EXCEL存入SQL数据库

    windows窗体上放了一个Textbox1,2个按钮button1和button2~按button1选择excel文件~按button2进行相关处理 Code Snippet private  vo ...