spring study notes

spring+spring mvc+hibernate实现简单登录注册网站

spring的一些概念

响应流程

response

依赖注入

依赖注入(Dependency Injection, DI)也被称为控制反转(Inversion of Control, IoC)。

简单介绍

如果调用者采用new方法创建被调用者以实现两个或多个对象的组合,简单说就是一个类的一段方法代码里若需要new很多个对象,就会导致代码耦合度高难调试。为此,引入了依赖注入的概念(传统方法有使用工厂模式,还是麻烦),
即一个类不需要查找或实例化(new)它们所依赖的类,对象间的依赖关系是在对象创建时由负责协调项目中各个对象的外部容器(spring)来提供并管理。也就是强调了对象间的某种依赖关系是由容器在运行期间注入调用者的,控制程序间关系的实现交给外部的容器来完成。
就我的理解,说白了,就是把类对象转化成全局变量放在一个仓库中由spring进行统一的管理。

最直观的表现

定义处:

1
2
3
@Repository
public interface UserRepository extends JpaRepository<UserEntity,Integer> {
...

使用处:

1
2
3
4
...
@Autowired
UserRepository userRepository;
...

通过annotation的方式,@Repository 把其下定义的接口丢入仓库,再由 @Autowired 自动装配到需要使用到的代码部分。

spring ApplicationContext容器

Spring ApplicationContext 容器(极客学院)

spring aop

AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。

简单的说,就是定义一些方法As并规定一些条件,另外的某些类某些方法Bs若满足这些条件,此前定义的那些方法As就会自动执行。

简单登录注册网站的实现

参考的这个网站

相关环境

  • intellij idea 2016
  • spring + spring mvc + hibernate
  • JDK 1.8
  • mysql
  • maven
  • tomcat

spring环境配置

通过maven导入依赖的包

创建maven web项目后,编辑pom.xml文件,导入spring项目所需依赖的包。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.vic</groupId>
<artifactId>springlogin</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>springlogin Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<spring.version>4.2.6.RELEASE</spring.version>
<hibernate.version>5.1.0.Final</hibernate.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.10.1.RELEASE</version>
</dependency>
...
...
</dependencies>
<build>
<finalName>springlogin</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

以上主要是通过解析 标签导入依赖包。

在web.xml中注册servlet

1
2
3
4
5
6
7
8
9
10
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

在WEB-INF文件夹下新建mvc-dispatcher-servlet.xml配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<!--指明 controller 所在包,并扫描其中的注解-->
<context:component-scan base-package="com.vic.controller"/>
<!-- 静态资源(js、image等)的访问 -->
<mvc:default-servlet-handler/>
<!-- 开启注解 -->
<mvc:annotation-driven/>
<!--ViewResolver 视图解析器-->
<!--用于支持Servlet、JSP视图解析-->
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--数据库配置-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="defaultPersistenceUnit"/>
<property name="packagesToScan" value="com.vic.model" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
<prop key="hibernate.connection.url">jdbc:mysql://localhost:3306/(database name)?useSSL=false</prop>
<prop key="hibernate.connection.username">(username)</prop>
<prop key="hibernate.connection.password">(password)</prop>
<prop key="hibernate.show_sql">false</prop>
...
...
</property>
</bean>
<!-- 表示JPA Repository所在的包 -->
<jpa:repositories base-package="com.vic.repository"/>
<!-- 事务管理 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!-- 开启事务管理注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

我的文件结构

我的文件结构

model

  • 首先在mysql里创建所需的表,然后在项目中
    Add Frameword Support–>J2EE Persistence
  • 项目左侧会出现Persistence,右键
    Generate Persistence Mapping–>By Database Schema
  • 再进行相关设置,最后idea就会根据数据库中的表自动生成model中对应的entity类。

repository

在repository包中新建UserRepository接口,放进仓库。

1
2
3
4
5
6
7
@Repository
public interface UserRepository extends JpaRepository<UserEntity,Integer> {
@Query(value = "select * from user u where u.username=?1",nativeQuery = true)
UserEntity findByUsername(String username);
}

JpaRepository本身就提供一些基本的数据库操作方法,例如

  • findAll()
  • saveAndFlush(entity)

我们还可以在接口内自定义数据库操作方法,如上所示。

@Query(value = "select * from user u where u.username=?1",nativeQuery = true)
其中@Query支持原生的mysql语句操作。

controller

在controller包中新建LoginController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
@Controller
public class LoginController {
@Autowired
UserRepository userRepository;
@RequestMapping(value = "/", method = RequestMethod.GET)
public String index() {
return "index";
}
@RequestMapping(value = "/login",method = RequestMethod.GET)
public String login(){
return "/login";
}
@RequestMapping(value = "/loginG", method = RequestMethod.GET)
public String loginG(@RequestParam("username") String username,
@RequestParam("password") String password) {
UserEntity user = userRepository.findByUsername(username);
if (user == null)
return "/loginfail";
else if (!user.getPassword().equals(password))
return "/loginfail";
else
return "/loginsuccess";
}
@RequestMapping(value = "/signup", method = RequestMethod.GET)
public String signUp() {
return "/addUser";
}
@RequestMapping(value = "/signupP", method = RequestMethod.POST)
public String signUPP(@ModelAttribute("user") UserEntity userEntity) {
userRepository.saveAndFlush(userEntity);
return "/loginsuccess";
}
}
  • 首先需要@Controller注明控制器
  • 接着通过@Autowired从仓库中取到userRepository对象
  • 然后通过@RequestMapping将http请求映射到对应函数方法
  • 最后return到相应的.jsp网页

(note. 数据库相关操作由userRepository完成)

login.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Login Page</title>
</head>
<body>
<form action="/loginG" method="get">
<input type="text" id="username" name="username" placeholder="username">
<input type="password" id="password" name="password" placeholder="password">
<button type="submit">login</button>
</form>
<a href="/signup" type="button">sign up</a>
</body>
</html>

前端向后端传值的方法

@PathVariable

举个栗子

1
2
3
4
@RequestMapping(value = "/.../{id}", method = RequestMethod.GET)
public String Func(@PathVariable int id) {
...
}

@RequestParam

对应括号中的属性名获取值

1
2
3
4
5
6
7
8
9
10
11
@RequestMapping(value = "/loginG", method = RequestMethod.GET)
public String loginG(@RequestParam("username") String username,
@RequestParam("password") String password) {
UserEntity user = userRepository.findByUsername(username);
if (user == null)
return "/loginfail";
else if (!user.getPassword().equals(password))
return "/loginfail";
else
return "/loginsuccess";
}

@ModelAttribute

直接通过form传递一个entity值

1
2
3
4
5
@RequestMapping(value = "/signupP", method = RequestMethod.POST)
public String signUPP(@ModelAttribute("user") UserEntity userEntity) {
userRepository.saveAndFlush(userEntity);
return "/loginsuccess";
}

intellij idea版本控制

从github网站将项目导入idea

  • 新建项目选择 Check out from version control–>github

idea新建的项目分享到github上

  • VCS–>import into version control–>share on github

总结

界面简陋这里就不献丑了。整个spring框架只是学了点皮毛,参照别人的经验教训恰巧能实现最基本的用户登录注册功能而已。不够系统,spring的很多特性没有涉及,实现功能的很多方法也没掌握。若要进一步深入学习的话,还是要下一番苦功夫,踏踏实实地写一个项目来的实在。

我的github项目地址