Java Apache Shiro安全框架快速开发详解流程

目录
  • 一、Shiro简介:
    • shiro功能:
    • Shiro架构(外部)
    • Shiro架构(内部)
  • 二、快速入门
    • 1.拷贝案例
    • 2.分析代码
  • 三、SpringBoot 集成 Shiro
    • 1.编写测试环境
    • 2.使用
      • 1.登录拦截
      • 2.用户认证
  • 四、Shiro整合Mybatis
  • 五、实现请求授权
  • 六、Shiro整合Thymeleaf

一、Shiro简介:

Apache Shiro是一个Java的安全(权限)框架。
Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE环境,也可以用在JavaEE环境。Shiro可以完成,认证,授权,加密,会话管理,Web集成,缓存等。
官网地址:Apache Shiro | Simple. Java. Security.

shiro功能:

Authentication:身份认证、登录,验证用户是不是拥有相应的身份;
Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限,即判断用户能否进行什么操作,如:验证某个用户是否拥有某个角色,或者细粒度的验证某个用户对某个资源是否具有某个权限!
Session Manager:会话管理,即用户登录后就是第一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通的JavaSE环境,也可以是Web环境;
Cryptography:加密,保护数据的安全性,如密码加密存储到数据库中,而不是明文存储;Web Support: Web支持,可以非常容易的集成到Web环境;
Caching:缓存,比如用户登录后,其用户信息,拥有的角色、权限不必每次去查,这样可以提高效率
Concurrency: Shiro支持多线程应用的并发验证,即,如在一个线程中开启另一个线程,能把权限自动的传播过去
Testing:提供测试支持;
Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了

Shiro架构(外部)

从外部来看Shiro,即从应用程序角度来观察如何使用shiro完成工作:

subject:应用代码直接交互的对象是Subject,也就是说Shiro的对外API核心就是Subject,Subject代表了当前的用户,这个用户不一定是一个具体的人,与当前应用交互的任何东西都是Subject,如网络爬虫,机器人等,与Subject的所有交互都会委托给SecurityManager; Subject其实是一个门面,SecurityManageer才是实际的执行者
SecurityManager: 安全管理器,即所有与安全有关的操作都会与SercurityManager交互,并且它管理着所有的Subject,可以看出它是Shiro的核心,它负责与Shiro的其他组件进行交互,它相当于SpringMVC的
DispatcherServlet的角色
Realm: Shiro从Realm获取安全数据((如用户,角色,权限),就是说SecurityManager要验证用户身份,那么它需要从Realm 获取相应的用户进行比较,来确定用户的身份是否合法;也需要从Realm得到用户相应的角色、权限,进行验证用户的操作是否能够进行,可以把Realm看成DataSource;

Shiro架构(内部)

subject:任何可以与应用交互的'用户';
Security Manager:相当于SpringMVC中的DispatcherServlet;是Shiro的心脏,所有具体的交互都通过Security Manager进行控制,它管理者所有的Subject,且负责进行认证,授权,会话,及缓存的管理.

Authenticator:负责Subject认证,是一个扩展点,可以自定义实现;可以使用认证策略(AuthenticationStrategy),即什么情况下算用户认证通过了;
Authorizer: 授权器,即访问控制器,用来决定主体是否有权限进行相应的操作;即控制着用户能访问应用中的那些功能;
Realm:可以有一个或者多个的realm,可以认为是安全实体数据源,即用于获取安全实体的,可以用DBC实现,也可以是内存实现等等,由用户提供;所以一般在应用中都需要实现自己的realm
SessionManager: 管理Session生命周期的组件,而Shiro并不仅仅可以用在Web环境,也可以用在普通的JavaSE环境中
CacheManager:缓存控制器,来管理如用户,角色,权限等缓存的;因为这些数据基本上很少以受,成到缓存中后可以提高访问的性能;
Cryptography:密码模块,Shiro提高了一些常见的加密组件用于密码加密,解密等

二、快速入门

1.拷贝案例

1.按照官网提示找到 快速入门案例 GitHub地址:shiro/samples/quickstart/

2.新建一个 Maven 工程,删除其 src 目录,将其作为父工程

3.在父工程中新建一个 Maven 模块

4.复制快速入门案例 POM.xml 文件中的依赖

<dependencies>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.4.1</version>
        </dependency>

        <!-- configure logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.7.29</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.29</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>

5.把快速入门案例中的 resource 下的log4j.properties复制下来

6.复制一下shiro.ini文件

7.复制一下Quickstart.java文件

8.运行启动Quickstart.java

2.分析代码

public class Quickstart {
    private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);
    public static void main(String[] args) {
        //工厂模式,通过shiro.ini配置文件中的信息,生成一个工厂实例
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
        //获取当前的用户对象Subject
        Subject currentUser = SecurityUtils.getSubject();
        //通过当前用户拿到session
        Session session = currentUser.getSession();
        session.setAttribute("someKey", "aValue");
        String value = (String) session.getAttribute("someKey");
        if (value.equals("aValue")) {
            log.info("Subject=>session[" + value + "]");
        }
        //判断当前的用户是否被认证
        if (!currentUser.isAuthenticated()) {
            //Token :令牌,没有获取,随机
            UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
            token.setRememberMe(true);  //设置记住我
            try {
                currentUser.login(token); //执行了登录操作
            } catch (UnknownAccountException uae) {
                //如果   用户名不存在
                log.info("There is no user with username of " + token.getPrincipal());
            } catch (IncorrectCredentialsException ice) {
                //如果   密码不正确
                log.info("Password for account " + token.getPrincipal() + " was incorrect!");
            } catch (LockedAccountException lae) {
                //用户被锁定,如密码输出过多,则被锁定
                log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                        "Please contact your administrator to unlock it.");
            }
            //...在此处捕获更多异常
            catch (AuthenticationException ae) {
                //意外情况 ? 错误 ?
            }
        }
        //打印其标识主体(在这种情况下,为用户名)
        log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");

        //测试角色是否存在
        if (currentUser.hasRole("schwartz")) {
            log.info("May the Schwartz be with you!");
        } else {
            log.info("Hello, mere mortal.");
        }
        //粗粒度,极限范围小
        //测试类型化的极限(不是实例级别)
        if (currentUser.isPermitted("lightsaber:wield")) {
            log.info("You may use a lightsaber ring.  Use it wisely.");
        } else {
            log.info("Sorry, lightsaber rings are for schwartz masters only.");
        }
        //细粒度,极限范围广
        //实例级别的权限(非常强大)
        if (currentUser.isPermitted("winnebago:drive:eagle5")) {
            log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'.  " +
                    "Here are the keys - have fun!");
        } else {
            log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
        }
        //注销
        currentUser.logout();
        //退出
        System.exit(0);
    }
}

三、SpringBoot 集成 Shiro

1.编写测试环境

1.在刚刚的父项目中新建一个 springboot 模块

2.导入 SpringBoot 和 Shiro 整合包的依赖

 <!--SpringBoot 和 Shiro 整合包-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.1</version>
        </dependency>

下面是编写配置文件
Shiro 三大要素

Subject 用户 -> ShiroFilterFactoryBean
SecurityManager 管理所有用户 -> DefaultWebSecurityManager
Realm 连接数据

实际操作中对象创建的顺序 : realm -> securityManager -> subject

3.编写自定义的 realm ,需要继承 AuthorizingRealm

//自定义的 UserRealm        extends AuthorizingRealm
public class UserRealm extends AuthorizingRealm {
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //打印一个提示
        System.out.println("执行了授权方法");
        return null;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //打印一个提示
        System.out.println("执行了认证方法");
        return null;
    }
}

4.新建一个ShiroConfig配置文件

@Configuration
public class ShiroConfig {

    //ShiroFilterFactoryBean:3
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebsecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultWebsecurityManager);
        return bean;
    }
    //DefaultWebSecurityManager:2
    @Bean(name="securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
        //关闭UserRealm
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    //创建realm 对象,需要自定义类:1
    @Bean(name="userRealm")
    public UserRealm userRealm(){
        return new UserRealm();
    }
}

5.测试成功!

2.使用

1.登录拦截

在getShiroFilterFactoryBean方法中添加需要拦截的登录请求

@Configuration
public class ShiroConfig {

    //ShiroFilterFactoryBean:3
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebsecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultWebsecurityManager);
        //添加shiro的内置过滤器
        /*
            anon : 无需认证,就可以访问
            authc : 必须认证了才能访问
            user : 必须拥有 “记住我” 功能才能用
            perms : 拥有对某个资源的权限才能访问
            role : 拥有某个角色权限才能访问
         */

        filterMap.put("/user/add","authc");
        filterMap.put("/user/update","authc");
        //拦截
        Map<String,String> filterMap=new LinkedHashMap<>();
        filterMap.put("/user/*","authc");
        bean.setFilterChainDefinitionMap(filterMap);

//        //设置登录的请求
//        bean.setLoginUrl("/toLogin");
        return bean;
    }

测试:点击 add链接,不会跳到 add 页面,而是跳到登录页,拦截成功

2.用户认证

1.在Controller层写一个登录的方法

    //登录的方法
    @RequestMapping("/login")
    public String login(String username, String password, Model model) {
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //封装用户的登录数据,获得令牌
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        //登录 及 异常处理
        try {
            //执行用户登录的方法,如果没有异常就说明OK了
            subject.login(token);
            return "index";
        } catch (UnknownAccountException e) {
            //如果用户名不存在
            System.out.println("用户名不存在");
            model.addAttribute("msg", "用户名错误");
            return "login";
        } catch (IncorrectCredentialsException ice) {
            //如果密码错误
            System.out.println("密码错误");
            model.addAttribute("msg", "密码错误");
            return "login";
        }
    }
}

2.测试

可以看出是先执行了自定义的UserRealm中的AuthenticationInfo方法,再执行登录相关的操作

3.修改UserRealm中的doGetAuthenticationInfo方法

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //打印一个提示
        System.out.println("执行了认证方法");
        // 用户名密码
        String name = "root";
        String password = "123456";
        //通过参数获取登录的控制器中生成的 令牌
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        //用户名认证
        if (!token.getUsername().equals(name)){
            // return null UnKnownAccountException
            return null;
        }
        //密码认证, Shiro 自己做,为了避免和密码的接触
        //最后返回一个 AuthenticationInfo 接口的实现类,这里选择 SimpleAuthenticationInfo
        // 三个参数:获取当前用户的认证 ; 密码 ; 认证名
        return new SimpleAuthenticationInfo("", password, "");
    }
}

4.测试,输入错误的密码

输入正确的密码,即可登录成功

四、Shiro整合Mybatis

1.导入依赖

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.12</version>
        </dependency>
       <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>

2.新建个application.yml

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

    #Spring Boot 默认是不注入这些属性值的,需要自己绑定
    #druid 数据源专有配置
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true

    #配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
    #如果允许时报错  java.lang.ClassNotFoundException: org.apache.log4j.Priority
    #则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
mybatis:
  type-aliases-package: com.huang.pojo
  mapper-locations: classpath:mybatis/mapper/*.xml

3.在application.properties

mybatis.type-aliases-package=com.longdi.pojo
mybatis.mapper-locations=classpath:mapper/*.xml

4.导入依赖

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
            <scope>provided</scope>
        </dependency>

5.编写User类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
        private int id;
        private String name;
        private String pwd;
        private String perms;
}

6.编写UserMapper

@Repository
@Mapper
public interface UserMapper {
    public User  queryUserByName(String name);

}

7.编写UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.longdi.mapper.UserMapper">

    <select id="queryUserByName" resultType="User" parameterType="String">
        select * from mybatis.user where name=#{name}
    </select>

</mapper>

8.Service层

UserService接口:

public interface UserService {
    public User queryUserByName(String name);
}

9.编写接口实现类UserServiceImpl

@Service
public class UserServiceImpl implements UserService{

    @Autowired
    UserMapper userMapper;

    @Override
    public User queryUserByName(String name) {
        return userMapper.queryUserByName(name);
    }
}

10.在ShiroSpringbootApplicationTests测试

@SpringBootTest
class ShiroSpringbootApplicationTests {
    @Autowired
    UserServiceImpl userService;
    @Test
    void contextLoads() {
        System.out.println(userService.queryUserByName("longdi"));
    }
}

11.成功连接数据库

五、实现请求授权

1.在ShiroConfig类中修改

2.controller跳转

3.登录拦截授权,测试成功

4.编写授权doGetAuthorizationInfo方法

5.请求授权测试成功

六、Shiro整合Thymeleaf

1.导入依赖

        <!--shiro和thymeleaf整合-->
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>

2.整合ShiroDialect

3.index.html

4.测试

5.在认证里放session

6.修改index.html

到此这篇关于Java Apache Shiro安全框架快速开发详解流程的文章就介绍到这了,更多相关Java Shiro框架内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • springboot整合shiro的过程详解

    目录 什么是 Shiro Shiro 架构 Shiro 架构图 Shiro 工作原理 Shiro 详细架构图 springboot 整合 shiro springboot 整合 shiro 思路 项目搭建 主要依赖 数据库表设计 实体类 自定义 Realm shiro 的配置类 ShiroFilterFactoryBean 过滤器链配置中的 url 匹配规则 ShiroFilterFactoryBean 过滤器 ShiroFilterFactoryBean 过滤器分类 前端页面 登录页面 log

  • 详解springboot shiro jwt实现权限管理

    springboot + shiro + jwt (详情解析+代码实现)加密接口 设置权限 首先需要把shiro的几个配置类给下载好(我已经把需要的配置类给放到了github和网盘之中) 先讲完各个配置类的作用,后面讲具体流程 ShiroConfig.java 类主要是设置了过滤器 和shiro自己的session,假如这个类没有放行就只有token才能访问后端接口 UserRealm.java 类主要是检测用户权限和授予权限,对用户名的验证 JWTFilter.java 类主要是防止别人访问你

  • spring-shiro权限控制realm实战教程

    目录 spring-shiro权限控制realm 用户与角色实体 Realm类 Shiro 配置类 控制器 Service shiro权限不生效原因分析 shiro遇到的坑 问题原因:权限标签定义问题 spring-shiro权限控制realm 用户与角色实体 Role.java @Data @Entity public class Role { @Id @GeneratedValue private Integer id; private Long userId; private String

  • springboot整合shiro之thymeleaf使用shiro标签的方法

    thymeleaf介绍 简单说, Thymeleaf 是一个跟 Velocity.FreeMarker 类似的模板引擎,它可以完全替代 JSP .相较与其他的模板引擎,它有如下三个极吸引人的特点: 1.Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果.这是由于它支持 html 原型,然后在 html 标签里增加额外的属性来达到模板+数据的展示方式.浏览器解释 html 时会忽略未定义的标签属性,所以 t

  • springboot整合shiro实现记住我功能

    前言 上一篇文章我们完成了在 thymeleaf 模板引擎中使用 shiro 标签,也就是根据不同的用户身份信息,前端页面来显示不同的页面内容.本篇文章我们来完成在登录页面的记住我的功能 springboot 整合 shiro 之实现记住我 项目依然使用 springboot整合shiro这个项目,稍稍改动即可完成记住我的功能 配置类 ShiroConfig 完整的代码如下 @Configuration public class ShiroConfig { /** * 安全管理器 * * @pa

  • shiro 与 SpringMVC的整合完美示例

    想要整合Shiro和springmvc,在网上找了很多例子,感觉都有一点复杂.所以就自己写了一个最简单整合项目,记录在这里以备后面查看. 这个例子包含如下三个部分: 1.简单的页面 2.shiro配置 3.springmvc配置 shiro可以直接和spring整合,但是这样需要单独配置spring用于整合shiro,在配置springmvc.配置文件看起来乱七八糟的.所以这里就shiro不采用spring来管理.因此这里的整合类似 shiro + servlet + springmvc.这样配

  • Java Apache Shiro安全框架快速开发详解流程

    目录 一.Shiro简介: shiro功能: Shiro架构(外部) Shiro架构(内部) 二.快速入门 1.拷贝案例 2.分析代码 三.SpringBoot 集成 Shiro 1.编写测试环境 2.使用 1.登录拦截 2.用户认证 四.Shiro整合Mybatis 五.实现请求授权 六.Shiro整合Thymeleaf 一.Shiro简介: Apache Shiro是一个Java的安全(权限)框架. Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE环境,也可以用在Ja

  • Java spring的三种注入方式详解流程

    目录 设置Spring的作用域 自动注入 @Primary Qualifier @ComponentScan不同的配置对性能的影响 懒加载 三种注入方式 字段注入(IDEA 会提示不推荐) 字段注入的bean类外部不可见 循环依赖问题 构造器注入(官方推荐) set方法注入 设置Spring的作用域 或者使用枚举值设置 单例和多里使用场景 自动注入 @Primary 一个接口有多个实现被spring管理吗,在依赖注入式,spring会不知道注入哪个实现类就会抛出NoUniqueBeanDefin

  • Java 实现限流器处理Rest接口请求详解流程

    Maven依赖 <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>31.0.1-jre</version> </dependency> 代码 上代码,不废话. 首先是限流器代码. package com.huyi.csdn.tools.rate; import com.google.c

  • Java文件(io)编程之记事本开发详解

    本文实例为大家分享了Java开发简易记事本的具体代码,供大家参考,具体内容如下 public class NotePad extends JFrame implements ActionListener{ //定义需要的组件 JTextArea jta=null; //多行文本框 JMenuBar jmb=null; //菜单条 JMenu jm1=null; //菜单 JMenuItem jmi1=null,jmi2=null; //菜单项 public static void main(St

  • Java Mybatis框架多表操作与注解开发详解分析

    目录 一对一查询 多对多查询 Mybatis的注解开发 Mybatis的增删查改 MyBatis的注解实现复杂映射开发 一对一查询 一对一查询的模型 用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户. 一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户 一对一查询的语句 对应的sql语句: select * from orders o,user u where o.uid=u.id;查询的结果如下: 创建Order和User实体 创建OrderMapper接口 p

  • Java Mybatis框架增删查改与核心配置详解流程与用法

    目录 Mybatis简介 Mybatis开发步骤: Mybatis的映射文件概述 Mybatis的增删改查操作 MyBatis的核心配置文件概述 MyBatis核心配置文件层级关系 MyBatis常用配置解析 Mybatis相应API 原始JDBC操作 原始jdbc操作(查询数据) 原始jdbc操作(插入数据) 原始jdbc操作的分析原始jdbc开发存在的问题如下: ①数据库连接创建.释放频繁造成系统资源浪费从而影响系统性能 ②sql 语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可

  • Java MyBatis框架环境搭建详解

    目录 一.MyBatis简介 1.MyBatis历史 2.MyBatis特性 3.MyBatis下载 4.和其它持久化层技术对比 JDBC Hibernate 和 JPA MyBatis 二.搭建MyBatis 1.开发环境 2.创建maven工程 3.创建MyBatis的核心配置文件 4.创建mapper接口 5.创建MyBatis的映射文件 6.通过junit测试功能 7.加入log4j日志功能 一.MyBatis简介 1.MyBatis历史 MyBatis最初是Apache的一个开源项目i

  • 基于Java中最常用的集合类框架之HashMap(详解)

    一.HashMap的概述 HashMap可以说是Java中最常用的集合类框架之一,是Java语言中非常典型的数据结构. HashMap是基于哈希表的Map接口实现的,此实现提供所有可选的映射操作.存储的是对的映射,允许多个null值和一个null键.但此类不保证映射的顺序,特别是它不保证该顺序恒久不变. 除了HashMap是非同步以及允许使用null外,HashMap 类与 Hashtable大致相同. 此实现假定哈希函数将元素适当地分布在各桶之间,可为基本操作(get 和 put)提供稳定的性

  • Java Executor 框架的实例详解

    Java Executor 框架的实例详解 大多数并发都是通过任务执行的方式来实现的. 一般有两种方式执行任务:串行和并行. class SingleThreadWebServer { public static void main(String[] args) throws Exception { ServerSocket socket = new ServerSocket(80); while(true) { Socket conn = socket.accept(); handleRequ

  • Java NIO服务器端开发详解

    一.NIO类库简介 1.缓冲区Buffer Buffer是一个对象,包含一些要写入和读出的数据. 在NIO中,所有的数据都是用缓冲区处理的,读取数据时,它是从通道(Channel)直接读到缓冲区中,在写入数据时,也是从缓冲区写入到通道. 缓冲区实质上是一个数组,通常是一个字节数组(ByteBuffer),也可以是其它类型的数组,此外缓冲区还提供了对数据的结构化访问以及维护读写位置等信息. Buffer类的继承关系如下图所示: 2.通道Channel Channel是一个通道,网络数据通过Chan

随机推荐