springboot入门教程

博客指南:

出自马士兵机构老师课程,随堂笔记,快速入门企业开发主要框架springboot

第一天:

对于一个表来说主键最好的是什么?

时间戳 毫秒 + 机器编号 + 用户编号+自定义的数组(数字) 一定要有指数

连接数据库,遍历数据库中的用户信息开发流程:

①创建springboot工程

选择国内springboot网址

勾选

web 下的Spring web

模板引擎下的 Thymeleaf

关系型数据库下的Spring Data JPA

MySQL Driver

②application.properties文件下链接数据库

数据库:

 

填写数据库用户名和密码

选定数据库链接地址

# 数据库连接地址
spring.datasource.url=jdbc:mysql://localhost:3306/demo?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
# 数据库用户名&密码:
spring.datasource.username=root
spring.datasource.password=root

③创建包repository ,并创建类UserRepository继承JpaRepository<UserInfo,Integer>

//我们能够连接数据库,去查询里面的信息
@Repository
public interface UserRepository extends JpaRepository<UserInfo,Integer> {

}

④创建数据库对应的实体类

创建info包,并在包下创建UserInfo类

@Entity  //告诉spring我是一个实体类
@Table(name = "user_info") //当前这个实体类和数据表产生关系
public class UserInfo {
    @Id//@Id 标注用于声明一个实体类的属性映射为数据库的主键列。该属性通常置于属性声明语句之前,可与声明语句同行,也可写在单独行上。 
    @GeneratedValue(strategy = GenerationType.IDENTITY)  //设定策略主键自增
    private int id;

    @Column(name = "username")
    private String username;
    @Column(name = "password")
    private String password;

    

    public UserInfo() {
    }

    public UserInfo(int id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "UserInfo{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

⑤在DemoApplicationTests类中进行测试

@Test
public void test1(){
    PageRequest of = PageRequest.of(1, 3); //索引从0开始
    Page<UserInfo> page = repository.findAll(of);
    List<UserInfo> all = page.toList();

    for (UserInfo u : all) {
         System.out.println(u);
    }
}

运行结果

 

⑥创建service包,并创建UserService接口,在service包下创建impl包并创建UserServiceImpl接口的实现类

UserService:

public interface UserService {
    //查询所有用户
    public List<UserInfo> queryAll();

    //根据id查询用户信息
    public UserInfo queryUserById(Integer id);
}

UserServiceImpl:

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserRepository repository;

    @Override
    public List<UserInfo> queryAll() {
        return repository.findAll();
    }

    @Override
    public UserInfo queryUserById(Integer id) {
        return repository.findById(id).get();  //根据id查询一个用户信息
    }
}

⑦创建web包,并创建UserController类,也就是控制器

加注解@RestController

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    UserService userService;

    //查询用户信息
    @RequestMapping("/all")
    public List<UserInfo> queryList() {
        return userService.queryAll();
    }

    //根据id查询用户信息
    @RequestMapping("/query/{id}")
    public UserInfo queryUserById(@PathVariable("id") Integer id) {
       UserInfo userInfo = userService.queryUserById(id);
		
        return userInfo;
    }
}

测试结果:

但是,实际的开发中不能这样写,需要加入一些日志进行完善

⑧添加日志

创建Logger对象 使用LoggerFactory中的getLogger()

//日志记录框架
Logger logger = LoggerFactory.getLogger("UserController");

传入日志

logger.info();

在info包下创建ResponseInfo类 这个类中我们主要是用来存放用户信息(obj)和运行代码(resultCode)和报错信息(resultMsg)

public class ResponseInfo {

    private Object obj;
    private int resultCode;
    private String resultMsg;

    public Object getObj() {
        return obj;
    }

    public void setObj(Object obj) {
        this.obj = obj;
    }

    public int getResultCode() {
        return resultCode;
    }

    public void setResultCode(int resultCode) {
        this.resultCode = resultCode;
    }

    public String getResultMsg() {
        return resultMsg;
    }

    public void setResultMsg(String resultMsg) {
        this.resultMsg = resultMsg;
    }
}

编写控制层,实现根据id查询用户信息

//根据id查询用户信息
@RequestMapping("/query/{id}")
public ResponseInfo queryUserById(@PathVariable("id") Integer id) {
    logger.info("come in queryUserById");
    ResponseInfo ri = new ResponseInfo();
    //1:参数合法性的校验   永远不要相信前端给你的数据是正确的数据,一定要做校验
    //永远不要返回空对象给前端
    if (id < 0) {
        logger.error("id param < 0");
        ri.setResultCode(6666);
        return ri;
    }
    //2.日志记录
    //3.正常的数据请求
    //4.数据日志记录
    //5.数据返回
    logger.info("Go userService select user");
    UserInfo userInfo = userService.queryUserById(id);
    logger.info("userService select user  success" + userInfo);
    ri.setObj(userInfo);
    ri.setResultCode(0000);
    return ri;
}

解决权限问题

不同的用户属于不同的角色,每个角色相对应了一些权限,有些权限某些用户是不能拥有的,所以我们要进行限制处理

创建数据库表来进行限制

我开发了一个直播后台管理系统

系统有很多功能,我从事其中的权限管理模块 权限模块我怎么开发的呢

​ 1: 用户管理 ​ 用户查询 ​ 用户删除 ​ 用户修改 ​ 用户增加 ​ 给用户绑定角色 ​

2: 角色管理 ​ 角色添加 ​ 删除 ​ 查询 ​ 修改 ​

3: 权限管理 ​ 权限查询 权限路径修改

我们一个系统有多少个权限;一定是在项目上线的时候,就确定了的; 通过初始化数据库脚本,去执行权限的添加

①创建表role_info

 

②创建用户信息和角色信息的连接表user_role

 

 

③在info包下创建role_info对应的实体类

@Entity
@Table
public class RoleInfo {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int rid;

    @Column(name = "rolename")
    private String rolename;

    public int getRid() {
        return rid;
    }

    public void setRid(int rid) {
        this.rid = rid;
    }

    public String getRolename() {
        return rolename;
    }

    public void setRolename(String rolename) {
        this.rolename = rolename;
    }
}

④在UserInfo类中添加指定第三方表

//targetEntity目标的实体类,默认的级联关系是查询,懒加载 用到的时候查询
​
@OneToMany(targetEntity = RoleInfo.class, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
//多对多,指定第三方表
@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "uid"), inverseJoinColumns = @JoinColumn(name = "rid"))
private Set<RoleInfo> roles;
​
public Set<RoleInfo> getRoles() {
    return roles;
}
​
public void setRoles(Set<RoleInfo> roles) {
    this.roles = roles;
}

即:

@Entity  //告诉spring我是一个实体类
@Table(name = "user_info") //当前这个实体类和数据表产生关系
public class UserInfo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)  //设定策略主键自增
    private int id;
​
    @Column(name = "username")
    private String username;
    @Column(name = "password")
    private String password;
​
   // targetEntity目标的实体类,默认的级联关系是查询,懒加载 用到的时候查询
​
    @OneToMany(targetEntity = RoleInfo.class, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
   // 多对多,指定第三方表
    @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "uid"), inverseJoinColumns = @JoinColumn(name = "rid"))
    private Set<RoleInfo> roles;
​
    public Set<RoleInfo> getRoles() {
        return roles;
    }
​
    public void setRoles(Set<RoleInfo> roles) {
        this.roles = roles;
    }
​
    public UserInfo() {
    }
​
    public UserInfo(int id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }
​
    public int getId() {
        return id;
    }
​
    public void setId(int id) {
        this.id = id;
    }
​
    public String getUsername() {
        return username;
    }
​
    public void setUsername(String username) {
        this.username = username;
    }
​
    public String getPassword() {
        return password;
    }
​
    public void setPassword(String password) {
        this.password = password;
    }
​
    @Override
    public String toString() {
        return "UserInfo{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

这时我们查询到的信息就包含这个表的信息

 

数据库查询语句

SELECT * FROM user_info LEFT JOIN user_role ON user_info.`id` = user_role.`uid`
			LEFT JOIN role_info ON user_role.`rid` = role_info.`rid`
WHERE user_info.`id`=1

第二天:

@SpringBootConfiguration

这个是以前spring的配置文件

application.xml配置一些节点

<bean class id >

以下是@EnableAutoConfiguration的说明

@EnableAutoConfiguration 启用自动装配

@Import 将一个普通的Java类,作为spring bean的方式导入到项目里面

 

并不是导入这一个类 点进去这个类中进入AutoConfigurationImportSelector 然后往下翻,会看见这个方法

哪个类实现了ImportSelector,重写以下的方法

 

代表所有导入的类是由这个方法决定的 String[]有多少导入多少

点getAutoConfigurationEntry

这里会看见

在这个方法体中点击getCandidateConfigurations,会看到

loadFactoryNames方法,点进去

会出现这行代码

Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");

键值对文件META-INF/spring.factories

所谓的自动装配无非就是springboot默认配置写好了很多配置

这些默认的配置不需要我们自己去写了

@Indexed注解 加入依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-indexer</artifactId>
</dependency>

使用后会在target/classes/META-INF下生成spring.components

在进行注解扫描的时候,如果类比较多就会出现启动变慢的现象,我们使用了这个注解就可以使加载速度变快,使用这个注解就将所有的Component组件都生成到列表文件中

@ComponentScan

这个注解在Spring中很重要 ,它对应XML配置中的元素。

作用:自动扫描并加载符合条件的组件或者bean , 将这个bean定义加载到IOC容器中

方法如果有返回值,所有的操作都是为返回值服务的

反射知识+注解

约定大于配置 就是默认自动配置了一些东西,不需要自己配置了,默认值就是约定

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数泛西舟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值