综合概述 Spring Security 是 Spring 社区的一个顶级项目,也是 Spring Boot 官方推荐使用的安全框架。除了常规的认证(Authentication)和授权(Authorization)之外,Spring Security还提供了诸如ACLs,LDAP,JAAS,CAS等高级特性以满足复杂场景下的安全需求。另外,就目前而言,Spring Security和Shiro也是当前广大应用使用比较广泛的两个安全框架。 Spring Security 应用级别的安全主要包含两个主要部分,即登录认证(Authentication)和访问授权(Authorization),首先用户登录的时候传入登录信息,登录验证器完成登录认证并将登录认证好的信息存储到请求上下文,然后再进行其他操作,如在进行接口访问、方法调用时,权限认证器从上下文中获取登录认证信息,然后根据认证信息获取权限信息,通过权限信息和特定的授权策略决定是否授权。 本教程将首先给出一个完整的案例实现,然后再分别对登录认证和访问授权的执行流程进行剖析,希望大家可以通过实现案例和流程分析,充分理解Spring Security的登录认证和访问授权的执行原理,并且能够在理解原理的基础上熟练自主的使用Spring Security实现相关的需求。 实现案例 接下来,我们就通过一个具体的案例,来讲解如何进行Spring Security的整合,然后借助Spring Security实现登录认证和访问控制。 生成项目模板 为方便我们初始化项目,Spring Boot给我们提供一个项目模板生成网站。 1. 打开浏览器,访问:https://start.spring.io/ 2. 根据页面提示,选择构建工具,开发语言,项目信息等。 3. 点击 Generate the project,生成项目模板,生成之后会将压缩包下载到本地。 4. 使用IDE导入项目,我这里使用Eclipse,通过导入Maven项目的方式导入。 添加相关依赖 清理掉不需要的测试类及测试依赖,添加 Maven 相关依赖,这里需要添加上web、swagger、spring security、jwt和fastjson的依赖,Swagge和fastjson的添加是为了方便接口测试。 pom.xml
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.louis.springboot</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!-- web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- swagger --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency> <!-- spring security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- jwt --> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> <!-- fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.58</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> <!-- 打包时拷贝MyBatis的映射文件 --> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/sqlmap/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.*</include> </includes> <filtering>true</filtering> </resource> </resources> </build> </project> |
添加相关配置 1.添加swagger 配置 添加一个swagger 配置类,在工程下新建 config 包并添加一个 SwaggerConfig 配置类,除了常规配置外,加了一个令牌属性,可以在接口调用的时候传递令牌。 SwaggerConfig.java
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
package com.louis.springboot.demo.config; import java.util.ArrayList; import java.util.List; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.ParameterBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.schema.ModelRef; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Parameter; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket createRestApi(){ // 添加请求参数,我们这里把token作为请求头部参数传入后端 ParameterBuilder parameterBuilder = new ParameterBuilder(); List<Parameter> parameters = new ArrayList<Parameter>(); parameterBuilder.name("Authorization").description("令牌").modelRef(new ModelRef("string")).parameterType("header") .required(false).build(); parameters.add(parameterBuilder.build()); return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select().apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()).build().globalOperationParameters(parameters); } private ApiInfo apiInfo(){ return new ApiInfoBuilder() .title("SpringBoot API Doc") .description("This is a restful api document of Spring Boot.") .version("1.0") .build(); } } |
加了令牌属性后的 Swagger 接口调用界面,会多出一个令牌参数,在发起请求的时候一起发送令牌。 2.添加跨域 配置 添加一个CORS跨域配置类,在工程下新建 config 包并添加一个 CorsConfig配置类。 CorsConfig.java
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package com.louis.springboot.demo.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // 允许跨域访问的路径 .allowedOrigins("*") // 允许跨域访问的源 .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") // 允许请求方法 .maxAge(168000) // 预检间隔时间 .allowedHeaders("*") // 允许头部设置 .allowCredentials(true); // 是否发送cookie } } |
安全配置类 下面这个配置类是Spring Security的关键配置。 在这个配置类中,我们主要做了以下几个配置: 1. 访问路径URL的授权策略,如登录、Swagger访问免登录认证等 2. 指定了登录认证流程过滤器 JwtLoginFilter,由它来触发登录认证 3. 指定了自定义身份认证组件 JwtAuthenticationProvider,并注入 UserDetailsService 4. 指定了访问控制过滤器 JwtAuthenticationFilter,在授权时解析令牌和设置登录状态 5. 指定了退出登录处理器,因为是前后端分离,防止内置的登录处理器在后台进行跳转 WebSecurityConfig.java
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
package com.louis.springboot.demo.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler; import com.louis.springboot.demo.security.JwtAuthenticationFilter; import com.louis.springboot.demo.security.JwtAuthenticationProvider; import com.louis.springboot.demo.security.JwtLoginFilter; @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { // 使用自定义登录身份认证组件 auth.authenticationProvider(new JwtAuthenticationProvider(userDetailsService)); } @Override protected void configure(HttpSecurity http) throws Exception { // 禁用 csrf, 由于使用的是JWT,我们这里不需要csrf http.cors().and().csrf().disable() .authorizeRequests() // 跨域预检请求 .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 登录URL .antMatchers("/login").permitAll() // swagger .antMatchers("/swagger**/**").permitAll() .antMatchers("/webjars/**").permitAll() .antMatchers("/v2/**").permitAll() // 其他所有请求需要身份认证 .anyRequest().authenticated(); // 退出登录处理器 http.logout().logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler()); // 开启登录认证流程过滤器 http.addFilterBefore(new JwtLoginFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class); // 访问控制时登录状态检查过滤器 http.addFilterBefore(new JwtAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class); } @Bean @Override public AuthenticationManager authenticationManager() throws Exception { return super.authenticationManager(); } } |
登录认证触发过滤器 JwtLoginFilter 是在通过访问 /login 的POST请求是被首先被触发的过滤器,默认实现是 UsernamePasswordAuthenticationFilter,它继承了 AbstractAuthenticationProcessingFilter,抽象父类的 doFilter 定义了登录认证的大致操作流程,这里我们的 JwtLoginFilter 继承了 UsernamePasswordAuthenticationFilter,并进行了两个主要内容的定制。 1. […]
View Details捕获全局异常是在项目运行期间如果调用的某一个方法出现了运行时异常,则会捕获,并且给出回馈。 首先需要建一个包,包里新建一个捕获异常类GlobalExceptionHandler。前提是springboot的启动类的扫描注解ComponentScan()要扫描到。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/** * 用于捕获全局异常 */ @ControllerAdvice//控制器切面 public class GlobalExceptionHandler { @ExceptionHandler(RuntimeException.class)//捕获运行时异常 @ResponseBody public Map<String,Object> exceptionHandler(){//处理异常方法 Map<String,Object> map=new HashMap<String, Object>(); map.put("errorCode","101"); map.put("errorMsg","系统错误!"); return map; } } |
这个捕获异常类可以捕获到全局的运行时异常,例如商城购物车的控制层一个方法出现异常,黄色背景的是重点,会发生异常。
|
1 2 3 4 5 6 7 |
@RequestMapping("getShoppingCar") public String getShoppingCar(HttpSession session,Model model){ Map<Integer,Cart> cartMap =(Map<Integer,Cart>)session.getAttribute("cartMap"); model.addAttribute("carList",cartMap); int i=1/0; return "udai_shopcart"; } |
然后启动项目,进入主页,当点击购物车按钮时也就是调用了getShoppingCar这个方法,发生了异常,运行结果是跳转页面失败,直接给出异常信息,也就是全局捕获异常类中设置的信息。 配置多数据源# 以前是在applicationContext.xml中配置的,现在springboot通过注解来配置数据源。 首先在application.properties配置文件中加入多数据源配置。
|
1 2 3 4 5 6 7 8 9 |
spring.datasource.test1.url=jdbc:mysql://127.0.0.1:3306/test1?serverTimezone=UTC spring.datasource.test1.username=root spring.datasource.test1.password=1234 spring.datasource.test1.driverClassName=com.mysql.cj.jdbc.Driver spring.datasource.test2.url=jdbc:mysql://127.0.0.1:3306/test2?serverTimezone=UTC spring.datasource.test2.username=root spring.datasource.test2.password=1234 spring.datasource.test2.driverClassName=com.mysql.cj.jdbc.Driver |
在例子开始之前,首先去创建两个用于测试的数据库test1和test2,并且新建两张空表。 写两个数据源的配置类。# 在java文件夹下新建dataSource包,新建数据源配置类DataSource01和DataSource02。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
@Configuration//注解到springboot容器中 @MapperScan(basePackages="com.gyf.test1.mapper",sqlSessionFactoryRef="test1SqlSessionFactory") public class DataSource01 { /** * @return 返回test1数据库的数据源 */ @Bean(name="test1DataSource") @Primary//主数据源,一个应用只能有一个主数据源 @ConfigurationProperties(prefix="spring.datasource.test1") public DataSource dateSource(){ return DataSourceBuilder.create().build(); } /** * @return 返回test1数据库的会话工厂 */ @Bean(name = "test1SqlSessionFactory") public SqlSessionFactory sqlSessionFactory(@Qualifier("test1DataSource") DataSource ds) throws Exception{ SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(ds); return bean.getObject(); } /** * @return 返回test1数据库的事务 */ @Bean(name = "test1TransactionManager") @Primary//主事务 public DataSourceTransactionManager transactionManager(@Qualifier("test1DataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } /** * @return 返回test1数据库的会话模版 */ @Bean(name = "test1SqlSessionTemplate") public SqlSessionTemplate sqlSessionTemplate( @Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } } |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
@Configuration//注解到springboot容器中 @MapperScan(basePackages="com.gyf.test2.mapper",sqlSessionFactoryRef="test2SqlSessionFactory") public class DataSource02 { /** * @return 返回test2数据库的数据源 */ @Bean(name="test2DataSource") @ConfigurationProperties(prefix="spring.datasource.test2") public DataSource dateSource(){ return DataSourceBuilder.create().build(); } /** * @return 返回test2数据库的会话工厂 */ @Bean(name = "test2SqlSessionFactory") public SqlSessionFactory sqlSessionFactory(@Qualifier("test2DataSource") DataSource ds) throws Exception{ SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(ds); return bean.getObject(); } /** * @return 返回test2数据库的事务 */ @Bean(name = "test2TransactionManager") public DataSourceTransactionManager transactionManager(@Qualifier("test2DataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } /** * @return 返回test2数据库的会话模版 */ @Bean(name = "test2SqlSessionTemplate") public SqlSessionTemplate sqlSessionTemplate( @Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } } |
在java文件夹下分别创建两个文件夹test1和test2,分别对这两个数据库进行操作,启动类都需要先扫描到test1和test2的包
|
1 2 3 4 5 6 7 8 9 10 |
@EnableAutoConfiguration @ComponentScan(basePackages = {"com.gyf.datasource","com.gyf.web","com.gyf.test1.service","com.gyf.test2.service"}) public class App { public static void main( String[] args ) { //启动springboot项目 SpringApplication.run(App.class,args); } } |
Test1的userMapper
|
1 2 3 4 |
public interface UserMapper { @Insert("insert user (username,password) values (#{username},#{password})") public int save(@Param("username") String username, @Param("password") String password); } |
Test1的UserServiceImpl
|
1 2 3 4 5 6 7 8 9 |
@Service @Transactional public class UserServiceImpl{ @Autowired private UserMapper userMapper; public void register(String username, String password) { userMapper.save(username,password); } } |
Test2的CustomerMapper
|
1 2 3 4 5 |
public interface CustomerMapper { @Insert("insert customer (name,tel) values (#{name},#{tel})") public int save(@Param("name") String name, @Param("tel") String tel); } |
Test2的CustomerServiceImpl
|
1 2 3 4 5 6 7 8 9 |
@Service @Transactional public class CustomerServiceImpl { @Autowired private CustomerMapper customerMapper; public void save(String name, String tel) { customerMapper.save(name,tel); } } |
最后写一个controller类,调用这两个service
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
@RestController //声明Rest风格的控制器 //@EnableAutoConfiguration //自动配置,相当于写了spring的配置文件 @RequestMapping("user") public class UserController { @Autowired private UserServiceImpl userService; @Autowired private CustomerServiceImpl customerService; @RequestMapping("register") @ResponseBody public String register(String username,String password){ //把数据保存到test1数据库 userService.register(username,password); //把数据保存到test2数据库 customerService.save(username,"120"); return "success"; } } |
启动项目,看数据库表内容,两张表都插入了信息。 from:https://www.cnblogs.com/fantongxue/p/12443377.html
View Details总归上述问题Rt,其实今天开发刚遇到,当时找了半天为啥前台传参后台却接收不到,原来是返回的时候返回小写,但是前台依旧大写传参。 查了很多后发现其实是json返回的时候把首字母变小写了,也就是Spring Boot中Jackson的功劳 百度后得@JsonProperty注解完美解决。但与此同时会出现两个问题 如果注解放到属性上,则返回的时候既有大写也有小写,
|
1 2 |
@JsonProperty("Ao") private Integer Ao; |
Result:{Ao:xxx,ao:xxx} 所以注解放在getter上完美解决,返回只有大写不再自动变为小写的问题。
|
1 2 3 4 |
@JsonProperty("Ao") public Integer getAo() { return Ao; } |
Result:{Ao:xxx} from:https://blog.csdn.net/github_36887863/article/details/81807088
View DetailsVS 是一个很强大的编译器 以前都是根据方法 名Ctrl+F 搜索 很不方便 但VS已经有方便的提示功能了 设置方法 工具>>文本文本编译器>>所有语言>>CodeLens >> 选择启用Code了Lens from:https://blog.csdn.net/q465162770/article/details/104039869
View Details控制台报错: java.lang.NoSuchMethodException:tk.mybatis.mapper.provider.base.BaseSelectProvider.<init>() 浏览器访问:http://localhost:8081/category/list?pid=0 解决办法: 应该导入import tk.mybatis.spring.annotation.MapperScan这个包。 from:https://blog.csdn.net/qq_37495786/article/details/83448614
View Details使用Mybatis的开发者,大多数都会遇到一个问题,就是要写大量的SQL在xml文件中,除了特殊的业务逻辑SQL之外,还有大量结构类似的增删改查SQL。而且,当数据库表结构改动时,对应的所有SQL以及实体类都需要更改。这工作量和效率的影响或许就是区别增删改查程序员和真正程序员的屏障。这时,通用Mapper便应运而生……
View DetailsUnsigned Fields MySql supports both signed, and unsigned, numeric fields. These are not JDBC types, so MyBatis generator cannot automatically account for these types of fields. The Java data types are always signed. This can lead to a loss of precision when using unsigned fields. The solution is to provide a <columnOverride> for any unsigned numeric field in MySql. Here is an example of how to deal with an unsigned bigint field in MySql:
|
1 2 3 |
<table tableName="ALLTYPES" > <columnOverride column="UNSIGNED_BIGINT_FIELD" javaType="java.lang.Object" jdbcType="LONG" /> </table> |
You will have to cast the returned value to the appropriate type yourself (in this […]
View Details错误日志:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Exception in thread "main" java.lang.NoClassDefFoundError: org/mybatis/generator/api/dom/xml/Element at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:348) at org.mybatis.generator.internal.ObjectFactory.internalClassForName(ObjectFactory.java:144) at org.mybatis.generator.internal.ObjectFactory.createInternalObject(ObjectFactory.java:180) at org.mybatis.generator.internal.ObjectFactory.createCommentGenerator(ObjectFactory.java:241) at org.mybatis.generator.config.Context.getCommentGenerator(Context.java:266) at org.mybatis.generator.codegen.mybatis3.model.SimpleModelGenerator.getCompilationUnits(SimpleModelGenerator.java:51) at org.mybatis.generator.codegen.mybatis3.IntrospectedTableMyBatis3Impl.getGeneratedJavaFiles(IntrospectedTableMyBatis3Impl.java:181) at org.mybatis.generator.config.Context.generateFiles(Context.java:460) at org.mybatis.generator.api.MyBatisGenerator.generate(MyBatisGenerator.java:262) at org.mybatis.generator.api.MyBatisGenerator.generate(MyBatisGenerator.java:132) at com.weChat.MybatisStartup.GeneratorDisplay.generator(GeneratorDisplay.java:33) at com.weChat.MybatisStartup.GeneratorDisplay.main(GeneratorDisplay.java:17) Caused by: java.lang.ClassNotFoundException: org.mybatis.generator.api.dom.xml.Element at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 13 more |
原因及其解决办法: 错误日志中很明显的说是 mybatis 的代码自动生成依赖 generator 的 api 存在问题,查看 pom.xml 文件的依赖,发现引用是正常的,也就是说引用和使用都不可能有问题,因为我并没有直接操作 generator 的 api ,那么只可能是版本的问题了,而我的这个依赖的版本是 1.4.0 ,是目前最高的版本: 所以只有可能是我的版本太高了,下降一个版本试试,换成1.3.7的果然就好了!看来做这个不能写的太满,不然很容易给自己埋雷啊! from:https://www.cnblogs.com/90s-ITBoy/p/13388452.html
View Details在 Intellij IDEA 中结合 Gradle 使用 MyBatis Generator 逆向生成代码 Info: JDK 1.8 Gradle 2.14 Intellij IDEA 2016.3 前言 由于 IDEA 的教程较少,且 MyBatis Generator 不支持 Gradle 直接运行,因此这次是在自己折腾项目过程中,根据一些参考资料加上自己的实践得出的结论,并附上相应的 Demo 可供自己未来参考,也与大家分享。 本文的 Demo 也可以当作工具直接导入 IDEA,加上自己的数据库信息即可生成代码。 创建项目 详细的创建步骤可以参考使用 Gradle 构建 Struts 2 Web 应用中「新建 Gradle Web 项目」一节即可。当创建完毕,需要等待 Gradle 联网构建,由于国内网络因素,可能需要稍作等待。当构建完成,目录结构应如下图一致: Gradle 构建完成 配置依赖 这里需要使用 MyBatis Generator,MySQL 驱动,以及 MyBatis Mapper。由于代码生成单独运行即可,不需要参与到整个项目的编译,因此在 build.gradle 中添加配置:
|
1 2 3 |
configurations { mybatisGenerator } |
在 Maven Repository (http://mvnrepository.com/) 分别搜索依赖: org.mybatis.generator mysql-connector-java tk.mybatis:mapper 依赖的版本并不是局限于某个特定版本,可以选择适时相应的更新版本。添加到 build.gradle 的 dependencies 中(注意前面需将「compile group:」改为 「mybatisGenerator」):
|
1 2 3 4 5 6 7 |
dependencies { testCompile group: 'junit', name: 'junit', version: '4.11' mybatisGenerator 'org.mybatis.generator:mybatis-generator-core:1.3.5' mybatisGenerator 'mysql:mysql-connector-java:5.1.40' mybatisGenerator 'tk.mybatis:mapper:3.3.9' } |
设置数据库信息 在 resources 下,新建 mybatis 文件夹,并新建 config.properties 和 generatorConfig.xml,文件结构如下: 配置文件目录 在 config.properties 中配置数据库和要生成的 […]
View Details今天写东西测试的时候发现一个问题,如下: application.yml中数据源是这样配置的: 第一反应就是记忆中连接mysql的驱动不都是com.mysql.jdbc.Driver吗?com.mysql.cj.jdbc.Driver是什么鬼? 后来查看了一下才知道 这个跟驱动的依赖版本有关
|
1 2 3 4 5 |
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> |
com.mysql.cj.jdbc.Driver是mysql-connector-java 6 中的特性,相比mysql-connector-java 5 多了一个时区:serverTimezone,把数据源配置的驱动改一下就好了 这样启动就不会再报:Loading class com.mysql.jdbc.Driver'. This is deprecated. The new driver class iscom.mysql.cj.jdbc.Driver’. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary. 使用UTC会有8小时的时差(中国快全球标准8小时,比如:全球标准当前是上午1点,中国时间则为上午9点),可设置为北京时间东八区GMT%2B8 或者上海时间Asia/Shanghai。 总结: com.mysql.jdbc.Driver和mysql-connector-java 5一起用。 com.mysql.cj.jdbc.Driver和mysql-connector-java 6 一起用。 from:https://blog.csdn.net/weixin_43770545/article/details/90486809
View Details