常用注解笔记
pojo包
@Date 简化代码
前提:需要引入lombok依赖和IDEA安装lombok插件
<!--Lombok (提供对类的字节码功能增强(类中添加
set,get,toString,...))-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
作用:这个类加了@Data注解,所有Java代码中不需要生成getters and setters
,而在编译的时候会自动生成getters and setters、equals、hashcode、toString等方法,提高了一定的开发效率
展示:
package com.cy.pj.sys.pojo;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
@Data
public class SysUser implements Serializable {
private static final long serialVersionUID = 926757209123294684L;
private Integer id;
private String username;
private String password;
private String salt;
private String mobile;
private String email;
private Integer valid=1;//默认为有效状态,0 代表无效
private Integer deptId;
private String deptName;
private List<Integer> roleIds;
private Date createdTime;
private Date modifiedTime;
private String createdUser;
private String modifiedUser;
}
@Accessors(…) 选择性的@Date (需要先添加上@Date这个注解)
需要引入lombok依赖和IDEA安装lombok插件
Accessor的中文含义是存取器,@Accessors用于配置getter和setter方法的生成结果
//fluent
//fluent的中文含义是流畅的,设置为true,则getter和setter方法的方法名都是基础属性名,且setter方法返回当前对象。如下
@Data
@Accessors(fluent = true)
public class User {
private Long id;
private String name;
// 生成的getter和setter方法如下,方法体略
public Long id() {}
public User id(Long id) {}
public String name() {}
public User name(String name) {}
}
//chain
//chain的中文含义是链式的,设置为true,则setter方法返回当前对象。如下
@Data
@Accessors(chain = true)
public class User {
private Long id;
private String name;
// 生成的setter方法如下,方法体略
public User setId(Long id) {}
public User setName(String name) {}
}
//prefix
//prefix的中文含义是前缀,用于生成getter和setter方法的字段名会忽视指定前缀(遵守驼峰命名)。如下
@Data
@Accessors(prefix = "p")
class User {
private Long pId;
private String pName;
// 生成的getter和setter方法如下,方法体略
public Long getId() {}
public void setId(Long id) {}
public String getName() {}
public void setName(String name) {}
}
@TableName(“value”) 和数据库表名实现映射
用来将指定的数据库表和 JavaBean 进行映射。该注解属性如下:
//字符串类型,不是必填,用来指定数据表名称。例如:
@TableName("user")
public class UserBean {
// ...
}
//上面实例中,将 user 数据表和 UserBean 实体进行映射。
@TableId(type = …) 主键专属
比如数据中的表中的字段是id,但是实体类是userId,那么就需要在userId上打上这个注解
/*用法
设置主键映射 value映射主键字段的名字
type 设置主键类型 主键的生成策略 (圈起来的重要)*/
/*
值 描述
AUTO 数据库自增
NONE MP set主键,雪花算法实现
INPUT 需要开发者手动赋值
ASSIGN_ID MP分配 ID,Long、Integer、String
ASSIGN_UUID 分配 UUID,Strinig
*/
@TableName("participant")
@Data
@Accessors(chain = true)
public class Participant extends BasePojo{
//开发者无需赋值,自己根据当前表中id最大值自增+1
@TableId(type = IdType.AUTO)
private Integer id;
private String name;
private String text;//参赛者自我介绍
private Integer parent_id;//外键
private Integer num;//票数
}
其它值和描述:(11条消息) @tableid注解_MyBatis-Plus 常用注解_lwieui的博客-CSDN博客
@TableField 字段填充策略
对添加了注解@TableField(fill = FieldFill.INSERT_UPDATE)的字段在进行插入(insert)和更新(update)时进行自动填充。
/*
值 描述
DEFAULT 默认不处理
INSERT 插入填充字段
UPDATE 更新填充字段
INSERT_UPDATE 插入和更新填充字段
*/
@Data
@Accessors(chain = true)//则setter方法返回当前对象
public class BasePojo implements Serializable {
@TableField(fill = FieldFill.INSERT)
private Date created_time;//创建时间
@TableField(fill = FieldFill.UPDATE)
private Date modified_time;//修改时间
}
其它值和描述:(11条消息) MybatisPlus中@TableField注解的使用_JavaAlliance-CSDN博客_@tablefield
dao包(持久层)
@Mapper 标记
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<mybatis.starter>2.1.3</mybatis.starter>
</properties>
<dependencies>
<!--Spring mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.starter}</version>
</dependency>
</dependencies>
@Mapper注释用来表示该接口类的实现类对象交给mybatis底层创建,然后交由Spring框架管理。
@Mapper
public interface UserMapper{
/**
* 查询所有用户
*/
public List<User> findAll();
}
@Select 查询
只需要在mapper中方法上加入@Select(),然后在括号中写入需要实现的sql语句即可
@Mapper
public interface SysUserDao {
//直接写,不用在Mapper.xml写,就可以实现效果
@Select("select * from sys_users where username=#{username}")
SysUser selectUserByUsername(String username);
}
@Select("select role_id from sys_user_roles where user_id=#{userId}")
List<Integer> selectRoleIdsByUserId(Integer userId);
@Select("select id,name,parentId from sys_depts")
List<Node> selectDeptTreeNodes();
@Select("select id,name,parentId from sys_menus")
List<Node> selectMenuTreeNodes();
@Select("select c.*,p.name parentName from sys_depts c left join sys_depts p on c.parentId=p.id")
List<Map<String,Object>> selectDepts();
@Delete 删除
只需要在mapper中方法上加入@Delete,然后在括号中写入需要实现的sql语句即可
@Mapper
public interface SysRoleMenuDao {
@Delete("delete from sys_role_menus where role_id=#{id}")
int deleteByRoleId(Integer id);
}
@Delete("delete from sys_user_roles where user_id=#{userId}")
int deleteByUserId(Integer userId);
@Update 修改
只需要在mapper中方法上加入@Update,然后在括号中写入需要实现的sql语句即可
@Mapper
public interface SysUserDao {
@Update("update sys_users set valid=#{valid},modifiedUser=#{modifiedUser},modifiedTime=now() where id=#{id}")
int validById(Integer id,Integer valid,String modifiedUser);
}
service包(业务层)
@Service 标注
@Service
public class VentorServiceImpl implements iVentorService{
}
@Autowired 注入关联Dao包(持久层)
@Service
public class SysDeptServiceImpl implements SysDeptService {
@Autowired
private SysDeptDao sysDeptDao;//注入之后就可以用dao包里类的方法操作数据库了
@Override
public List<Map<String, Object>> findMenus() {
List<Map<String, Object>> list=
sysDeptDao.selectDepts();
if(list==null||list.size()==0)
throw new ServiceException("没有部门信息");
return list;
}
}
@Transactional(…) 事务管理
需要明确几点:
- 默认配置下 Spring 只会回滚运行时、未检查异常(继承自 RuntimeException 的异常)或者 Error。参考这里
@Transactional
注解只能应用到 public 方法才有效
该属性用于设置需要进行回滚的异常类数组
,当方法中抛出指定异常数组中的异常时,则进行事务回滚
,Throwable是Error和Exception的父类,用来定义所有可以作为异常被抛出来的类。
package com.cy.pj.sys.service;
import com.cy.pj.common.pojo.CheckBox;
import com.cy.pj.sys.pojo.SysRole;
import java.util.List;
public interface SysRoleService {
List<SysRole> findRoles(SysRole sysRole);
SysRole findById(Integer id);
int saveRole(SysRole sysRole);
int updateRole(SysRole sysRole);
List<CheckBox> findCheckRoles();
}
//rollbackFor值是受检异常,isolation值是读取已提交数据(会出现不可重复读和幻读),timeout值是60秒
@Transactional(rollbackFor = Throwable.class,isolation = Isolation.READ_COMMITTED,timeout = 60)
@Service
public class SysRoleServiceImpl implements SysRoleService {
@Autowired
private SysRoleDao sysRoleDao;
@Autowired
private SysRoleMenuDao sysRoleMenuDao;
@Transactional(readOnly = true)//设置为true表示只读,false则表示可读写,默认值为false
@Override
public List<SysRole> findRoles(SysRole sysRole) {
return sysRoleDao.selectRoles(sysRole);
}
@Transactional(readOnly = true)
@Override
public SysRole findById(Integer id) {
return sysRoleDao.selectById(id);
}
@Transactional
@Override
public int saveRole(SysRole sysRole) {
int rows=sysRoleDao.insertRole(sysRole);
sysRoleMenuDao.insertRoleMenus(sysRole.getId(), sysRole.getMenuIds());
throw new ServiceException("save error");
// return rows;
}
@Override
public int updateRole(SysRole sysRole) {
int rows = sysRoleDao.updateRole(sysRole);
if (rows==0)throw new ServiceException("记录可能已经不存在");
sysRoleMenuDao.deleteByRoleId(sysRole.getId());
sysRoleMenuDao.insertRoleMenus(sysRole.getId(),
sysRole.getMenuIds());
return rows;
}
@Transactional(readOnly = true)
@Override
public List<CheckBox> findCheckRoles() {
return sysRoleDao.selectCheckRoles();
}
}
类设置readOnly值可以修改,特殊需要设置readOnly只读,默认是false,所以下面类写这个有点多余
@Transactional(readOnly = false,
rollbackFor = Throwable.class,
isolation = Isolation.READ_COMMITTED)
@Service
public class SysMenuServiceImpl implements SysMenuService {
@Autowired
private SysMenuDao sysMenuDao;
@Transactional(readOnly = true)
@Override
public List<SysMenu> findMenus() {
return sysMenuDao.selectMenus();
}
@Transactional(readOnly = true)
@Override
public List<Node> findMenuTreeNodes() {
return sysMenuDao.selectMenuTreeNodes();
}
@Override
public int saveMenu(SysMenu menu) {
return sysMenuDao.insertMenu(menu);
}
@Transactional(readOnly = true)
@Override
public SysMenu findById(Integer id) {
return sysMenuDao.selectById(id);
}
@Override
public int updateMenu(SysMenu menu) {
/*if (menu.getId()==null){
return sysMenuDao.insertMenu(menu);
}*/
return sysMenuDao.updateMenu(menu);
}
}
详情:(11条消息) @Transactional_走在命运的左岸-CSDN博客
详情:(11条消息) @Transactional注解详解_javaxuexilu的博客-CSDN博客
web包(控制层)
@Configuration+@Bean 定义配置类 (config包)
@Configuration注解的配置类有如下要求:
- @Configuration不可以是final类型;
- @Configuration不可以是匿名类;
- 嵌套的configuration必须是静态类。
一、用@Configuration加载spring
- 1.1、@Configuration配置spring并启动spring容器
- 1.2、@Configuration启动容器+@Bean注册Bean
- 1.3、@Configuration启动容器+@Component注册Bean
- 1.4、使用 AnnotationConfigApplicationContext 注册 AppContext 类的两种方法
- 1.5、配置Web应用程序(web.xml中配置AnnotationConfigApplicationContext)
二、组合多个配置类
- 2.1、在@configuration中引入spring的xml配置文件
- 2.2、在@configuration中引入其它注解配置
- 2.3、@configuration嵌套(嵌套的Configuration必须是静态类)
- 三、@EnableXXX注解
- 四、@Profile逻辑组配置
- 五、使用外部变量
@Configuration可理解为用spring的时候xml里面的<beans>标签
@Bean可理解为用spring的时候xml里面的<bean>标签
package com.cy.pj.sys.service.realm;
import com.cy.pj.sys.dao.SysMenuDao;
import com.cy.pj.sys.dao.SysUserDao;
import com.cy.pj.sys.pojo.SysUser;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Set;
/**
* 定义shiro realm对象,基于此对象获取用户认证和授权信息,
* 假如将来你的项目只做认证,不做授权,则继承继承AuthenticatingRealm对象即可
*/
public class ShiroRealm extends /*AuthenticatingRealm*/ AuthorizingRealm {
@Autowired
private SysUserDao sysUserDao;
/**获取并封装认证信息
* @param authenticationToken 为封装了客户端认证信息的一个令牌对象
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authenticationToken) throws AuthenticationException {
//1.获取客户端提交的用户名
String username=((UsernamePasswordToken) authenticationToken).getUsername();
//2.基于用户名查询用户信息并校验
SysUser user=sysUserDao.selectUserByUsername(username);
if(user==null)throw new UnknownAccountException();
if(user.getValid()==0)throw new LockedAccountException();
//3.封装用户信息
ByteSource credentialsSalt=
ByteSource.Util.bytes(user.getSalt());
//new SimpleByteSource(user.getSalt());
String realmName=getName();
System.out.println("realmName="+realmName);
SimpleAuthenticationInfo info=
new SimpleAuthenticationInfo(user,//principal用户身份(基于业务设置)
user.getPassword(),//hashedCredentials 已加密的凭证(密码)
credentialsSalt,//credentialsSalt (做了编码处理的加密盐对象)
realmName);//realmName
return info;
}
/**重写此方法的目的是,底层对用户输入的登录密码进行加密,需要算法*/
@Override
public CredentialsMatcher getCredentialsMatcher() {
HashedCredentialsMatcher credentialsMatcher=
new HashedCredentialsMatcher("MD5");
credentialsMatcher.setHashIterations(1);
return credentialsMatcher;
}
//也可以在构造方法中通过调用set方法设置加密策略
// public ShiroRealm(){
// HashedCredentialsMatcher credentialsMatcher=
// new HashedCredentialsMatcher("MD5");
// credentialsMatcher.setHashIterations(1);
// setCredentialsMatcher(credentialsMatcher);
// }
@Autowired
private SysMenuDao sysMenuDao;
/**获取并封装授权信息*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principalCollection) {
System.out.println("==doGetAuthorizationInfo==");
//获取登录用户
SysUser user=(SysUser)principalCollection.getPrimaryPrincipal();
//基于登录用户id,查询用户权限
Set<String> permissionSet=
sysMenuDao.selectUserPermissions(user.getId());
// if(permissionSet==null||permissionSet.isEmpty())
// throw new AuthorizationException();
//封装用户权限信息
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
info.setStringPermissions(permissionSet);
return info;
}
}
package com.cy.pj.sys.web.config;
import com.cy.pj.sys.service.realm.ShiroRealm;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ShiroConfig {
/**
* 定义Realm对象,通过此对象访问数据库中的用户和权限信息,并进行封装。
* @Bean注解描述方法时,表示方法的返回要交给spring管理,这个bean的名字默认
* 为方法名。,还可以自己起名,例如@Bean("shiroRealm")*/
@Bean
public Realm realm() {
return new ShiroRealm();
}
/**基于此对象定义过滤规则,例如哪些请求必须要认证,哪些请求不需要认证
* ShiroFilterChainDefinition 此对象中定义了若干过滤器Filter,基于这
* 些过滤器以及我们定义的过滤规则对业务进行实现。
*/
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
//定义过滤链对象
DefaultShiroFilterChainDefinition chainDefinition =
new DefaultShiroFilterChainDefinition();
//设置登录操作不需要认证(其中,anon表示匿名访问处理)
chainDefinition.addPathDefinition("/user/login/**", "anon");
//设置登出操作,登出以后要跳转到登录页面(其中,logout表示系统登出处理)
chainDefinition.addPathDefinition("/user/logout", "logout");
//设置哪些资源需要认证才可访问
//这里表示对这个url(例如/user/**),要调用过滤链中的哪个过滤器(例如authc)进行处理
//chainDefinition.addPathDefinition("/user/**", "authc");
//chainDefinition.addPathDefinition("/**", "authc");
chainDefinition.addPathDefinition("/**", "user");
//当我们访问一个需要认证以后才可以访问的资源时,但是你还没有认证,此时会跳转到登录页面
return chainDefinition;
}
/**
* 当将shiro中的注解RequiresPermissions放到控制层方法时需要配置此对象
* ,并设置对控制层方法上的注解有效(例如@GetMapping)
* @return
*/
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setUsePrefix(true);
return advisorAutoProxyCreator;
}
/**会话session设置*/
@Bean
public SessionManager sessionManager(){
DefaultWebSessionManager sessionManager=
new DefaultWebSessionManager();
//session 的超时时间
//sessionManager.setGlobalSessionTimeout(1000*60*60);//1 个小时
sessionManager.setGlobalSessionTimeout(2*60*1000);//2 分钟
//删除无效 session
sessionManager.setDeleteInvalidSessions(true);
//当客户端 cookie 被禁用是否要设置 url 重写
sessionManager.setSessionIdUrlRewritingEnabled(false);
return sessionManager;
}
/**记住我*/
@Bean
public RememberMeManager rememberMeManager(){
CookieRememberMeManager rememberMeManager=new CookieRememberMeManager();
SimpleCookie cookie=new SimpleCookie("rememberMe");
cookie.setMaxAge(7*24*60*60);//设置cookie的生命周期
rememberMeManager.setCookie(cookie);
rememberMeManager.setCipherKey(
Base64.decode("WGjHie9R114WBoCm3TAZ0g=="));
return rememberMeManager;
}
/**配置授权缓存管理器,默认应用的缓存是shiro框架内置的缓存对象,
* 缓存实现就是一个map.*/
@Bean
protected CacheManager shiroCacheManager() {
return new MemoryConstrainedCacheManager();
}
}
详情:(11条消息) @Configuration和@Bean的用法和理解_liuyinfei_java的博客-CSDN博客
@CrossOrigin 用来处理跨域请求的注解
跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。
所谓同源是指,域名,协议,端口均相同,不明白没关系,举个栗子:
http://www.123.com/index.html 调用 http://www.123.com/server.PHP (非跨域)
http://www.123.com/index.html 调用 http://www.456.com/server.php (主域名不同:123/456,跨域)
http://abc.123.com/index.html 调用 http://def.123.com/server.php(子域名不同:abc/def,跨域)
http://www.123.com:8080/index.html调用 http://www.123.com:8081/server.php(端口不同:8080/8081,跨域)
http://www.123.com/index.html 调用 https://www.123.com/server.php(协议不同:http/https,跨域)
请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。
浏览器执行javascript脚本时,会检查这个脚本属于哪个页面,如果不是同源页面,就不会被执行。
当域名www.abc.com下的js代码去访问www.def.com域名下的资源,就会受到限制。
@CrossOrigin可以处理跨域请求,让你能访问不是一个域的文件。
//前端代码:
axios.post("http://localhost:8081/crossOrigin/id", {}).then(res => {
console.log("res", res);
});
//后端代码
@RestController
public class CrossController {
// 此处的地址http://localhost:8080是要访问后台本地接口的地址即要跨域访问的域(后台本地接口8081)
@CrossOrigin(origins = "http://localhost:8080", allowCredentials = "true")
@PostMapping(value = "crossOrigin/id")
public String get() {
System.out.println("ok");
return "succses";
}
}
前端启动的vue服务端口号为8080后端启动Java服务端口号为8081
详情:注解 @CrossOrigin - 简书 (jianshu.com)
(11条消息) 注解@CrossOrigin详解_诚的博客-CSDN博客_@crossorigin
使用:@CrossOrigin 的使用 - 小学生搬砖选手 - 博客园 (cnblogs.com)
@RestController 数据直接写给浏览器
@RestController是:@ResponseBody和@Controller两个注解的合体
标注在类上,表示:这个Controller类的所有方法返回的数据直接写给浏览器。
/*@ResponseBody
@Controller*/
@RestController
public class HelloController {
@RequestMapping("/hello")
public String Hello(){
return "Hello world!";
}
}
@RequestMapping("/…/") 端口号后面的响应字段
@RequestMapping 注解在 UserController 类上,这时类的注解是相对于 Web 根目录,而方法上的是相对于类上的路径
RequestMapping注解有六个属性,下面我们把她分成三类进行说明:
1、 value, method;
value: 指定请求的实际地址,指定的地址可以是URI Template 模式(后面将会说明);
method: 指定请求的method类型, GET、POST、PUT、DELETE等;
2、 consumes,produces;
consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
3、 params,headers;
params: 指定request中必须包含某些参数值是,才让该方法处理。
headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。
@Controller
@RequestMapping("/user")
public class UserController {
//大部分情况下都不会写到方法上
@RequestMapping("/login")
public String login() {
return "success";
}
}
详情:@RequestMapping 用法详解之地址映射(转) - 红酒人生 - 博客园 (cnblogs.com)
详情:(11条消息) @RequestMapping用法详解_江南雨-CSDN博客_@requestmapping
@Autowired 注入关联service包(业务层)
@RestController
@RequestMapping("/dept/")
public class SysDeptController {
@Autowired
private SysDeptService sysDeptService;//注入之后就可以用service包里类的方法操作业务和数据库了
@GetMapping
public JsonResult doFindObjects() {
return new JsonResult(sysDeptService.findMenus());
}
@GetMapping("treeNodes")
public JsonResult doFindZTreeNodes() {
return new JsonResult(sysDeptService.findDeptTreeNodes());
}
}
@RequestBody 前端传给后端json字符串数据(@PostMapping 和 @PutMapping)
@requestBody注解常用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容,比如说:application/json或者是application/xml等。一般情况下来说常用其来处理application/json类型。@RequestBody接受的是一个json格式的字符串,一定是一个字符串。
主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);
一个请求——》只有一个@RequestBody;
一个请求——》可以有多个@RequestParam。
适用于:@PostMapping 和 @PutMapping注解的方法上
@PutMapping
public JsonResult doUpdateMenu(@RequestBody SysDept entity){
sysDeptService.updateMenu(entity);
return new JsonResult("update ok");
}
@PostMapping
public JsonResult doSaveMenu(@RequestBody SysDept entity){
sysDeptService.saveMenu(entity);
return new JsonResult("save ok");
}
@RequestParam 用于从request中接收请求的
看下面一段代码:
http://localhost:8080/springmvc/hello/101?param1=10¶m2=20
根据上面的这个URL,你可以用这样的方式来进行获取
@GetMapping("{param1}/{param2}")
public String getDetails(
@RequestParam(value="param1", required=true) String param1,
@RequestParam(value="param2", required=false) String param2){
...
}
@RequestParam 支持下面四种参数
- defaultValue 如果本次请求没有携带这个参数,或者参数为空,那么就会启用默认值
- name 绑定本次参数的名称,要跟URL上面的一样
- required 这个参数是不是必须的
- value 跟name一样的作用,是name属性的一个别名
@PathVariable 接收请求路径中占位符的值(@GetMapping、 @PatchMapping 和 @DeleteMapping)
能够识别URL
里面的一个模板,我们看下面的一个URL
适用于:@GetMapping 和 @PatchMapping注解的方法上
//http://localhost:8080/springmvc/hello/101?param1=10¶m2=20
//上面的一个url你可以这样写:
@RequestMapping("/hello/{id}")
public String getDetails(@PathVariable(value="id") String id,
@RequestParam(value="param1", required=true) String param1,
@RequestParam(value="param2", required=false) String param2){
.......
}
@GetMapping("login/{username}/{password}")
public JsonResult doLogin(@PathVariable String username,
@PathVariable String password){
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token =
new UsernamePasswordToken(username,password);
token.setRememberMe(true);
subject.login(token);
return new JsonResult("login ok");
}
@RequiresPermissions("sys:user:update")
@PatchMapping("{id}/{valid}")
public JsonResult doValidById(@PathVariable Integer id,@PathVariable Integer valid){
sysUserService.validById(id, valid);
return new JsonResult("update ok");
}
@DeleteMapping(“candidateAssess/{id}”)
public ResponseResult deleteCandidateAssess(@PathVariable String id) {
candidateAssessService.deleteCandidateAssess(id);
return new ResponseResult(“删除成功”, 200);
}
详细:(11条消息) @RequestParam,@PathParam,@PathVariable等注解区别_一年e度的夏天的专栏-CSDN博客_@pathvariable
@RequiresPermissions("") shiro框架权限判定
@CrossOrigin
@RestController
@RequestMapping("/user/")
public class SysUserController {
@Autowired
private SysUserService sysUserService;
/**
* @Transactional 描述方法时,此方法为一个事务切入点方法
* @RequiresPermissions 描述方法时,此方法为一个授权切入点方法,我们在
* 访问此方法时就需要授权,有权限则可以访问,没有权限则抛出异常。那如何
* 判定用户有没有访问此方法的权限呢?当我们在方法时,shiro框架底层会获取
* 此方法上的 @RequiresPermissions注解,进而取到注解中的权限标识,然后
* 会调用subject对象的checkPermissions(权限标识)方法检测用户是否有权限。
*
* 这个方法的权限检测调用流程分析?
* subject->SecurityManager-Authorize-->Realm
*/
@RequiresPermissions("sys:user:update")
@PatchMapping("{id}/{valid}")
public JsonResult doValidById(@PathVariable Integer id,@PathVariable Integer valid){
sysUserService.validById(id, valid);
return new JsonResult("update ok");
}
@RequiresPermissions("sys:user:view")
@GetMapping
public JsonResult doFindUsers(SysUser sysUser){
return new JsonResult(PageUtil.startPage().doSelectPageInfo(()->{
sysUserService.findUsers(sysUser);
}));
}
}
@GetMapping 处理请求方法的GET类型
@GetMapping 和 @GetMapping(value=““)的区别:
类上响应路径响应时,会直接出现
响应路径上,只能是方法上@GetMapping(“值”)时,才会响应
//旧方法:如果我们想使用传统的@RequestMapping注释实现URL处理程序,那么它应该是这样的:
@RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
//新方法可以简化为:
@GetMapping("/get/{id}")
@RestController
@RequestMapping("/dept/")
public class SysDeptController {
@Autowired
private SysDeptService sysDeptService;
//localhost:端口号/dept
@GetMapping
public JsonResult doFindObjects() {
return new JsonResult(sysDeptService.findMenus());
}
//localhost:端口号/dept/treeNodes
@GetMapping("treeNodes")
public JsonResult doFindZTreeNodes() {
return new JsonResult(sysDeptService.findDeptTreeNodes());
}
}
效果:(11条消息) @GetMapping和@GetMapping(value=““)的区别纪要_大雷-CSDN博客
@PostMapping 处理post请求
@PostMapping(value = "/user/login")
//等价于
@RequestMapping(value = "/user/login",method = RequestMethod.POST)
@RestController
@RequestMapping("/dept/")
public class SysDeptController {
@Autowired
private SysDeptService sysDeptService;
@PostMapping//处理这个方法的POST请求
public JsonResult doSaveMenu(@RequestBody SysDept entity){
sysDeptService.saveMenu(entity);
return new JsonResult("save ok");
}
}
详情:Spring MVC的@PostMapping注解 - 程序员大本营 (pianshen.com)
@PutMapping 更新请求
和PostMapping作用等同,都是用来向服务器提交信息。如果是添加信息,倾向于用@PostMapping,如果是更新信息,倾向于用@PutMapping。两者差别不是很明显。
@RestController
@RequestMapping("/dept/")
public class SysDeptController {
@Autowired
private SysDeptService sysDeptService;
@PutMapping
public JsonResult doUpdateMenu(@RequestBody SysDept entity){
sysDeptService.updateMenu(entity);
return new JsonResult("update ok");
}
}
@DeleteMapping(…) 处理删除请求(不常用)
//@DeleteMapping 删除URL映射
@DeleteMapping(“candidateAssess/{id}”)
public ResponseResult deleteCandidateAssess(@PathVariable String id) {
candidateAssessService.deleteCandidateAssess(id);
return new ResponseResult(“删除成功”, 200);
}
@DeleteMapping("/pollution/delete/{id}")
public ResponseData deletePollutionById(@PathVariable("id")String id, @RequestBody PollutionData data){
System.out.println(id);
System.out.println(data);
return new ResponseData(CodeEnum.SUCCESS.getCode(),MsgEnum.SUCCESS.getMsg(),null);
}
@PatchMapping(…) 修改少部分请求
@CrossOrigin
@RestController
@RequestMapping("/user/")
public class SysUserController {
@Autowired
private SysUserService sysUserService;
@RequiresPermissions("sys:user:update")
@PatchMapping("{id}/{valid}")
public JsonResult doValidById(@PathVariable Integer id,@PathVariable Integer valid){
sysUserService.validById(id, valid);
return new JsonResult("update ok");
}
}
公共配置模块
@Date 简化代码
前提:需要引入lombok依赖和IDEA安装lombok插件
<!--Lombok (提供对类的字节码功能增强(类中添加
set,get,toString,...))-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
作用:这个类加了@Data注解,所有Java代码中不需要生成getters and setters
,而在编译的时候会自动生成getters and setters、equals、hashcode、toString等方法,提高了一定的开发效率
展示:
package com.cy.pj.sys.pojo;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
@Data
public class SysUser implements Serializable {
private static final long serialVersionUID = 926757209123294684L;
private Integer id;
private String username;
private String password;
private String salt;
private String mobile;
private String email;
private Integer valid=1;//默认为有效状态,0 代表无效
private Integer deptId;
private String deptName;
private List<Integer> roleIds;
private Date createdTime;
private Date modifiedTime;
private String createdUser;
private String modifiedUser;
}
@NoArgsConstructor 生成一个无参数的构造方法
前提:需要引入lombok依赖和IDEA安装lombok插件
<!--Lombok (提供对类的字节码功能增强(类中添加
set,get,toString,...))-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
作用:在类里生成一个无参构造方法
@NoArgsConstructor
public class User {
private String username;
private String password;
}
// 编译后:
public class User {
private String username;
private String password;
public User() { }
}
配置资源Mapper笔记(实现持久层)
这是每个xml文件的开头
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
package com.cy.pj.sys.dao;
import com.cy.pj.common.pojo.CheckBox;
import com.cy.pj.sys.pojo.SysRole;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface SysRoleDao {
/**
* 基于条件查询角色信息
* @param sysRole
* @return
*/
List<SysRole> selectRoles(SysRole sysRole);
SysRole selectById(Integer id);
int insertRole(SysRole sysRole);
int updateRole(SysRole sysRole);
@Select("select id,name from sys_roles")
List<CheckBox> selectCheckRoles();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cy.pj.sys.dao.SysRoleDao">-- namespace的值是它继承的java持久层类
-- id值是类的方法名
-- resultType是返回值类型(返回值是java类)
<select id="selectRoles" resultType="com.cy.pj.sys.pojo.SysRole">
select *
from sys_roles
-- where、if就相当于sql语句,只不过是标签形式
<where>-- test值是 这个类型名字的值不能null和空
<if test="name!=null and name!=''">
name like concat("%",#{name},"%")
</if>
</where>
order by createdTime desc
</select>
-- resultMap最终还是要将结果映射到pojo包里的类上,type就是指定映射到哪一个pojo包的类
-- id值是自定义名,设置ResultMap的id
<resultMap id="sysRoleMenu" type="com.cy.pj.sys.pojo.SysRole">
-- 定义主键 ,非常重要。如果是多个字段,则定义多个id
-- property:主键在pojo中的属性名,column:主键在数据库中的列名
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="remark" column="remark"/>
-- 配置一对多的关系
-- property:填写pojo类中集合类类属性的名称(如果不是集合,可以采用数据库列名加上s,集合内封装的对象的属性名一定要遵循驼峰命名法,首字母不要大写)
-- javaType:填写集合类型的名称 (ArrayList....)
-- ofType(Java实体类)存储的类型;
<collection property="menuIds" ofType="integer">
<result column="menu_id"/>
</collection>
</resultMap>
<select id="selectById" resultMap="sysRoleMenu">-- resultMap值采用哪个resultMap的id
select r.id,r.name,r.remark,rm.menu_id
from sys_roles r left join sys_role_menus rm
on r.id=rm.role_id
where r.id=#{id}
</select>
<insert id="insertRole"
-- useGeneratedKeys 表示使用 insert 操作的自增主键值,
-- keyProperty 表示将获取的 自增主键值赋值给参数对象的 id 属性
parameterType="com.cy.pj.sys.pojo.SysRole" -- parameterType值是参数值是哪个pojo类
useGeneratedKeys="true"
keyProperty="id">
insert into sys_roles
(name,remark,createdTime,modifiedTime,createdUser,modifiedUser)
values
(#{name},#{remark},now(),now(),#{createdUser},#{modifiedUser})
</insert>
<!--更新角色自身信息--> -- parameterType值是参数值是哪个pojo类
<update id="updateRole" parameterType="com.cy.pj.sys.pojo.SysRole">
update sys_roles
set name=#{name},
remark=#{remark},
modifiedTime=now(),
modifiedUser=#{modifiedUser}
where id=#{id}
</update>
</mapper>
详细:(11条消息) resultMap的用法以及关联结果集映射_正在努力的陈序员的博客-CSDN博客_resultmap
详情:(11条消息) ResultMap详解_bear_wr的专栏-CSDN博客_resultmap
@Mapper
public interface SysRoleMenuDao {
@Delete("delete from sys_role_menus where role_id=#{id}")
int deleteByRoleId(Integer id);
int insertRoleMenus(Integer roleId, List<Integer> menuIds);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-使用这个注解好处:当传入的参数为多个时,可以不再用map来传参数了,并解决了传入参数为数组类型进行批量操作无法识别的问题。
<mapper namespace="com.cy.pj.sys.dao.SysRoleMenuDao">
<insert id="insertRoleMenus">
insert into sys_role_menus
(role_id,menu_id)
values
-- collection值是集合名,separator值是分段,item值是单值
<foreach collection="menuIds" separator="," item="menuId">
(#{roleId},#{menuId})
</foreach>
</insert>
</mapper>
log4j打印的sql语句:
==> Preparing: insert into ims_finance_role2menu values (?,?) , (?,?) , (?,?)
==> Parameters: 10(Integer), 200(String), 10(Integer), 2001(String), 10(Integer), 2002(String)
<== Updates: 3
一定要注意格式(重要)
<!--更新角色自身信息-->
<update id="updateRole"
parameterType="com.cy.pj.sys.pojo.SysRole"
flushCache="false">
update sys_roles
set name=#{name},
remark=#{remark},
modifiedTime=now(),
modifiedUser=#{modifiedUser}, --这里有,它会报错
where id=#{id}
</update>
<!--更新角色自身信息-->
<update id="updateRole"
parameterType="com.cy.pj.sys.pojo.SysRole"
flushCache="false">
update sys_roles
set name=#{name},
remark=#{remark},
modifiedTime=now(),
modifiedUser=#{modifiedUser} --这里没有,才可以正常执行
where id=#{id}
</update>