博客指南:
出自马士兵机构老师课程,随堂笔记,快速入门企业开发主要框架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容器中
方法如果有返回值,所有的操作都是为返回值服务的
反射知识+注解
约定大于配置 就是默认自动配置了一些东西,不需要自己配置了,默认值就是约定