Springboot配置SQL server数据库和注册登录模块
前言
因为之前电脑上已经装过SQL Server了,所以我打算直接用springboot连接SQL Server而不用Mysql,这样就不用再下载一次MySQL了,节约为数不多的电脑磁盘空间QAQ。但是y总只讲了Mysql的配置,我自己用springboot连接sql server的时候踩了许多坑,查阅网上的资料也基本上是人传人现象,有效利用信息非常的少,因此在这里写一下笔记记录一下自己的sb事迹,好歹也是能配起来跑了,如果能帮助到有需要的朋友就更好了。害,什么时候才能成为大佬呢o(╯□╰)o
配置TCP/IP环境
工欲善其事必先利其器,要成功连接SQL server,首先要给它设置一个端口。因为微软有专门的SSMS给我们做数据库操作,因此配置环境变量这一步我们可以跳过了,直接设置TCP/IP端口。首先win + R,输入compmgmt.msc
打开电脑管理设置,点击“服务与应用程序” -> SQL server配置管理器->SQL Server 网络配置 -> TCP/IP, 此时如果TCP/IP 没有启动的话,把它改为启动,然后点击“属性”,点击“IP地址”,找到“IPALL”选项,将TCP端口改成1433,将配置保存下来,
然后将SQL Native Client11
全部启动,
将SQL server服务重新启动
在此,TCP/IP端口就设置好了。
配置Springboot,添加Maven依赖
在Maven官网下找即可:https://mvnrepository.com
在pom.xml
文件中添加依赖:
Spring Boot Starter JDBC
Project Lombok
Microsoft JDBC Driver For SQL Server //这个和MySQL的驱动不一样
mybatis-plus-boot-starter
mybatis-plus-generator
//下面两个可以不急着添加
spring-boot-starter-security
jjwt-api
特别注意的是版本问题
安装Microsoft JDBC Driver For SQL Server
的时候要选择合适自己Java版本的相应的版本,比如我们项目用的是JAVA8,就要用低一点的版本,Maven官网上的最新版本适不适合我们JAVA8的,微软提供了两个版本(6.1.0.jre8和6.1.0.jre7)的驱动,我目前的开发基于Java8,所以选择了6.1.0.jre8这个版本。具体依赖如下:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>6.1.0.jre8</version>
</dependency>
我在运行springboot的时候还出现了一些小错误,导致我一直报错,好像是引入了上述的依赖后,有些东西会产生版本冲突,需要检查pom.xml
里有没有报错的地方,有的话要改掉。我的是版本兼容问题,具体改进如下
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.1</version> //添加了版本选项
</plugin>
</plugins>
</build>
配置application.properties文件
server.port=3000
spring.datasource.url=jdbc:sqlserver://localhost:1433;DatabaseName=kob
spring.datasource.username=sa
spring.datasource.password=密码
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
至此,springboot就可以成功连接到SQL server了。
什么?你说我这里比y总少了一步添加数据库源?
其实这个配不配没什么关系,因为微软提供了SSMS让我们可以像用IDEA写代码一样编辑自己的数据库,不需要在命令行输入,因此也算是可以替代在IDEA里配置数据库源的一步。当然,按照y总一样的配是没有问题的,有兴趣的朋友照着y总一样做就好了,这里就不再赘述。
Springboot中常用的模块
pojo
层:将数据库中的表对应成Java中的Classmapper
层(也叫Dao
层):将pojo
层的class
中的操作,映射成sql语句service
层:写具体的业务逻辑,组合使用mapper中的操作controller
层:负责请求转发,接受页面过来的参数,传给Service处理,接到返回值,再传给页面
实现pojo层
在backend
文件夹里新建一个包叫pojo
,在pojo
里新建一个类Users
(因为我的数据库里存储用户信息的表名叫users
)
lombok
依赖里面的注解@Data
可以帮我做繁琐的类初始化工作,即一堆方法函数。
@NoArgsConstructor
,可以帮我们生成无参构造函数
@AllArgsConstructor
,生成有参构造函数。
每一个Users
对象都对应数据库里的一行数据,对象里的各个属性依次对应数据库里的每一列的属性。
package com.popgame.backend.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Users {
private Integer id;
private String username;
private String password;
private Integer rating;
}
实现mapper层
在backend
文件夹里新建一个包叫mapper
,在mapper
里新建一个类UsersMapper
@Mapper
引入mybatis-plus
接口继承BaseMapper<Users>
一个表对应一个pojo,对应一个mapper
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.popgame.backend.pojo.Users;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UsersMapper extends BaseMapper<Users> {
}
BaseMapper<>
里面已经帮我们实现了很多接口了,mybatis-plus
可以帮我们写好很多sql语句,不用自己再手写,直接调用接口即可。
实现UserController
@RequestMapping
:将所有请求全部映射过来。请求有很多类型如:GET
,POST
。
如果想只映射相应类型的请求直接@请求名+Mapping
如: @GetMapping
, @PostMapping
如果想要利用数据库里的mapper
的话要加注解:@Autowired
条件构造器: QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
Users
表示数据库里的一行数据,也可以说是pojo里的一个对象
@PathVariable
:用来把前面@GetMapping()
路径里{}
内的参数取出来
package com.popgame.backend.controller.user;
import com.popgame.backend.mapper.UsersMapper;
import com.popgame.backend.pojo.Users;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class UserController {
@Autowired
UsersMapper usersMapper;
@RequestMapping("/user/all/")
public List<Users> getAll() {
return usersMapper.selectList(null);
}
@GetMapping("/user/{userID}/")
public Users getUser(@PathVariable int userID) {
return usersMapper.selectById(userID);
}
/*
上面也可以写成
@GetMapping("/user/{userID}/")
public Users getUser(@PathVariable int userID) {
QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id",userID);
return usersMapper.selectOne(queryWrapper);
}
*/
//查询某个区间内的用户
/*
queryWrapper.lt(“id”,userID); lt小于,le小于等于;gt 大于,ge大于等于
eg:id大于等于2小于等于3
queryWrapper.ge(“id”,2).le("id",3); 可以一直.下去加条件
@GetMapping("/user/select/")
public List<Users> getUser(@PathVariable int userID) {
QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id",userID);
return usersMapper.selectList(queryWrapper);
}
*/
@GetMapping("/user/add/{userID}/{username}/{password}/")
public String addUser(@PathVariable int userID,
@PathVariable String username,
@PathVariable String password) {
Users user = new Users(userID,username,password,0);
usersMapper.insert(user);
return "Add User Successfully";
}
@GetMapping("/user/delete/{userID}/")
public String deleteUser(@PathVariable int userID) {
usersMapper.deleteById(userID);
return "Delete User Successfully";
}
}
原理可以简单的看成是一组字符串处理,每次调用一次注解@GetMapping()
,就会自动调用下面的函数。
授权与权限判断
直接安装前面提到的 spring-boot-starter-security
依赖即可。
每次运行springboot都会产生一个随机密码,默认用户名是user
配置security
实现service.impl.UserDetailsServiceImpl
类,继承自UserDetailsService
接口,用来接入数据库信息
实现config.SecurityConfig
类,用来实现用户密码的加密存储
创建好UserDetailsServiceImpl
类后,用快捷键ALT + INS
打开重写方法,重写loadUserByUsername
会传入username
,返回对应的一个用户的用户名和密码等信息
注意要加上@Service
package com.popgame.backend.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.popgame.backend.mapper.UsersMapper;
import com.popgame.backend.pojo.Users;
import com.popgame.backend.service.impl.utils.UserDetailsImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UsersMapper usersMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username",username);
Users user = usersMapper.selectOne(queryWrapper);
if (user == null) {
throw new RuntimeException("用户不存在");
}
return new UserDetailsImpl(user);
}
}
在impl
文件夹里面新建一个软件包utils
,里面新建一个类UserDetailsImpl
,继承自UserDetails
接口
注意要把@Data @NoArgsConstructor @AllArgsConstructor
都写上
package com.popgame.backend.service.impl.utils;
import com.popgame.backend.pojo.Users;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserDetailsImpl implements UserDetails {
private Users user;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() { //是否没有被封号锁住
return true;
}
@Override
public boolean isAccountNonLocked() { //是否没有被锁定
return true;
}
@Override
public boolean isCredentialsNonExpired() { //授权是否没有过期
return true;
}
@Override
public boolean isEnabled() { //是否被启用
return true;
}
}
这样写完的话,就可以实现从数据库里面找到相应的用户名和密码登陆了,不单单只用默认的用户名和密码登录。
数据库里若密码存储的是明文的话,要在前面加上{noop}
实现密码加密存储
在Config
包里新建一个SecurityConfig
类
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Ending
希望自己和大家都码力+ +,rp + + !若有写的不好的地方也可指出交流嘻!