常用注解笔记

常用注解笔记

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(…) 事务管理

需要明确几点:
  1. 默认配置下 Spring 只会回滚运行时、未检查异常(继承自 RuntimeException 的异常)或者 Error。参考这里
  2. @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注解的配置类有如下要求:

  1. @Configuration不可以是final类型;
  2. @Configuration不可以是匿名类;
  3. 嵌套的configuration必须是静态类。

一、用@Configuration加载spring

  1. 1.1、@Configuration配置spring并启动spring容器
  2. 1.2、@Configuration启动容器+@Bean注册Bean
  3. 1.3、@Configuration启动容器+@Component注册Bean
  4. 1.4、使用 AnnotationConfigApplicationContext 注册 AppContext 类的两种方法
  5. 1.5、配置Web应用程序(web.xml中配置AnnotationConfigApplicationContext)

二、组合多个配置类

  1. 2.1、在@configuration中引入spring的xml配置文件
  2. 2.2、在@configuration中引入其它注解配置
  3. 2.3、@configuration嵌套(嵌套的Configuration必须是静态类)
  4. 三、@EnableXXX注解
  5. 四、@Profile逻辑组配置
  6. 五、使用外部变量

@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&param2=20

根据上面的这个URL,你可以用这样的方式来进行获取

@GetMapping("{param1}/{param2}")
public String getDetails(
    @RequestParam(value="param1", required=true) String param1,
    @RequestParam(value="param2", required=false) String param2){
    ...
}

@RequestParam 支持下面四种参数

  1. defaultValue 如果本次请求没有携带这个参数,或者参数为空,那么就会启用默认值
  2. name 绑定本次参数的名称,要跟URL上面的一样
  3. required 这个参数是不是必须的
  4. value 跟name一样的作用,是name属性的一个别名

@PathVariable 接收请求路径中占位符的值(@GetMapping、 @PatchMapping 和 @DeleteMapping)

能够识别URL里面的一个模板,我们看下面的一个URL

适用于:@GetMapping 和 @PatchMapping注解的方法上

//http://localhost:8080/springmvc/hello/101?param1=10&param2=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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值