1、概述:是分层地JavaSE/EE应用full-stack轻量级开源框架,以IOC和AOP为内核
2、优点
(1)、方便解耦,简化开发
(2)、Aop编程支持
(3)、声明式事务的支持
(4)、方便程序的测试
(5)、方便集成各种优秀框架
(6)、降低JavaEEAPI的使用难度
(7)、java源码是经典学习范例
3、开发步骤
(1)、导入Spring开发的基本包坐标
(2)、编写Dao接口和实现类
(3)、创建Spring核心配置文件
(4)、在Spring配置文件中配置Dao接口的实现类
(5)、使用Spring的API获取Bean实例
4、依赖
org.springframework
spring-context
5.3.18
二、IOC
(一)、Bean
1、概述:是一个被实例化,组装,并通过Spring IOC容器所管理的对象
2、属性
(1)、id:在spring容器中的唯一标识
(2)、class:Bean的全类路径
(3)、scope:对象的作用范围
取值范围 | 说明 |
---|---|
singleton | 默认值,单例的;核心配值文件加载,就实例化Bean实例 |
prototype | 多例的;调用getBean是,就创建新的实例化Bean |
request | web项目中。spring创建一个Bean对象,将对象存入到request域中 |
session | web项目中。spring创建一个Bean对象,将对象存入到session域中 |
global session | web项目中。应用在Portlet环境中,若没有Portlet环境,那么global session就相当于session |
(4)、init-method:指定类型初始化方法名称,方法名称随意
(5)、destroy-method:指定类型销毁方法的名称,方法名称随意
3、子属性
(1)、property:依赖注入,set方法
①、name:属性名称
②、value:注入的普通属性值
③、ref:注入对象的引用值
(2)、constructor-arg::依赖注入,有参构造
1、无参构造方法实例化
2、工厂静态方法实例化
3、工厂实例方法实例化
(三)、依赖注入
1、概述:是Spring框架核心的IOC的具体实现
2、方式
(1)、set
①、普通类型
②、引用类型
③、集合
Java
Mysql
Python
Php
html
js
spring
springmvc
(2)、有参构造
①、普通类型
②、引用类型
③、集合
(四)、引入外部模块1、概述:将主配置文件进行分模块的拆解,通过标签引入即可 2、标签
(五)、相关API
1、ApplicationContext
(1)、概述:接口,文件的上下文
(2)、实现类
①、CalssPathXmlApplicationContext:是从类的跟路径下加载配置文件
②、FileSystemXmlApplicationContext:从磁盘路径下加载配置文件
③、AnnotaionConfigApplicationContext:注解配置容器对象是,用来读取注解的
2、getBean
(1)、getBean(String name):通过Id获取,可以不是唯一的类型,需要强制转换
(2)、getBean(Class
1、概述:提供了应用程序所需要数据的位置
2、作用:简化开发,提升性能
3、常见数据源:DBCP、C3P0、BoneCP、Druid...
4、开发步骤
(1)、导入数据源的坐标和数据驱动坐标
(2)、创建数据源对象
(3)、设置数据源的基本连接数据
(4)、使用数据源获取连接资源和归还资源
5、C3P0
(1)、导入依赖
c3p0
c3p0
0.9.1.2
(2)、传统案例
public void c3p0() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mysql");
dataSource.setUser("root");
dataSource.setPassword("root");
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
(3)、抽取配置消息
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mysql
username=root
password=root
public void c3p0() throws Exception {
ResourceBundle rb = ResourceBundle.getBundle(" jdbc");
String driver = rb.getString("driver");
String url = rb.getString("ur1");
String username = rb.getString("username");
String password = rb.getString("password");
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
(4)、spring配置数据源
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mysql
username=root
password=root
6、Druid
(1)、导入依赖
com.alibaba
druid
1.2.8
x
(2)、传统案例
public void druid() throws Exception {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/mysql");
dataSource.setUsername("root");
dataSource.setPassword("root");
DruidPooledConnection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
(3)、抽取配置消息
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mysql
username=root
password=root
public void c3p0() throws Exception {j
ResourceBundle rb = ResourceBundle.getBundle(" jdbc");
String driver = rb.getString("driver");
String url = rb.getString("ur1");
String username = rb.getString("username");
String password = rb.getString("password");
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
DruidPooledConnection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
(4)、spring配置数据源
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mysql
username=root
password=root
(七)、注解开发
1、作用:简化配置,提高开发效率
2、原始注解
注解 | 说明 |
---|---|
@Component | 使用在类上用于实例化Bean |
@Controller | 使用在web层类上用于实例化Bean |
@Service | 使用在service层类上用于实例化Bean |
@Repository | 使用在Dao层类上用于实例化Bean |
@Autowired | 使用在字段上用于根据类型依赖注入 |
@Qualifier | 结合@Autowired一起使用用于根据名称进行依赖注入 |
@Resource | 相当于@Autowired+@Qualifier,安装名称进行注入 |
@Value | 注入普通属性 |
@Scope | 标注Bean的作用范围 |
@PostConstruct | 使用在方法上标注该方法是Bean的初始化方法 |
@PreDestroy | 使用在方法上标注该方法是Bean的销毁方法 |
3、注意事项:使用注解式开发时,要在spring的核心配置文件中,加入注解扫描器
4、新注解
注解 | 说明 |
---|---|
@Configuration | 用于指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解 |
@ComponentScan | 用于指定Spring在初始化容器时要扫描的包 |
@Bean | 使用在方法上,标注将该方法的返回值存储到Spring容器中 |
@PropertySource | 用于加载properties文件中的位置 |
@Import | 用于导入其它配置类 |
1、概述:Spring框架对JDBC进行封装,方便实现对数据库 *** 作
2、开发步骤
(1)、导入spring-jdbc和spring-tx的依赖
org.springframework
spring-jdbc
5.3.18
org.springframework
spring-tx
5.3.18
(2)、创建数据库的表和实体
(3)、创建JDBCTemplate对象
(4)、执行数据库 *** 作
(5)、示例
jdbc.DriverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc.mysql://localhost:3306//user_db
jdbc.username=root
jdbc.password=root
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Book {
private String userId;
private String userName;
private String ustatus;
}
public interface BookDao{
public void add(Book book);//添加
public void updateBook(Book book);//修改
public void deleteBook(String id);//删除
public int selectCount();//返回某个值
public Book findBookInfo();//返回一个对象
public List findBookAll();//返回一个集合
public void batchAddBook(List
x
public class Test{
public static void main(String[] agrs){
ApplicationContext context = new ClassPathXmlApplicationContext("beam.xml");
BookService bookService = context.getBean("bookService",BookService.class);
bookService.addBook(new Book("1","java","在学");//添加
bookService.updateBook(new Book("1","java","完成");//修改
bookService.deleteBook(1);//删除
System.out.println(bookService.selectCount());//返回某个值
System.out.println(bookService.findOne(1));//返回一个对象
System.out.println(bookService.find());//返回一个集合
List batchArgs = new ArrayList<>();
Object[] o1 = {"1","Java","a"};
Object[] o2 = {"2","mysql","b"};
Object[] o3 = {"3","html","c"};
batchArgs.add(o1);
batchArgs.add(o2);
batchArgs.add(o3);
bookService.batchAdd(batchArgs);//批量添加
List batchArgs = new ArrayList<>();
Object[] o1 = {"js","d","1"};
Object[] o2 = {"css","e","2"};
Object[] o3 = {"mysql","f","3"};
batchArgs.add(o1);
batchArgs.add(o2);
batchArgs.add(o3);
bookService.batchUpdate(batchArgs);//批量修改
List batchArgs = new ArrayList<>();
Object[] o1 = {"1"};
Object[] o2 = {"2"};
batchArgs.add(o1);
batchArgs.add(o2);
batchArgs.add(o3);
bookService.batchUpdate(batchArgs);//批量删除
}
}
四、AOP
(一)、简介
1、概述:是通过预编译方式和运行期动态代理,实现程序功能的统一维护的一种技术
2、目的:降低业务和逻辑的耦合度,提高程序的可重用行,同时提高了开发效率
3、作用:在程序运行期间,在不修改源码的情况下对方法进行功能增强
4、优势:减少重复代码,提高开发效率,并且便于维护
5、底层原理:动态代理
6、常用的动态代理技术
(1)、JDK代理:基于接口的动态代理技术
(2)、cglib代理:基于父类的动态代理技术
7、术语
(1)、目标对象:Target,代理的目标对象
(2)、代理:Proxy,一个类被AOP织入增强时,就产生一个结果代理类
(3)、连接点:Joinpoint,那些方法可以被增强
(4)、切入点:Pointcut,实际真正增强的方法;execution([权限修饰符] [返回类型] [类全路径] [方法名称] ([参数列表]))
(5)、通知:Advice,实际增强的逻辑部分
(6)、切面:Aspect,把通知应用到切入点的过程
(7)、织入:Weaving,把增强应用到目标对象来创建新的代理对象的过程
8、注意事项
(1)、需要编写的内容;切点、通知、织入配置
(2)、AOP技术实现的内容 (3)、AOP底层使用那种代理方式
1、概述:是一个易用的功能强大的AOP框架
2、依赖
org.aspectj
aspectjweaver
1.8.4
3、xml实现
public interface TargetInterface{
public void save();
}
public class Target implements TargetInterface{
public void save(){
System.out.println("需要增强");
}
}
public class MyAspect(){
public void before(){//前置
System.out.println("before...");
}
public void afterReturning(){//后置
System.out.println("afterReturning...");
}
public void after(){//最终
System.out.println("after...");
}
public void afterThrowing()//异常
System.out.println("afterThrowing...");
}
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{//环绕
System.out.println("around...前");
proceedingJoinPoint.proceed();
System.out.println("around...后");
}
}
4、注解实现
public interface TargetInterface{
public void save();
}
@Component("target")
public class Target implements TargetInterface{
public void save(){
System.out.println("需要增强");
}
}
@Component("myAspect")
@Aspect
public class MyAspect(){
@Pointcut(value="execution(*[路径].User.add(...))")//相同切入点抽取
public void pointdemo(){}
@Before("execution(* com.spring.aop.Target.save())")
public void before(){//前置
System.out.println("before...");
}
@AfterReturning("execution(* com.spring.aop.Target.save())")
public void afterReturning(){//后置
System.out.println("afterReturning...");
}
@After("execution(* com.spring.aop.Target.save())")
public void after(){//最终
System.out.println("after...");
}
@AfterThrowing("execution(* com.spring.aop.Target.save())")
public void afterThrowing(){//异常
System.out.println("afterThrowing...");
}
@Around("execution(* com.spring.aop.Target.save())")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{//环绕
System.out.println("around...前");
proceedingJoinPoint.proceed();
System.out.println("around...后");
}
}
@Configuration
@ComponentScan(basePackages={"com.spring5"})
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class ConfigAop{}
五、事务控制
(一)、编程式事务控制
1、PlatformTransactionManager:事务管理器, *** 作事务的方法
(1)、获取事务:TransactionStatus getTransaction(TransactionDefinition definition)
(2)、提交事务:void commit(TransactionStatus status)
(3)、回滚事务:void rollback(TransactionStatus status)
2、TransactionDefinition:定义了事务的基本信息
(1)、获取事务定义名称:String getName()
(2)、获取事务的读写属性:boolean isReadOnly()
(3)、获取事务隔离级别:int getIsolationLevel()
(4)、获事务超时时间:int getTimeout()
(5)、获取事务传播行为特征:int getPropagationBehavior()
3、TransactionStatus:事务在执行过程中某个时间点上的状态信息及对应的状态 *** 作
(1)、获取事务是否处于新开启事务状态:boolean isNewTransaction()
(2)、获取事务是否处于已完成状态:boolean isCompleted()
(3)、获取事务是否处于回滚状态:boolean isRollbackOnly()
(4)、刷新事务状态:void flush()
(5)、获取事务是否具有回滚存储点:boolean hasSavepoint()
(6)、设置事务处于回滚状态:void setRollbackOnly()
1、概述:采用声明的方式来处理事务,指在配置文件中声明
2、作用
(1)、事务管理不侵入开发的组件
(2)、维护方便
3、xml
4、注解
@Configuration//配置类
@ComponentScan(basePackages="com.spring5")//组件扫描
@EnableTransactionManagement//开启事务
public class TxConfig{
@Bean
public DruidDataSource getDruidDataSource(){ //创建链接池
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://user_db");
dataSource.setUsername("root");
dataSource.setPassword("root");
return dataSource;
}
@Bean
public JdbcTemolate getJdbcTemolate(DataSource dataSource){//创建JDBCTemolate对象
JdbcTemolate jdbcTemolate = new JdbcTemolate();
//注入DataSource
JdbcTemolate.setDataSource(dataSource);
return jdbcTemolate;
}
@Bean //创建事务管理对象
public DataSourceTransacrionManager getDataSourceTransacrionManager(DataSource dataSource){
DataSourceTransacrionManager transacrionManager = new DataSourceTransacrionManager();
transacrionManager.setDataSource(dataSource);
return transacrionManager;
}
}
六、集成
(一)、web环境
1、三层架构
2、ContextLoaderListener
WebApplicationContext app = WebApplicationContextUtils.getWebApplicationContext (servletContext);
contextConfigLocation
classpath:applicationContext.xml
org.springframework.web.context.ContextLoaderListener
3、步骤
(1)、导依赖
(2)、配置ContextLoaderListener监听器
(3)、使用 WebApplicationContextUtils获取应用上下文
1、导入依赖的坐标
junit
junit
4.13.1
test
org.springframework
spring-test
5.3.18
2、使用@Runwith注解替换原来的运行期
3、使用@ContextConfiguration指定配置文件或配置类
4、使用@Autowired注入需要测试的对象
5、测试
6、示例
(1)、整合Junit4
@RunWith(SpringJUnit4ClassRunner.class)
@ContestConfiguration("classpath:bean.xml")
public class JTest4{
@Autowired
private UserService userService;
@Test
public void test(){
userService.addMoney();
}
}
(2)、整合Junit5
@ExtendWith(SprintExtension.class)
@ContextConfiguration("classpath:bean.xml")
或
@SpringJunitConfig(locations="classpath:bean.xml")
public class Jtest5{
@Autowired
private UserService userService;
@Test
public void test(){
userService.addMoney();
}
}
SpringMVC
一、简介
1、概述:是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架
2、特点
(1)、Spring家族原生产品,与IOC容器等基础设施无缝对接
(2)、基于原生地Servlet,通过了功能强大地前端控制器DispatcherServlet,对请求和响应进行统一处理
(3)、表述层各细分邻域需要解决的问题全方位覆盖,提供全面解决方案
(4)、代码清新简洁,大幅度提升开发效率
(5)、内部组件化程序高,可插拔式组件即插即用,想要什么功能配置相应组件即可
(6)、性能卓越,尤其适合现代大型、超大型互联网项目要求
3、优点
(1)、清晰地角色划分,Spring MVC 在 Model、View 和 Controller 方面提供了一个非常清晰的角色划分,这 3 个方面真正是各司其职,各负其责。
(2)、灵活的配置功能,可以把类当作 Bean 通过 XML 进行配置。
(3)、提供了大量的控制器接口和实现类,开发者可以使用 Spring 提供的控制器实现类,也可以自己实现控制器接口。
(4)、真正做到与 View 层的实现无关。它不会强制开发者使用 JSP,可以根据项目需求使用 Velocity、FreeMarker 等技术。
(5)、国际化支持
(6)、面向接口编程
(7)、与 Spring 框架无缝集成
1、开发环境
(1)、IDE:IntelliJ IDEA 2021.1.2
(2)、构建工具:apache-maven-3.8.2
(3)、服务器:apache-tomcat-8.5.70
(4)、Spring版本:
2、创建工程(手动)
4.0.0
com.springmvc
springmvc
1.0-SNAPSHOT
war
org.springframework
spring-webmvc
5.3.1
ch.qos.logback
logback-classic
1.2.3
javax.servlet
javax.servlet-api
3.1.0
provided
org.thymeleaf
thymeleaf-spring5
3.0.12.RELEASE
3、添加Web模板
(1)、创建webapp文件夹,创建web.xml文件
(2)、配置web.xml文件
springMVC
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springMVC.xml
1
springMVC
/
4、创建控制器
@Controller
public class HelloController {
@RequestMapping("/")
public String index(){
return "index";
}
@RequestMapping("/target")
public String target(){
return "target";
}
}
5、创建并配置springMVC.xml
6、访问首页和指定页面
(1)、访问首页
首页
target
(2)、访问指定页面
target
HelloWorld
7、执行流程
(1)、用户点击某个请求路径,发起一个 HTTP request 请求,该请求会被提交到 DispatcherServlet(前端控制器)
(2)、由 DispatcherServlet 请求一个或多个 HandlerMapping(处理器映射器),并返回一个执行链(HandlerExecutionChain)
(3)、DispatcherServlet 将执行链返回的 Handler 信息发送给 HandlerAdapter(处理器适配器)
(4)、HandlerAdapter 根据 Handler 信息找到并执行相应的 Handler(常称为 Controller)
(5)、Handler 执行完毕后会返回给 HandlerAdapter 一个 ModelAndView 对象(Spring MVC的底层对象,包括 Model 数据模型和 View 视图信息)
(6)、HandlerAdapter 接收到 ModelAndView 对象后,将其返回给 DispatcherServlet
(7)、DispatcherServlet 接收到 ModelAndView 对象后,会请求 ViewResolver(视图解析器)对视图进行解析
(8)、ViewResolver 根据 View 信息匹配到相应的视图结果,并返回给 DispatcherServlet
(9)、DispatcherServlet 接收到具体的 View 视图后,进行视图渲染,将 Model 中的模型数据填充到 View 视图中的 request 域,生成最终的 View(视图)
(10)、视图负责将结果显示到浏览器(客户端)
1、作用:将请求和处理请求的控制器方法进行关联
2、位置
(1)、类:设置映射请求的路径的初始信息
(2)、方法:设置映射请求路径的具体信息
3、属性
(1)、value:通过请求的地址匹配进行映射,可以匹配多个地址进行映射,且必须设置该属性
@RequestMapping(value="/userAdd")
public String userAdd(){
return "add";
}
(2)、method:通过请求方式匹配请求映射,可以匹配多种请求方式,不满足就报:405 - Request method "POST" not supported
@RequestMapping(value="/userAdd",method=RequestMethod.POST)
public String userAdd(){
return "add";
}
(3)、params:通过请求的请求参数匹配请求,可以匹配多种请求参数,且要同时满足
@RequestMapping(value="/userAdd",params={"username"})
public String userAdd(){
return "add";
}
(4)、headers:通过请求的请求头信息匹配映射
@RequestMapping(value="/userAdd",headers="Host:localhost:8080")
public String userAdd(){
return "add";
}
4、派生注解
(1)、@GetMapping:处理get请求映射
(2)、@PostMapping:处理post请求映射
(3)、@DeleteMapping:处理delete请求映射
(4)、@PutMapping:处理put请求映射
1、作用:将请求参数和控制器方法的形参进行映射关系
2、示例
@RequestMapping(value="/userAdd")
public String userAdd(@RequestParam("name")String username,@RequestParam("pwd")String password){
return "add";
}
(三)、@RequestHesder
1、作用:将请求头信息和控制器方法的形参进行映射关系
2、示例
@RequestMapping(value="/userAdd")
public String userAdd(@RequestHesder("host")String username){
return "add";
}
(四)、@CookieValue
1、作用:将cookie数据信息和控制器方法的形参进行映射关系
2、示例
@RequestMapping(value="/userAdd")
public String userAdd(@RequestHesder("cookie")String cookie){
return "add";
}
(五)、@RequestBody
1、作用:将请求的请求体和当前注解所标识的形参赋值
2、示例
@RequestMapping("/param")
public String testRequestBody(@RequestBody String requestBody){
System.out.println("requestBody"+requestBody);
return "param";
}
(六)、RequestEnitty
1、作用:在控制器方法的形参设置该类型时,请求报文信息会自动赋值
2、示例
@RequestMapping("/param")
public String testRequestEntity(RequestEntity requestEntity){
System.out.println("请求头"+requestEntity.getHeaders());
System.out.println("请求体"+requestEntity.getBodty());
return "param";
}
(七)、@ResponseBody
1、作用:在控制器方法上标识,可以将方法的返回值直接作为响应体响应打浏览器中
2、示例
@RequestMapping("/param")
@ResponseBody
public String testResponseBody(){
return "param";
}
(八)、@RestController
1、作用:给当前类所有的方法加上@ResponseBody
2、示例
@RestController
public class EmployeeController {
@RequestMapping("/param")
public String testResponseBody(){
return "param";
}
@RequestMapping("/param")
public String testRequestEntity(RequestEntity requestEntity){
System.out.println("请求头"+requestEntity.getHeaders());
System.out.println("请求体"+requestEntity.getBodty());
return "param";
}
}
(九)、ResponseEntity
1、作用:用于控制器方法的返回值类型,该类型是返回值就是响应到浏览器的响应报文
2、示例
@RequestMapping("/hello")
public ResponseEntity hello() {
return new ResponseEntity<>("Hello World!", HttpStatus.OK);
}
四、域对象
(一)、Repuest
1、servletAPI
@RequestMapping("/param")
public String testServletAPI(HttpServletRequest request){
request.setAttribute("Scoke","servletAPI");
return "param";
}
2、ModelAndView
@RequestMapping("/param")
public ModelAndView testModelAndViewI(){
//创建ModelAndView对象
ModelAndView mav = new ModelAndView();
//向请求域共享数据
mav.addObject("Scoke","ModelAndView");
//设置视图,实现页面跳转
mav.setViewName("param");
return mav;
}
3、Model
@RequestMapping("/param")
public String testModel(Model model){
model.addAttriubute("Scoke","Model");
return "param";
}
4、Map
@RequestMapping("/param")
public String testMap(Map map){
map.put("Scoke","Map");
return "param";
}
5、ModelMap
@RequestMapping("/param")
public String testModelMap(ModelMap modelMap){
modelMap.addAttriubute("Scoke","ModelMap");
return "param";
}
(二)、Session
@RequestMapping("/param")
public String testSession(HttpSession Session){
session.setAttriubute("Scoke","Session");
return "param";
}
(三)、Application
@RequestMapping("/param")
public String testApplication(HttpSession Session){
ServletContext application = session.getServletContext();
application.setAttriubute("Scoke","Application");
return "param";
}
五、视图
(一)、Thymeleaf
@RequestMapping("/param")
public String testThymeleaf(){
return "param";
}
(二)、InternalResourceView
@RequestMapping("/param")
public String testForward(){
return "forward:/param";
}
(三)、RedirectView
@RequestMapping("/param")
public String testRedirectf(){
return "redirect:/param";
}
(四)、view-controller
(六)、InternalResourceViewResolver
六、RESTFurl
(一)、简介
1、概述:是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用XML格式定义或JSON格式定义
2、特点
(1)、每一个URI代表1种资源;
(2)、客户端使用GET、POST、PUT、DELETE4个表示 *** 作方式的动词对服务端资源进行 *** 作
(3)、通过 *** 作资源的表现形式来 *** 作资源;
(4)、资源的表现形式是XML或者HTML
(5)、客户端与服务端之间的交互在请求之间是无状态的
3、资源:看待服务器的方式,即将服务器看作很多高校的资源组成
4、资源表述:是一段对于资源在某个特定时刻的状态的描述
5、状态转移:指客户端和服务器端之间转移,实现 *** 作资源的目的
1、基本 *** 作:GET(获取)、POST(新建)、PUT(更新)、DELETE(删除)
2、示例
@Controller
public class EmployeeController {
@Autowired
private EmployeeDao employeeDao;
//查询所有的信息
@RequestMapping(value = "/employee",method = RequestMethod.GET)
public String getAllEmployee(Model model){
Collection employeesList = employeeDao.getAll();
model.addAttribute("employeesList",employeesList);
return "employee_List";
}
//根据Id进行删除
@RequestMapping(value = "/employee/{id}",method = RequestMethod.DELETE)
public String deleteEmployee(@PathVariable("id")Integer id){
employeeDao.delete(id);
return "redirect:/employee";
}
//添加信息
@RequestMapping(value = "/employee",method = RequestMethod.POST)
public String addEmployee(Employee employee){
employeeDao.save(employee);
return "redirect:/employee";
}
//根据Id查询信息
@RequestMapping(value = "/employee/{id}",method = RequestMethod.GET)
public String getEmployeeById(@PathVariable("id")Integer id,Model model){
Employee employee = employeeDao.get(id);
model.addAttribute("employee",employee);
return "employee_update";
}
//修改信息
@RequestMapping(value = "/employee",method = RequestMethod.PUT)
public String updateEmployee(Employee employee){
employeeDao.save(employee);
return "redirect:/employee";
}
}
3、注意事项:使用PUT和DELETE时要加入配置HiddenHttpMethodFilter过滤器,还要开始的请求方式必须为POST,还要设置_method属性,值为put或delete,大小写无所谓
HiddenHttpMethodFilter
org.springframework.web.filter.HiddenHttpMethodFilter
HiddenHttpMethodFilter
/*
七、静态资源
八、HttpMessageConverter
1、概述:请求报文转换器
2、作用:将请求报文转换为java对象,或将java对象转换为响应报文
3、使用:提供了两个注解和两个类型@RequestBody、@ResponseBody、RequestEnitty、ResponseEntity
4、处理JSON数据
(1)、导入依赖
com.fasterxml.jackson.core
jackson-databind
2.13.1
(2)、加入注解驱动
(3)、在方法上加入@ResponseBody注解
(4)、测试
5、处理ajax
(1)、下载vue、axios的js文件
vue ---> https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js
axios --> https://unpkg.com/axios/dist/axios.min.js
(2)、创建Vue实例
new Vue({
el:"#app",
methods:{
textAxios:function (ecent){
axios({
method:"post",
url:event.target.href,
params:{
username:"admin",
password:"123456"
}
}).then(function (response){
alert(response.data);
});
ecent.preventDefault();
}
}
});
(3)、测试
九、文件下载上传1、文件下载
@RequestMapping("/textDown")
public ResponseEntity testResponseEntity(HttpSession session){
ResponseEntity responseEntity = null;
try {
//获取ServletContext对象
ServletContext servletContext = session.getServletContext();
//获取服务器中的文件的真实路径
String realPath = servletContext.getRealPath("/static/img/1.jpg");
System.out.println(realPath);
//创建输入流
InputStream is = new FileInputStream(realPath);
//创建字节数组
byte[] bytes = new byte[is.available()];
//将流读取到数组
is.read(bytes);
//创建响应头信息
MultiValueMap multiValueMap = new HttpHeaders();
//设置下载方式和下载文件的名字
multiValueMap.add("Content-Disposition","attachment;filename=1.jpg");
//设置相应状态码
HttpStatus status = HttpStatus.OK;
//创建 ResponseEntity对象
responseEntity = new ResponseEntity(bytes,multiValueMap,status);
//关闭流
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return responseEntity;
}
2、文件上传
(1)、导入依赖
commons-fileupload
commons-fileupload
1.3.1
(2)、配置文件上传解析器
(3)、上传方法
@RequestMapping("/textUp")
public void textUp(MultipartFile multipartFile, HttpSession session) {
try {
//获取文件名字
String fileName = multipartFile.getOriginalFilename();
//获取文件的后缀名
String suffixName = fileName.substring(fileName.lastIndexOf("."));
//将UUID作为文件名
String uuid = UUID.randomUUID().toString().replace("-","");
//新的文件名
String newName = uuid + suffixName;
//获取ServletContext对象
ServletContext servletContext = session.getServletContext();
//获取服务器中的文件的真实路径
String realPath = servletContext.getRealPath("photo");
File file = new File(realPath);
//判断目录是否存在
if (!file.exists()) {
//不存在就创建
file.mkdir();
}
//拼接名字
String finalPath = realPath + File.separator + newName;
//资源转移
multipartFile.transferTo(new File(fileName));
} catch (Exception e) {
e.printStackTrace();
}
}
十、拦截器
1、作用:用于拦截控制器方法的执行
2、示例
(1)、实现拦截器
@Component
public class FirstInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("方法执行之前");
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("方法执行之后");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("视图渲染之后");
}
}
(2)、配置拦截器
3、多个拦截器的执行的步骤
(1)、若每个拦截器的preHandle()都返回true,此时多个拦截器的执行顺序和拦截器在SpringMVC的配置文件的配置顺序有关。preHandle()会按照配置的顺序执行,而postHandle()和afterCompletion()会按照配置的反序执行
(2)、若某个拦截器的preHandle()返回false,preHandle()返回false和它之前的拦截器的preHandle()都会执行,postHandle()都不执行,返回false的拦截器之前的afterCompletion()会执行
1、基于配置文件
error
2、基于注解
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler(ArithmeticException.class)
public String handleArithmeticException(Exception ex, Model model){
model.addAttribute("ex",ex);
return "error";
}
}
十四、注解配置
1、配置web.xml
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.Filter;
/**
* @author: 海
* @version: 1.0
*/
public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer {
/**
* 指定spring配置类
* @return: java.lang.Class>[]
*/
@Override
protected Class>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
/**
* 指定springmvc的配置类
* @return: java.lang.Class>[]
*/
@Override
protected Class>[] getServletConfigClasses() {
return new Class[]{WebConfig.class};
}
/**
* 指定DispatcherServlet的映射规则
* @return: java.lang.String[]
*/
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
/**
* 指定Filter的配置类
* @return: javax.servlet.Filter[]
*/
@Override
protected Filter[] getServletFilters() {
// 处理中文乱码问题
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceResponseEncoding(true);
// 将请求方式转换
HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
return new Filter[]{characterEncodingFilter, hiddenHttpMethodFilter};
}
}
2、创建spring.xml的配置类
import org.springframework.context.annotation.Configuration;
/**
* @author: 海
* @version: 1.0
*/
@Configuration
public class SpringConfig {
}
3、配置springmvc.xml的配置类
import com.springmvc.hander.FirstInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ITemplateResolver;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
import javax.servlet.ServletContext;
import java.util.List;
import java.util.Properties;
/**
* @author: 海
* @version: 1.0
*/
@Configuration
@ComponentScan("com.springmvc")
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
/**
* default - servlet - handler
*/
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
/**
* 拦截器
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
FirstInterceptor firstInterceptor = new FirstInterceptor();
registry.addInterceptor(firstInterceptor).addPathPatterns("/**");
}
/**
* 视图控制器
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("").setViewName("");
}
/**
* 文件上传解析器
*/
@Bean
public MultipartResolver multipartResolver() {
return new CommonsMultipartResolver();
}
/**
* 异常处理器
*/
@Override
public void configureHandlerExceptionResolvers(List resolvers) {
SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver();
Properties properties = new Properties();
properties.setProperty("java.lang.ArithmeticException", "error");
simpleMappingExceptionResolver.setExceptionMappings(properties);
simpleMappingExceptionResolver.setExceptionAttribute("exception");
resolvers.add(simpleMappingExceptionResolver);
}
/**
* 配置生成模板解析器
*/
@Bean
public ITemplateResolver templateResolver() {
WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
if(webApplicationContext==null){
return null;
}
ServletContext servletContext = webApplicationContext.getServletContext();
if(servletContext==null){
return null;
}
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setTemplateMode(TemplateMode.HTML);
return templateResolver;
}
/**
* 生成模板引擎为模板注入模板解析器
*/
@Bean
public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
return templateEngine;
}
/**
* 生成视图解析器并为解析器注入模版引擎
*/
@Bean
public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setCharacterEncoding("UTF-8");
viewResolver.setTemplateEngine(templateEngine);
return viewResolver;
}
}
十五、SpringMVC的常用组件
1、DispatcherServlet:前端控制器
(1)、是否需要工程师开发:不需要
(2)、作用:统一处理请求和响应,整个流程控制的中心,由它调用其他组件处理用户的请求
2、HandlerMapping:处理器映射器
(1)、是否需要工程师开发:不需要
(2)、作用:根据请求的url、method等信息查找Handler,即控制器方法
3、Handler:处理器
(1)、是否需要工程师开发:需要
(2)、作用:在DispatcherServlet的控制下Handler对具体的用户请求进行处理
4、HandlerAdapter:处理器适配器
(1)、是否需要工程师开发:不需要
(2)、作用:通过HandlerAapter对处理器进行执行
5、ViewResolver:视图解析器
(1)、是否需要工程师开发:不需要
(2)、作用:进行视图解析、的到响应的视图
6、View:视图
(1)、是否需要工程师开发:不需要
(2)、作用:将模型数据通过页面展示给用户
1、概述:是一个基于Java的持久层框架
2、特性
(1)、是支持定制化SQL、存储过程以及高级映射的优秀的持久层框架
(2)、避免了几乎所有的JDBC代码和手动设置参数以及获取结果集
(3)、可以使用简单的XML或注解用于配置和原始映射,将接口和java的POJO映射成数据库的记录
(4)、是一个半启动的ORM框架
3、官网:Mybatis
4、与其它持久化层技术对比
(1)、JDBC
①、SQL夹杂在Java代码中,耦合度高,导致硬编码内伤
②、维护不易且实际开发需求中SQL有变化,频繁修改的情况多见
③、代码冗长,开发效率低
(2)、Hibemate和JPA
①、 *** 作简便,开发效率高
②、程序中的长难度复杂的SQL需要绕过框架
③、内部自动生产的SQL,不容易做特殊优化
④、基于全映射的全自动框架,大量字段的POJO进行部分映射比较困难
⑤、反射 *** 作太多,导致数据性能下降
(3)、Mybatis
①、轻量级,性能出色
②、SQL和java代码分开,功能边界清晰,java代码专注业务、SQL语句专注数据
③、开发效率稍逊Hibemate,但是能完全接受
5、相应的API
(1)、SqlSessionFactoryBuilder:工厂构建器
(2)、SqlSessionFactory:获取工厂对象
①、openSession():默认开启开启一个事务,但要手动提交
②、openSession(boolean auto):为true时,自动提交
(3)、SqlSession:会话对象
①、查询单个:
②、查询全部:
③、插入数据:int insert (String statement, Object parame ter)
④、修改数据:int update (String statement, Object parameter)
⑤、删除数据:int delete (String statement, Object parameter)
⑥、提交事务:void commit()
⑦、回滚事务:void rollback()
⑧、获取接口的字节码文件:
6、mapper接口开发规范
(1)、Mapper.xml文件中的namespace与mapper接口的全限定名相同
(2)、Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
(3)、Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同
(4)、Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
1、环境
(1)、IDE:IDEA 2021.1.2
(2)、构建工具:maven3.8.2
(3)、MySQl版本:8.0
(4)、Mybatis版本:3.5.9
2、创建maven工程
org.mybatis
mybatis
3.5.9
junit
junit
4.13.1
test
log4j
log4j
1.2.12
org.projectlombok
lombok
1.18.22
3、创建数据库的表和实体
create table `user`(
`id` int(0) not null primary key auto_increment comment '主键',
`username` varchar(255) not null,
`password` varchar(255) not null
)
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String username;
private String password;
}
4、创建映射文件
insert into user values(#{id},#{username},#{password})
update user set username=#{username},password=#{password} where id=#{id}
delete from user where id=#{id}
5、创建核心文件
6、测试增删改查
import mybatis.entity.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class UserMapperTest {
public static SqlSession sqlSession() {
SqlSession sqlSession = null;
try {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
sqlSession = sqlSessionFactory.openSession(true);
} catch (IOException e) {
e.printStackTrace();
}
return sqlSession;
}
@Test
public void findUser() {
SqlSession sqlSession = sqlSession();
List list = sqlSession.selectList("mybatis.mapper.UserMapper.findUser");
System.out.println(list);
sqlSession.close();
}
@Test
public void addUser() {
User user = new User(null,"tom","123");
SqlSession sqlSession = sqlSession();
sqlSession.insert("mybatis.mapper.UserMapper.addUser",user);
sqlSession.commit();
sqlSession.close();
}
@Test
public void updateUser() {
User user = new User(4,"tom","123");
SqlSession sqlSession = sqlSession();
sqlSession.update("mybatis.mapper.UserMapper.updateUser",user);
sqlSession.commit();
sqlSession.close();
}
@Test
public void deleteUser() {
SqlSession sqlSession = sqlSession();
sqlSession.delete("mybatis.mapper.UserMapper.deleteUser",5);
sqlSession.commit();
sqlSession.close();
}
}
三、映射配置文件(一)、模板
1、IDEA:点击File,然后在点击Settings,然后再点击Editor,再点击File and Code Templates,然后在Files下的+号进行点击,再然后Name,输入名字mybatis-mapper,再在Extension,输入后缀名xml,然后再在下面的输入框中输入信息,最后点击Apply,再点击OK,就完成映射配置文件的模板的创建
(二)、mapper1、属性
(1)、namespace:命名空间
2、子标签:select、insert、update、delete
(1)、概述:增删改查
(2)、属性
①、id:语句的唯一标识
②、resultType:查询结果返回的数据类型
③、parameterType:传入的参数的类型或别名
④、resultMap:引入外部resultMap的引用,不能和resultType一起使用
(3)、子标签:if、where、foreach、sql
3、获取参数值的两种方式
(1)、${}:字符串拼接,要注意引号问题
(2)、#{}:占位符赋值
1、概述:根据特定条件动态地去拼接SQL语句的功能
2、if
List getEmpCondition(Emp emp)
2、where
List getEmpCondition(Emp emp)
3、trim
List getEmpCondition(Emp emp)
4、choose、when、otherwise
List getEmpChoose(Emp emp)
5、foreach
(1)、批量添加
int addEmps(@Param("emps")List emps)
(null,#{emp.empName},#{emp.age},#{emp.sex},#{emp.email})
(2)、批量删除
int deleteEmp(@Param("eids")Integer[] eids)//数组批量删除
delete from emp where
eid = #{eid}
6、sql
eid,emp_Name,age,sex,email
四、核心配置文件
(一)、模板
1、IDEA:点击File,然后在点击Settings,然后再点击Editor,再点击File and Code Templates,然后在Files下的+号进行点击,再然后Name,输入名字mybatis-config,再在Extension,输入后缀名xml,然后再在下面的输入框中输入信息,最后点击Apply,再点击OK,就完成核心配置文件的模板的创建
(二)、configuration1、properties:属性
2、settings:设置
3、typeAliases:类型别名
4、typeHandlers:类型处理器
5、objectFactory:对象工厂
6、plugins:插件
7、environments:环境
(1)、environment:环境变量
①、transactionManager:事务管理器
②、dataSource:数据源
8、databaseldProvider:数据库厂商标识
9、mappers:映射器
1、概述:配置数据库的环境
2、属性
(1)、id:指定当前环境的名称
3、子标签
(1)、transactionManager:事务管理器,它的类型有以下两种
①、JDBC:直接使用JDBC的提交和回滚设置,依赖于数据源得到的连接来管理事务作用域
②、MANAGED:从来不提交或回滚连接,而是让容器管理整个生命周期,默认情况下关闭连接,需要将closeConnection属性设置为false来阻止关闭行为
(2)、dataSource:数据源,它的类型有三种,它的标签是设置数据库的连接池的基本参数的配置
①、UNPOOLED:每次请求时打开和关闭连接
②、POOLED:实现利用"池"的概念将JDBC连接对象组织起来
③、JNDI:是为了能在如EJB或应用服务器这类容器中使用,容器可以集中或外部配置数据源,然后放置在一个JDNI上下文的引用
1、概述:引入映射文件的
2、加载方式
(1)、使用相对于类路径的资源引用,例如:
(2)、使用完全限定资源定位符(URL) ,例如:
(3)、使用映射器接口实现类的完全限定类名,例如:
(4)、将包内的映射器接口实现全部注册为映射器,例如:
1、概述:引入外部properties文件的
2、使用:通过resource标签引入即可
1、概述:定义类型别名
2、已经定义好的类型别名
数据类型 | String | Integrt | List | ArrayList | Map | HashMap | Date | Object |
---|---|---|---|---|---|---|---|---|
别名 | string | int | list | arraylist | map | hashmap | date | object |
3、注意实现:别名要定义在environments标签的上方
(七)、typeHandlers1、概述:类型处理器
2、常用类型处理器
类型处理器 | Java类型 | 数据库类型 |
---|---|---|
BooleanTypeHandler | java.lang.Boolean,boolean | BOOLEAN |
ByteTypeHandler | java.lang.Byte,byte | NUMERIC,BYTE |
ShortTypeHandler | java.lang.Short,short | NUMERTC,SHORT INTEGER |
IntegerTypeHandler | java.lang.Integer,int | NUMERTC,INTEGER |
LongTypeHandler | java.lang.Long,long | NUMERTC,LONGnINTEGER |
3、开发步骤
①、定义转换类,继承类BaseTypeHandler
②、覆盖4个未实现的方法,其中setNonNullParameter为java程序设置数据到数据库的回调方法,getNullableResult为查询时mysql的字符串类型转换成java的Type类型的方法
③、在MyBatis核心配置文件中进行注册
④、测试转换是否正确
4、示例
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
public class DateTypeHandler extends BaseTypeHandler {
/**
* 将java类型转换成数据库需要的类型
*/
@Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException {
long time = date.getTime();
preparedStatement.setLong(i,time);
}
/**
* 将数据库需要的类型转换成Java类型
*/
@Override
public Date getNullableResult(ResultSet resultSet, String s) throws SQLException {
long aLong = resultSet.getLong(s);
Date date = new Date(aLong);
return date;
}
/**
* 将数据库需要的类型转换成Java类型
*/
@Override
public Date getNullableResult(ResultSet resultSet, int i) throws SQLException {
long aLong = resultSet.getLong(i);
Date date = new Date(aLong);
return date;
}
/**
* 将数据库需要的类型转换成Java类型
*/
@Override
public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
long aLong = callableStatement.getLong(i);
Date date = new Date(aLong);
return date;
}
}
(八)、plugins
1、概述:可以使用第三方插件进行扩展
2、分页插件
(1)、概述:使用插件获取分页数据 (
2)、步骤
①、导入分页插件的坐标
②、配置插件
③、测试
(3)、示例
com.github.pagehelper
pagehelper
3.7.5
com.github.jsqlparser
jsqlparser
0.9.1
//设置分页参数
PageHelper.startPage(1,2);
//获取分页相关参数
PageInfo pageInfo = new PageInfo(list);
System.out.println("当前页: " + pageInfo.getPageNum());
System.out.println("页显示条数: " + pageInfo.getPageSize());
System.out.println("总条数: " + pageInfo.getTotal());
System.out.println("总页数: " + pageInfo.getPages());
System.out.println("上一页: " + pageInfo.getPrePage());
System.out.println("下一页: " + pageInfo.getNextPage());
System.out.println("是否为第一页: " + pageInfo.isIsFirstPage());
System.out.println("是否为最后一页: " + pageInfo.isIsLastPage());
五、多表 *** 作
(一)、一对一
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Integer id;
private String name;
private Boolean age;
private String sex;
private StudentStatus studentStatus;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class StudentStatus {
private Integer id;
private String num;
private String major;
}
public class MybatisDemo {
@Test
public void TestA() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
List list = sqlSession.selectList("com.mybatis.mapper.StudentMapper.findAll");
System.out.println(list);
}
}
(二)、一对多
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Integer sId;
private String sName;
private Long sAge;
private String sSex;
private Integer cId;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Class {
private Integer cId;
private String cName;
private String cAddr;
private List students;
}
public class MybatisDemo {
@Test
public void TestA() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
List list = sqlSession.selectList("com.mybatis.mapper.ClassMapper.findAll");
for (Class aClass : list) {
System.out.println(aClass);
}
}
}
(三)、多对多
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Course {
private Integer cId;
private String cName;
private List students;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Integer sId;
private String sName;
private Long sAge;
private String sSex;
private List courses;
}
public class MybatisDemo {
@Test
public void TestA() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
List courseList = sqlSession.selectList("com.mybatis.mapper.CourseMapper.findAll");
List studentList = sqlSession.selectList("com.mybatis.mapper.StudentMapper.findAll");
System.out.println("### 课程 ###");
for (Course course : courseList) {
System.out.println(course);
}
System.out.println("### 学生 ###");
for (Student student : studentList) {
System.out.println(student);
}
}
}
六、注解开发
(一)、常用注解
1、@Insert:实现新增
2、@Update:实现更新
3、@Delete:实现删除
4、@Select:实现查询
5、@Result:实现结果集封装
6、@Results:可以与
7、@Result:一起使用,封装多个结果集
8、@One:实现一对一结果集封装
9、@Many:实现一对多结果集封装
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String username;
private String password;
}
import mybatis.entity.User;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
public interface UserMapper {
@Insert("insert into user values(#{id},#{username},#{password})")
void save(User user);
@Update("update user set username=#{username},password=#{password} where id=#{id}")
void update(User user);
@Delete("delete from user where id=#{id}")
void delete(int id);
@Select("select * from user where id=#{id}")
User findById(int id);
@Select("select * from user")
List find();
}
import mybatis.entity.User;
import mybatis.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class UserMapperTest {
private UserMapper userMapper;
@Before
public void sqlSession() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
userMapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void find() {
List userList = userMapper.find();
for (User user : userList) {
System.out.println(user);
}
}
@Test
public void findById() {
User user = userMapper.findById(1);
System.out.println(user);
}
@Test
public void save() {
User user = new User(null, "tom", "123");
userMapper.save(user);
}
@Test
public void update() {
User user = new User(null, "tom", "123");
userMapper.update(user);
}
@Test
public void delete() {
userMapper.delete(1);
}
}
(三)、多表 *** 作
1、一对一
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Card {
private Integer id;
private String number;
private Person p;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private Integer id;
private String name;
private Integer age;
}
import com.cmy.bean.Card;
import com.cmy.bean.Person;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface CardMapper {
@Select("SELECT * FROM card")
@Results({@Result(column = "id", property = "id"),@Result(column = "number", property = "number"),@Result(property = "p",javaType = Person.class,column = "pid",one = @One(select = "com.mybatis.mapper.PersonMapper.selectById"))})
public abstract List selectAll();
}
import com.cmy.bean.Person;
import org.apache.ibatis.annotations.Select;
public interface PersonMapper {
@Select("SELECT * FROM person WHERE id=#{id}")
public abstract Person selectById(Integer id);
}
public class UserMapperTest {
private CardMapper cardMapper;
@Before
public void sqlSession() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
cardMapper = sqlSession.getMapper(CardMapper.class);
}
@Test
public void find() {
List userList = cardMapper.selectAll();
for (User user : userList) {
System.out.println(user);
}
}
}
2、一对多
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Classes {
private Integer id;
private String name;
private List students;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Integer id;
private String name;
private Integer age;
}
public interface ClassesMapper {
@Select("SELECT * FROM classes")
@Results({@Result(column = "id", property = "id"),@Result(column = "name", property = "name"),
@Result(property = "students",javaType = List.class,column = "id",many = @Many(select = "com.mybatis.mapper.StudentMapper.selectByCid"))})
public abstract List selectAll();
}
public interface StudentMapper {
@Select("SELECT * FROM student WHERE cid=#{cid}")
public abstract List selectByCid(Integer cid);
}
public class UserMapperTest {
private ClassesMapper classesMapper;
@Before
public void sqlSession() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
classesMapper = sqlSession.getMapper(ClassesMapper.class);
}
@Test
public void find() {
List userList = classesMapper.selectAll();
for (User user : userList) {
System.out.println(user);
}
}
}
3、多对多
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Course {
private Integer id;
private String name;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Integer id;
private String name;
private Integer age;
}
public interface StudentMapper {
@Select("SELECT DISTINCT s.id,s.name,s.age FROM student s,stu_cr sc WHERE sc.sid=s.id")
@Results({@Result(column = "id", property = "id"),@Result(column = "name", property = "name"),@Result(column = "age", property = "age"),@Result(property = "courses",javaType = List.class, column = "id",many = @Many(select = "com.mybatis.mapper.CourseMapper.selectBySid"))})
public abstract List selectAll();
}
public interface CourseMapper {
@Select("SELECT c.id,c.name FROM stu_cr sc,course c WHERE sc.cid=c.id AND sc.sid=#{id}")
public abstract List selectBySid(Integer sid);
}
public class UserMapperTest {
private StudentMapper studentMapper;
@Before
public void sqlSession() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
studentMapper = sqlSession.getMapper(StudentMapper.class);
}
@Test
public void find() {
List userList = studentMapper.selectAll();
for (User user : userList) {
System.out.println(user);
}
}
}
Mybatis-plus
一、简介
1、概述:是mybatis的增强工具,在mybatis的基础上只做增强,不做改变,为简化开发、提高效率而生
2、特点
(1)、无侵入
(2)、损耗小
(3)、强大的CRUD *** 作
(4)、支持Lanbda形式调用
(5)、支持主键自动生成
(6)、支持ActiveRecord
(7)、支持自定义全局通用 *** 作
(8)、内置代码生成器
(9)、内置分页插件
(10)、内置性能分析插件
(11)、内置全局拦截插件
3、支持数据库
(1)、mysql、Oracle、DB2、H2....
(2)、达梦数据库、虚谷数据库...
4、官方网址:MyBatis-Plus
1、环境
(1)、IDE:IDEA 2021.1.2
(2)、构建工具:maven3.8.2
(3)、MySQl版本:8.0
(4)、Mybatis版本:3.5.7
(5)、JDK:JDK1.8
(6)、SpringBoot:2.6.4
2、创建数据库中的表
create table `user`(
`id` bigint(0) not null auto_increment comment '主键ID',
`name` varchar(30) default null comment '姓名',
`age` int(11) default null comment '年龄',
`email` varchar(50) default null comment '邮箱',
primary key (`id`)
)
INSERT INTO `user` (id,name,age,email) values
(null,'jone',18,'rest1@baomidou.com'),
(null,'jack',34,'rest2@baomidou.com'),
(null,'Tom',42,'rest3@baomidou.com'),
(null,'Sandy',34,'rest4@baomidou.com'),
(null,'Billie',44,'rest5@baomidou.com')
3、创建SpringBoot工程
mysql
mysql-connector-java
runtime
com.baomidou
mybatis-plus-boot-starter
3.4.3
org.projectlombok
lombok
1.18.22
4、创建yml文件,进行配置
spring:
# 配置数据源信息
datasource:
# 配置数据源类型
type: com.zaxxer.hikari.HikariDataSource
# 配置连接数据库的各个信息
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/user?characterEncoding=utf-8&userSSL=false
username: root
password: root
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 将日志信息打印到控制台上
global-config:
db-config:
# 设置数据库自增长
id-type: auto
# 数据表的前缀
table-prefix:
5、创建实体类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
6、创建Mapper接口
@Repository
public interface UserMapper extends BaseMapper {
Map getById(@Param("id")Integer id);
}
7、创建service
public interface UserService extends IService {
}
8、创建service的实现类
@Service
public class UserServiceImpl extends ServiceImpl implements UserService {
}
9、Maper测试
@SpringBootTest
public class MybatisPlusTest {
@Autowired
private UserMapper userMapper;
@Test
public void select() {//查询
List list = userMapper.selectList(null);//查询全部
list.forEach(System.out::println);
User user = userMapper.selectById(7);//根据id查询的单个信息
System.out.println(user);
List list = Arrays.asList(9, 8, 7);//根据多个id查询信息
userMapper.selectBatchIds(list);
Map map = new HashMap<>();
map.put("name","jack");
map.put("age",34);
List userList = userMapper.selectByMap(map);//根据哟用户信息查询
userList.forEach(System.out::println);
Map map = userMapper.getById(7);
System.out.println(map);
}
@Test
public void insert() {//添加
User user = new User();
user.setName("张三");
user.setAge(13);
user.setEmail("zhangsan@qq.com");
int result = userMapper.insert(user);
System.out.println(result);
}
@Test
public void delete() {//删除
int result = userMapper.deleteById(5);//根据id进行单个删除
System.out.println(result);
Map map = new HashMap<>();
map.put("name","张三");
map.put("age",13);
int result = userMapper.deleteByMap(map);//根据用户信息进行和删除
System.out.println(result);
List list = Arrays.asList(1, 2, 3);
int resulr = userMapper.deleteBatchIds(list);//根据id进行批量删除
System.out.println(resulr);
}
@Test
public void update() {//修改
User user = new User();
user.setId(4);
user.setName("张三");
user.setAge(13);
user.setEmail("zhangsan@qq.com");
int result = userMapper.updateById(user);
System.out.println(result);
}
}
10、service测试
@SpringBootTest
public class MybatisPlusServiceTest {
@Autowired
private UserService userService;
@Test
public void count(){//查询记录数
int count = userService.count();
System.out.println(count);
}
@Test
public void insert(){//批量添加
List list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
User user = new User();
user.setName("nhy"+i);
user.setAge(13+i);
user.setEmail("nhy"+i+"@qq.com");
list.add(user);
}
boolean b = userService.saveBatch(list);
System.out.println(b);
}
}
三、注解
(一)、@TableName
1、概述:将实体类与表名进行映射
2、示例
@Data
@TableName(”t_user“)
public class User {
private Integer id;
private String name;
private Integer age;
private String email;
}
(二)、@TableId
1、概述:将属性与数据表中的字段指定为主键 2、示例
@Data
public class User {
@TableId
private Integer id;
private String name;
private Integer age;
private String email;
}
3、属性
(1)、value:用于指定主键的字段
(2)、type:主键生成策略,AUTO 为数据库表的主键递增
1、概述:指定属性所对应的字段名
2、示例
@Data
public class User {
private Integer id;
@TableField("user_name")
private String name;
private Integer age;
private String email;
}
(四)、@TableLogic
1、概述:逻辑删除
2、示例
@Data
public class User {
private Integer id;
private String name;
private Integer age;
private String email;
@TableLogic
private Integer isDelete;
}
(五)、@Version
1、概述:版本号
2、示例
@Data
public class User {
@TableId(value = "id")
private Long id;
private String name;
private Integer age;
private String email;
@Version
private Integer version;
}
(六)、@EnumVale
1、概述:将标注的属性的值存储到数据库中
2、示例
@Data
public class User {
private Long id;
private String name;
private Integer age;
@EnumVale
private SexEnum sex;
private String email;
@Version
private Integer version;
}
四、全局配置
mybatis-plus:
# 配置类型别名
type-aliases-package: com.mybatisPlus.pojo
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 设置mybatis-plus的全局配置
global-config:
db-config:
# 设置实体类所对应的统一前缀
# table-prefix: t_
# 设置统一的主键生成策略
id-type: auto # auto 数据库自动递增
# 枚举扫描包
type-enums-package: com.mybatisPlus.enums
五、条件构造器
(一)、 AbstractWrapper
1、概述:用于查询条件封装,生成sql的where条件
2、实现子类
(1)、QueryWrapper:查询条件封装
(2)、UpdateWrapper:Update条件封装
1、概述: Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column
2、实现子类
(1)、LambdaQueryWrapper:用于Lambda语法使用的查询Warpper
(2)、LambdaUpdateWrapper: Lambda 更新封装Wrapper
1、组装查询条件
@Autowired
private UserMapper userMapper;
@Test
void selectList(){
//查询用户名包含a 年龄在10-30之间,邮箱不为null的用户信息
//SELECT id,name,age,email FROM user WHERE (name LIKE ? AND age BETWEEN ? AND ? AND email IS NOT NULL)
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.like("name","a").between("age",20,30).isNotNull("email");
List userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
2、组装排序条件
@Autowired
private UserMapper userMapper;
@Test
void selectList2(){
//查询信息,按照年龄的降序排序,若年龄相同,则按照id的升序排序
//SELECT id,name,age,email FROM user ORDER BY age DESC,id ASC
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("age").orderByAsc("id");
List userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
3、组装删除条件
@Autowired
private UserMapper userMapper;
@Test
void delete(){
//删除邮箱地址为null的用户信息
//DELETE FROM user WHERE (email IS NULL)
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.isNull("email");
int delete = userMapper.delete(queryWrapper);
System.out.println(delete);
}
4、组装修改条件
@Autowired
private UserMapper userMapper;
@Test
void update(){
//将年龄大于20并且用户名包含有a或邮箱为null的用户信息修改
// UPDATE user SET name=?, age=?, email=? WHERE (age > ? AND name LIKE ? OR email IS NULL)
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age",20).like("name","a").or().isNull("email");
int update = userMapper.update(new User(null,"小明",12,"test@123.com"), queryWrapper);
System.out.println(update);
}
5、条件的优先级
@Autowired
private UserMapper userMapper;
@Test
void update2(){
//将用户名中包含a并且(年龄大于20或邮箱为null)的用户信息修改 lambda中条件优先执行
// UPDATE user SET name=?, age=?, email=? WHERE (name LIKE ? AND (age > ? OR email IS NULL))
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.like("name","3").and(i->i.gt("age",10).or().isNull("email"));
int update = userMapper.update(new User(null,"好",22,"test@123.com"), queryWrapper);
System.out.println(update);
}
6、组装select字句
@Autowired
private UserMapper userMapper;
@Test
void selectList3() {
//查询用户名、年龄、邮箱信息
//SELECT name,age,email FROM user
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.select("name","age","email");
List
7、组装子查询
@Autowired
private UserMapper userMapper;
@Test
void selectList4() {
//查询id大于100的
//SELECT id,name,age,email FROM user WHERE (id IN (select id from user where id > 100))
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.inSql("id","select id from user where id > 100");
List userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
(四)、UpdateWrapper
1、修改
@Autowired
private UserMapper userMapper;
@Test
void update3() {
//将用户名中包含a并且(年龄大于20或邮箱为null)的用户信息修改 lambda中条件优先执行
//UPDATE user SET name=?,email=? WHERE (name LIKE ? AND (age > ? OR email IS NULL))
UpdateWrapper updateWrapper = new UpdateWrapper<>();
updateWrapper.like("name", "2").and(i -> i.gt("age", 10).or().isNull("email"));
updateWrapper.set("name","1").set("email","ad@c123.com");
int update = userMapper.update(null, updateWrapper);
System.out.println(update);
}
2、实际开发中
@Autowired
private UserMapper userMapper;
@Test
void selectList5() {
//SELECT id,name,age,email FROM user WHERE (name LIKE ? AND age >= ? AND age <= ?)
String username = "好";
Integer ageBegin = 10;
Integer ageEnd = 23;
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.like(StringUtils.isNotBlank(username), "name", username).ge(ageBegin != null, "age", ageBegin).le(ageEnd != null, "age", ageEnd);
List userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
(五)、LambdaQueryWrapper
@Autowired
private UserMapper userMapper;
@Test
void selectList6() {
// SELECT id,name,age,email FROM user WHERE (name LIKE ? AND age >= ? AND age <= ?)
String username = "好";
Integer ageBegin = 10, ageEnd = 23;
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.like(StringUtils.isNotBlank(username),User::getName,username)
.ge(ageBegin!=null,User::getAge,ageBegin)
.le(ageEnd!=null,User::getAge,ageEnd);
List userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
(六)、LambdaUpdateWrapper
@Autowired
private UserMapper userMapper;
@Test
void update4() {
//将用户名中包含a并且(年龄大于20或邮箱为null)的用户信息修改 lambda中条件优先执行
// UPDATE user SET name=?,email=? WHERE (name LIKE ? AND (age > ? OR email IS NULL))
LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.like(User::getName, "2").and(i -> i.gt(User::getAge, 10).or().isNull(User::getEmail));
updateWrapper.set(User::getName, "1").set(User::getEmail, "ad@c123.com");
int update = userMapper.update(null, updateWrapper);
System.out.println(update);
}
六、插件
(一)、分页插件
@Configuration
@MapperScan("com.mybatisPlus.mapper")
public class MybatisConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
1、使用默认的分页语句
@Autowired
private UserMapper userMapper;
@Test
void page(){
Page page = new Page<>(1,2);
Page userPage = userMapper.selectPage(page, null);
System.out.println(userPage.getRecords());
System.out.println(userPage.getPages());
System.out.println(userPage.getTotal());
System.out.println(userPage.hasNext());
System.out.println(userPage.hasPrevious());
}
2、使用自定义的分页语句
@Repository
public interface UserMapper extends BaseMapper {
@Select("select * from user where age > #{age}")
Page selectPageVo(@Param("page") Page page, @Param("age") Integer age);
}
@Autowired
private UserMapper userMapper;
@Test
void page2(){
Page page = new Page<>(1,2);
Page userPage = userMapper.selectPageVo(page, 12);
System.out.println(userPage.getRecords());
System.out.println(userPage.getPages());
System.out.println(userPage.getTotal());
System.out.println(userPage.hasNext());
System.out.println(userPage.hasPrevious());
}
(二)、乐观锁
@Configuration
@MapperScan("com.mybatisPlus.mapper")
public class MybatisConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
private String email;
@Version
private Integer version;
}
七、通用枚举
@AllArgsConstructor
@Getter
public enum SexEnum {
MALE(1,"男"),FEMALE(2,"女");
@EnumValue
private Integer sex;
private String name;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
private SexEnum sex;
private String email;
@Version
private Integer version;
}
八、代码生成器
com.baomidou
mybatis-plus-generator
3.4.1
org.freemarker
freemarker
2.3.31
public class Code {
public static void code(String url,String username,String password,String author,String outputDir,String parent,String moduleName,String... table) {
FastAutoGenerator.create(url, username, password)
.globalConfig(builder -> {
builder.author(author) // 设置作者
.enableSwagger() // 开启 swagger 模式
.fileOverride() // 覆盖已生成文件
.outputDir(outputDir); // 指定输出目录
})
.packageConfig(builder -> {
builder.parent(parent) // 设置父包名
.moduleName(moduleName) // 设置父包模块名
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, outputDir)); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.addInclude(table) // 设置需要生成的表名
.addTablePrefix("t_", "c_"); // 设置过滤表前缀
})
// 使用Freemarker引擎模板,默认的是Velocity引擎模板
.templateEngine(new FreemarkerTemplateEngine())
.execute();
}
}
九、多数据源
com.baomidou
dynamic-datasource-spring-boot-starter
3.5.0
spring:
# 配置数据源信息
datasource:dynamic:
#设置默认的数据源或者数据源组,默认值即为master
primary: master
#严格匹配数据源,默认false.true未匹配到指定数据源时抛异常,false使用默认数据源
strict: false
datasource:
master:
ur1: jdbc:mysql://localhost:3306/mybatis_plus_1?char acter Encoding=utf8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
slave_1:
ur1: jdbc:mysq1://localhost:3306/mybatis_plus_2?character Encoding=utf8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
mybatis-plus:
# 配置类型别名
type-aliases-package: com.mybatisPlus.pojo
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 设置mybatis-plus的全局配置
global-config:
db-config:
# 设置实体类所对应的统一前缀
# table-prefix: t_
# 设置统一的主键生成策略
id-type: auto # auto 数据库自动递增
# 枚举扫描包
type-enums-package: com.mybatisPlus.enums
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@TableId(value = "id")
private Long id;
private String name;
private Integer age;
private String email;
@Version
private Integer version;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Product {
@TableId("id")
private Integer id;
private String name;
private Integer price;
@Version
private Integer version;
}
@Repository
public interface UserMapper extends BaseMapper {
}
@Repository
public interface ProductMapper extends BaseMapper {
}
public interface UserService extends IService {
}
public interface ProductService extends IService {
}
@Service
@DS("mybatis_plus")
public class UserServiceImpl extends ServiceImpl implements UserService {
}
@Service
@DS("mybatis_plus_1")
public class ProductServiceImpl extends ServiceImpl implements ProductService {
}
SpringBoot
一、简介
1、概述:简化Spring应用的初始搭建以及开发流程
2、特点
(1)、独立运行的 Spring 项目
(2)、内嵌 Servlet 容器
(3)、提供 starter 简化 Maven 配置
(4)、提供了大量的自动配置
(5)、自带应用监控
(6)、无代码生成和 xml 配置
3、优点
(1)、起步依赖
(2)、自动配置
(3)、辅助功能
1、IDEA:点击File,然后在点击New,再点击Project,在出现的界面上点击Spring Initializr,然后按照上面文字进行输入,输入完之后点击Next,然后在下一个界面点击你想要开发哪一个项目就添加哪一个,添加完之后,就点击Fiish,最后运行看是否成功;网址为:https://start.spring.io
2、官网:进入到Spring官网,然后进入SpringBoot的详情页面,滑倒最下面,找到Spring Initializr进行点击,然后按照上面的文字进行输入,然后再在右边添加依赖,点击ADD DEPENDENCIES,进入到依赖添加详情页面,找打需要的依赖进行添加即可,这个添加依赖的过程可能需要重复进入...到了最后一个依赖,就点击GENERATE,把下载的文件进行解压,把项目引入工程中即可运行;网址为:Spring Boot
3、阿里云:点击File,然后在点击New,再点击Project,在出现的界面上点击Spring Initializr,然后按照上面文字进行输入,输入完之后点击Next,然后在下一个界面点击你想要开发哪一个项目就添加哪一个,添加完之后,就点击Fiish,最后运行看是否成功;网址为:http://start.aliyun.com
4、Maven创建:在idea中使用Maven作为创建工具,但是有一个前提是要有SpringBoot的依赖即可创建,把SpringBoot的依赖放入到pom.xml文件中进行加载即可,最为创建一个Application类,类上@SpringBootApplication注解标识,在下面创建main方法,方法体中输入SpringApplication.run(Application.class)
,最后运行即可
5、解析
(1)、parent:仅定义未使用,减少依赖冲突问题
(2)、starter:依赖传递,减少依赖配置问题
(3)、引导类:启动Spring容器
(4)、内嵌tomcat
1、默认类型:properties
2、作用:修改springboot的默认设置
3、类型
(1)、properties:默认值,优先级最高
(2)、yml:建议使用这个,其次
(3)、yaml:优先级最低
4、yaml
(1)、定义:一种数据序列化格式
(2)、优点
①、容易阅读
②、容易与脚本语言交互
③、以数据为核心,重数据清格式
(3)、文件的扩展名
①、.yml:主流的
②、.yaml
(4)、语法规则
①、大小写敏感
②、属性层级关机使用多行描述,每行结尾使用冒号结束
③、使用缩进表示层级关系,同层级左侧对齐,只允许空格,不能使用Tab键
④、属性值前面添加空格,属性名与属性值之间使用冒号+空格作为分隔符
⑤、# 表示注释
(5)、表示方式
①、字面值:string: HelloWorld
②、数组:like: [王者荣耀,吃鸡战场]
③、对象数组:userr: [{name:Tom,age:4},{name:Juerry,age:6}]
(6)、读取数据
①、获取上面的单个属性数据:@Value("${一级属性名.二级属性名...}")
②、获取全部数据:@Autowied
③、获取引用类型数据:@Autowied
public interface BookDao{
void sove();
}
@Repository
public class implBooKDap implements BookDao{
@Override
void sove(){
System.out.println("sove");
}
}
@SpringBootTest
class ApplicationTests {
@Autowired
private BookDao bookDao;
@Test
void contextLoads() {
bookDao.save();
}
}
(二)、Mybatis
mysql
mysql-connector-java
runtime
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.2.2
org.projectlombok
lombok
1.18.22
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/book?serverTimezone=UTC
username: root
password: root
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
private Integer id;
private String type;
private String name;
private String description;
}
@Mapper
public interface BookMapper {
@Select("select * from boook where id = #{id}")
public Book getById(Integer id);
}
@SpringBootTest
class ApplicationTests {
@Autowired
private BookMapper bookMapper;
@Test
void contextLoads() {
bookMapper.getById(1);
}
}
(三)、Mybayis-plus
com.baomidou
mybatis-plus-boot-starter
3.4.3
org.projectlombok
lombok
1.18.22
mysql
mysql-connector-java
runtime
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/book?serverTimezone=UTC
username: root
password: root
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_ # 数据表的前缀
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
private Integer id;
private String type;
private String name;
private String description;
}
@Mapper
public interface BookDao extends BaseMapper{
}
@SpringBootTest
class ApplicationTests {
@Autowired
private BookDao bookDao;
@Test
void contextLoads() {
bookDao.selectById(1);
}
}
(四)、Druid
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.2.2
org.projectlombok
lombok
1.18.22
mysql
mysql-connector-java
runtime
com.alibaba
druid-spring-boot-starter
1.2.6
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/user_db
username: root
password: root
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
private Integer id;
private String type;
private String name;
private String description;
}
@Mapper
public interface BookDao {
@Select("select * from boook where id = #{id}")
public Book getById(Integer id);
}
@SpringBootTest
class ApplicationTests {
@Autowired
private BookDao bookDao;
@Test
void contextLoads() {
bookDao.getById(1);
}
}
SpringSecurity
一、简介
1、概述:是一个高度自定义的安全框架。利用 Spring loC/DI和AOP功能,为系统提供了声明式安全访问控制功能,减少了为系统安全而编写大量重复代码的工作
2、常用的安全框架
(1)、SpringSerurity:Spring家族中的一员
(2)、ApacheShiro:一个功能强大且易于使用的Java安全框架,提供了认证授权,加密和会话管理
1、环境
(1)、IDE:IDEA 2021.1.2
(2)、构建工具:maven3.8.2
(3)、JDK:JDK1.8
(4)、SpringBoot:2.6.4
(5)、SpringSecurity:2.6.4
2、创建maven工程
org.springframework.boot
spring-boot-starter-security
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.security
spring-security-test
test
3、创建控制器
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class LoginController {
@RequestMapping("login")
public String login(){
System.out.println("执行登录方法");
return "redirect:login.html";
}
}
4、创建页面
(1)、登录
登录
(2)、登录成功页面
mian
登录成功
5、测试
三、类 (一)、UserDetailsService1、概述:用来实现自定义登录逻辑的接口
2、loadUserByUsername:通过用户名来加载用户,并将用户传入到UserDetails接口中去
1、概述:是提供用户信息的核心接口
2、方法
(1)、Collection extends GrantedAuthority> getAuthorities():返回所有的权限
(2)、String getPassword():获取密码
(3)、String getUsername():货期用户名
(4)、boolean isAccountNonExpired():判断用户是否过期
(5)、boolean isAccountNonLocked():判断用户是否锁定
(6)、boolean isCredentialsNonExpired():判断凭证是否过期
(7)、boolean isEnabled():判断账号是否可用
3、实现类:User
1、概述:提供的密码加密方式的接口
2、方法 (1)、String encode(CharSequence rawPassword):对密码进行加密,推荐使用BCryptPasswordEncoder加密方法 (2)、boolean matches(CharSequence rawPassword, String encodedPassword):将原始密码和加密后的密码进行匹配 (3)、default boolean upgradeEncoding(String encodedPassword):解析密码
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Bean public PasswordEncoder getPasswordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity http) throws Exception { // 表单提交 http.formLogin() // 自定义密码和用户名的参数别名 .usernameParameter("username") .passwordParameter("password") // 当发现是login是,就要走登录逻辑 .loginProcessingUrl("/login") // 自定义登录页面 .loginPage("/login.html") // 登录成功后的页面,必须是POST请求 .successForwardUrl("/toMain") //登录成功处理器,不能和successForwardUrl共存 //.successHandler(new MyAuthenticationFailureHandler("https://youdao.com/")) // 登录失败后的页面,必须是POST请求 .failureForwardUrl("/toError"); //登录失败处理器,不能和failureForwardUrl共存 //.failureHandler(new MyAuthenticationFailureHandler("https://youdao.com/")); // 授权认证 http.authorizeRequests() //登录页面不需要被认证 .antMatchers("/login.html").permitAll() // 错误页面不需要被认证 .antMatchers("/error.html").permitAll() //所有请求都必须被认证,才能访问 .anyRequest().authenticated(); //关闭csrf防护 http.csrf().disable(); } }
@Controller public class LoginController { @RequestMapping("toMain") public String toMain(){ return "redirect:main.html"; } @RequestMapping("toError") public String toError(){ return "redirect:error.html"; } }
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler { private String url; public MyAuthenticationFailureHandler(String url) { this.url = url; } @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { response.sendRedirect(url); } }
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler { private String url; public MyAuthenticationSuccessHandler(String url) { this.url = url; } @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { response.sendRedirect(url); } }
@Service public class UserDetailsServiceImpl implements UserDetailsService { @Autowired private PasswordEncoder passwordEncoder; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { String oldUserName = "admin"; String oldPassWord = "123"; if(!oldUserName.equals(username)){ throw new UsernameNotFoundException("用户名不存在!"); } String newPassWord = passwordEncoder.encode(oldPassWord); return new User(username,newPassWord, AuthorityUtils.commaSeparatedStringToAuthorityList(oldUserName)); } }五、方法 (一)、授权
1、概述:本质就是请求 2、方法 (1)、anyRequest:所有请求 (2)、antMatchers:单个请求,也可以使用匹配符进行匹配 (3)、regexMathcers:使用正则表达式或者使用请求方式进行匹配 (4)、mvcMatchers:给请求加入一个前缀
(二)、访问控制1、概述:请求的匹配符 2、方法 (1)、parmitAll:允许任何人访问 (2)、dentAll:所有人不允许访问 (3)、anonymous:匿名访问 (4)、authenticated:需要认证才可访问 (5)、fullAuthenticated:完全认证才可访问 (6)、remenberMe:规定时间内才可访问
(三)、权限判断1、概述:用户登录后判断权限,严格区分大小写 2、方法 (1)、hasAuthority:用户是否具有特定权限就允许访问 (2)、hasAuythority:用户具有某一个权限就允许访问
(四)、角色判断1、概述:用户登录后判断权限,严格区分大小写,在传入数据是必须要ROLE_开头才可以,后面验证不需要 2、方法 (1)、hasRole:用户是否具有特定用户就允许访问 (2)、hasAnyRole:用户具有某一个用户就允许访问
(五)、IP地址1、概述:通过Id地址才能访问 2、方法 (1)、hasIpAddress:给定Ip地址才可访问
(六)、表达式控制1、本质:access方法 2、作用:控制方法的访问 3、常用的表达式
表达式 | 说明 |
---|---|
hasRole([role]) | 如果当前主体具有指定的角色,则返回true。默认情况下,如果提供的角色不是以'ROLE_'开头,它将被添加。这可以通过修改DefaulthebSecurityExpressionHandler上的defaultRolePrefix来定制 |
hasAnyRole([rolel,role2]) | 如果当前主体具有任何提供的角色(以逗号分隔的字符串列表给出),则返回true。默认情况下,如果提供的角色不以'ROLE_'开头,则将添加该角色。这可以通过在DefaultwebSecurityExpressionHandler上修改defaultRolePrefix来定制 |
hasAuthority([authority1) | 如果当前主体具有指定的权限,则返回true。 |
hasAnyAuthority([authority1, authority2]) | 如果当前主体具有任何提供的权限(以逗号分隔的字符串列表形式给出),则返回true |
principal | 允许直接访问代表当前用户的主体对象 |
authentication | 允许直接访问从SecurityContext获得的当前Authentication对象 |
permitAll | 总是计算为true |
denyAll | 计算结果总是为false |
isAnonymous () | 如果当前主体是匿名用户,则返回true |
isRememberMe() | 如果当前主体是remember-me用户,则返回true |
isAuthenticated() | 如果用户不是匿名的,则返回true |
isFullyAuthenticated() | 如果用户不是匿名用户或remember-me用户,则返回true |
hasPernission(Object target, Object permission) | 如果用户能够访问给定权限下提供的目标,则返回true。 |
hasPermission(Object targetId, String targetType, Object permission) | )如果用户有权限访问提供的目标,则返回true。为例。hasPermission (com . example。”域。消息”、“读”) |
4、自定义权限控制 (1)、配置类
public interface MyService { boolean hasPermission(HttpServletRequest request, Authentication authentication); }
@Service public class MyServiceImpl implements MyService { @Override public boolean hasPermission(HttpServletRequest request, Authentication authentication) { Object o = authentication.getPrincipal(); if (o instanceof UserDetails) { UserDetails userDetails = (UserDetails) o; Collection extends GrantedAuthority> authorities = userDetails.getAuthorities(); return authorities.contains(new SimpleGrantedAuthority(request.getRequestURI())); } return false; } }
http.authorizeRequests().anyRequest().access("@myServiceImpl.hasPermission(request,authentication)");
(2)、注解
@Secured("ROLE_abc") @RequestMapping("toError") public String toError(){ return "redirect:error.html"; }
ngBootApplication @EnableGlobalMethodSecurity(securedEnabled = true) public class SpringSecurityApplication { public static void main(String[] args) { SpringApplication.run(SpringSecurityApplication.class, args); } }六、SpringSecurityOauth2 (一)、简介
1、授权服务器 (1)、Authorize Endpoint :授权端点,进行授权 (2)、Token Endpoint :令牌端点,进过授权拿到对应的 (3)、TokenIntrospection Endpoint :校验端点,校验Token的合法性 (4)、Revocation Endpoint :撤销端点,撤销授权 2、流程 (1)、用户访问,此时没有Token。 Oauth2RestTemplate会报错,这个报错信息会被Oauth2ClientContextFilter捕获并重定向到认证服务器 (2)、认证服务器通过Authorization Endpoint进行授权,并通过AuthorizationServerTokenServices生成授权码并返回给客户端 (3)、客户端拿到授权码去认证服务器通过Token Endpoint调用AuthorizationServerTokenServices生成Token并返回给客户端 (4)、客户端拿到Token去资源服务器访问资源,一般会通过Oauth2AuthenticationManager调用ResourceServerTokenServices进行校验。校验通过可以获取资源
(二)、授权模式1、授权码模式
org.springframework.cloud spring-cloud-starter-oauth22.2.5.RELEASE org.springframework.cloud spring-cloud-starter-security2.2.5.RELEASE
2、密码模式
Oauth2 一、简介1、概述:是一个开放标准,允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息 2、主要角色 (1)、Resource Owner(资源所有者):用户,即资源的拥有人,想要分享某些资 源给第三方应用 (2)、Resource Server(资源服务器):放受保护资源,要访问这些资源,需要获得访问令牌 (3)、Authorization server(授权(认证)服务器):授权服务器用于发放访问令牌给客户端 (4)、Client(客户端(第三方应用)):客户端代表请求资源服务器资源的第三方程序 3、常用术语 (1)、客户凭证(client Credentials):客户端的clientld和密码用于认证客户 (2)、令牌(tokens):授权服务器在接收到客户请求后,颁发的访问令牌 (3)、作用域(scopes):客户请求访问令牌时,由资源拥有者额外指定的细分权限(permission (4)、用户代理(User Agent):用户代理。一般就是指浏览器 4、令牌类型 (1)、授权码:仅用于授权码授权类型,用于交换获取访问令牌和刷新令牌 (2)、访问令牌:用于代表一个用户或服务直接去访问受保护的资源 (3)、刷新令牌:用于去授权服务器获取一个刷新访问令牌 (4)、Bear erToken:不管谁拿到Token都可以访问资源,类似现金 (5)、Prooof of Possession(PoP) Token:可以校验client是否对Token有明确的拥有权 5、优点 (1)、更安全,客户端不接触用户密码,服务器端更易集中保护 (2)、广泛传播并被持续采用 (3)、短寿命和封装的token (4)、资源服务器和授权服务器解耦 (5)、集中式授权,简化客户端 (6)、HTTP/JSON友好,易于请求和传递token考虑 (7)、多种客户端架构场景 (8)、客户可以具有不同的信任级别 6、缺点 (1)、协议框架太宽泛,造成各种实现的兼容性和互 *** 作性差 (2)、不是一个认证协议,本身并不能告诉你任何用户信息。
二、授权模式 (一)、授权码模式1、概述:是功能最完整、使用最广泛、流程最严密的授权模式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌 2、步骤 (1)、用户访问客户端,客户端将用户导向授权服务器,通过用户代理(User-Agent)发送包括它的客户端标识符、请求的范围、本地状态和一个重定向URI,授权服务器在授予(或拒绝)访问权后将其发送给用户代理 (2)、授权服务器对资源所有者进行身份验证(通过用户代理,让用户输入用户名和密码),并确定资源所有者是否授予或拒绝客户端的访问请求。 (3)、用户跳转后,假如资源所有者同意授权请求,那么授权服务器将会使用前面提供的或者事先指定的重定向URI(redirection URI),重定向到客户端,并附上一个授权码(code)和一个前面提供的本地状态(state)(如果有的话,则会原值返回) (4)、客户端收到授权码,附上早先的重定向URI,向授权服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。在发出请求时,授权服务器对客户端进行身份验证。请求参数包含授权代码、用于获得验证的授权代码的重定向URI、标识客户端身份的client id和client secret (5)、授权服务器对客户端进行身份验证,验证授权代码,并确保所收到的重定向URI与用于在步骤©中对客户端重定向的URI相匹配,如果有效,授权服务器将发送访问令牌access token和刷新令牌refresh token,然后授权服务器给我们返回授权码
(二)、简化模式1、概述:不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了"授权码"这个步骤,因此得名。所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证 2、步骤 (1)、用户访问客户端,客户端将用户导向授权服务器,通过用户代理(User-Agent)发送包括它的客户端标识符、请求的范围、本地状态和一个重定向URI,授权服务器在授予(或拒绝)访问权后将其发送给用户代理 (2)、授权服务器对资源所有者进行身份验证(通过用户代理,让用户输入用户名和密码),并确定资源所有者是否授予或拒绝客户端的访问请求 (3)、用户跳转后,假如资源所有者同意授权请求,那么授权服务器将会使用前面提供的或者事先指定的重定向URI(redirection URI),重定向到客户端,并附上访问令牌等信息
(三)、密码模式1、概述:用户向客户端提供自己的用户名和密码。客户端使用这些信息,向"服务商提供商"索要授权 2、步骤 (1)、用户访问客户端,客户端将用户导向授权服务器,然后提供URI连接包含用户名和密码信息给授权服务器 (2)、授权服务器认证用户名和密码信息正确后,然后返回客户端access_token等信息
(四)、客户端模式1、概述:客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行认证 2、步骤 (1)、客户端直接向授权服务器发起认证请求 (2)、授权服务器通过认证后,直接返回客户端access_token等信息
JWT 一、简介1、常见的认证机制 (1)、HTTP Basic Auth (2)、Cookie Auth (3)、OAuth (4)、Token Auth 2、概述:JSON网络令牌,JWT是一个轻便的安全跨平台传输格式,定义了一个紧凑的自包含的方式在不同实体之间安全传输信息(JSON格式)。它是在Web环境下两个实体之间传输数据的一项标准 3、官网:JWT 4、优点 (1)、jwt基于json,非常方便解析 (2)、可以在令牌中自定义丰富的内容,易扩展 (3)、通过非对称加密算法及数字签名技术,JWT防止篡改 (4)、资源服务使用JWT可不依赖认证服务即可完成授权 5、缺点:JWT令牌较长,占存储空间比较大 6、组成: (1)、头部:描述关于该JWT最基本的信息 (2)、载荷:存放有效信息的地方 (3)、签名:签证信息
二、实现 (一)、永久有效io.jsonwebtoken jjwt0.9.1
@Test void getToken() { JwtBuilder jwtBuilder = Jwts.builder() // 标识 .setId("8888") // 用户 .setSubject("海") // 时间 .setIssuedAt(new Date()) .signWith(SignatureAlgorithm.HS256, "0903"); String token = jwtBuilder.compact(); System.out.println(token); String[] split = token.split("\."); for (String s : split) { System.out.println(Base64Codec.BASE64.decodeToString(s)); } } @Test void parseToken() { String token = ""; Claims body = Jwts.parser() .setSigningKey("0903") .parseClaimsJws(token) .getBody(); System.out.println(body.getId()); System.out.println(body.getSubject()); System.out.println(body.getIssuedAt()); }(二)、超时失效
io.jsonwebtoken jjwt0.9.1
@Test void getToken1() { long now = System.currentTimeMillis(); long exp = now + 60 * 10000; JwtBuilder jwtBuilder = Jwts.builder() // 标识 .setId("8888") // 用户 .setSubject("海") // 时间 .setIssuedAt(new Date()) .setExpiration(new Date(exp)) .signWith(SignatureAlgorithm.HS256, "0903"); String token = jwtBuilder.compact(); System.out.println(token); String[] split = token.split("\."); for (String s : split) { System.out.println(Base64Codec.BASE64.decodeToString(s)); } } @Test void parseToken1() { String token = ""; Claims body = Jwts.parser() .setSigningKey("0903") .parseClaimsJws(token) .getBody(); System.out.println(body.getId()); System.out.println(body.getSubject()); System.out.println(body.getIssuedAt()); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("签发时间" + simpleDateFormat.format(body.getIssuedAt())); System.out.println("过期时间" + simpleDateFormat.format(body.getExpiration())); System.out.println("当前时间" + simpleDateFormat.format(new Date())); }(三)、自定义声明
io.jsonwebtoken jjwt0.9.1
@Test void getToken2() { JwtBuilder jwtBuilder = Jwts.builder() // 标识 .setId("8888") // 用户 .setSubject("海") // 时间 .setIssuedAt(new Date()) .signWith(SignatureAlgorithm.HS256, "0903") //自定义声明 .claim("roles","admin") .claim("logo","ss.jpg"); String token = jwtBuilder.compact(); System.out.println(token); String[] split = token.split("\."); for (String s : split) { System.out.println(Base64Codec.BASE64.decodeToString(s)); } } @Test void parseToken2() { String token = ""; Claims body = Jwts.parser() .setSigningKey("0903") .parseClaimsJws(token) .getBody(); System.out.println(body.getId()); System.out.println(body.getSubject()); System.out.println(body.getIssuedAt()); System.out.println(body.get("logo")); System.out.println(body.get("roles")); }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)