zoukankan      html  css  js  c++  java
  • SSH随手记

    SSH是Spring + Struts + Hibernate,Struts是对Servlet的一个封装,通过配置文件来达到对Web请求做处理;SpringMVC是对系统的设计,使用轻量级、最小侵入的原则,通过配置文件使得程序员可以更专注逻辑/业务处理;Hibernate是对jdbc的优化处理,可以使用Hibernate直接操作bean,使用hibernate中的Session来操作数据库,支持事务处理。

    Struts

    一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。

    主要配置struts.xml

    <package name="default" namespace="" extends="struts-default">
      <action name="action" class="com.test.demo.Action" method="sayHello">
        <result name="success" value="">some.jsp</result>
      </action>
    </package>

    注解方式:

    @ParentPackage("struts-default")// 与package中的extends功能一样
    @Namespace("/user")// package中的namespace一样,指定上级请求
    public class UserAction extends ActionSupport implements ServletRequestAware, ServletResponseAware {
        
        private static final long serialVersionUID = 1L;
        private HttpServletRequest req;
        private HttpServletResponse resp;
        
        @Action("/login")
        public void login() throws Exception { // do login }
    }

    上面的示例代码中有实现 ServletRequestAware 和 ServletResponseAware 接口,这两个接口可以让我们获取到对应的 HttpServletRequest、HttpServletResponse 。

    获取其参数也可以通过Context:

    ServletActionContext.getRequest();
    ServletActionContext.getServletContext();
    ServletActionContext.getContext().getParameters();

    需要注意的是获取post中的JSON数据时需要通过流的形式读取,我这里使用的是 BufferedReader 读取其字符,并相应解码:

        private String parseReq() throws IOException {
            BufferedReader br = this.request.getReader();
            String line = null;
            StringBuilder sb = new StringBuilder();
            while((line = br.readLine()) != null) {
                sb.append(line);
            }
            JSONObject json = JSON.parseObject(sb.toString());
            return json.toJSONString();
        }

    Struts也可以实现输入验证及国际化,具体的请百度。可能listener这个配置我们开发中会用到,可以用来实现在线人数的统计,通过实现 HttpSessionListener  来监听

    // 会话被创建
    default public void sessionCreated(HttpSessionEvent se) {}
    // 会话被销毁
    default public void sessionDestroyed(HttpSessionEvent se) {}

    如果需要实现其他的功能,可以设置其他的Listener,并获取相应的数据,这里就不说了。

    Hibernate

    1、配置文件:配置一些数据库需要的基本数据,数据库引擎、url、driver、用户名、密码等基本配置,还有就是hibernate的参数配置,能使性能更佳。

    2、创建持久化对象

    public class Bean {
      private int userId;
    private String name; // ...... }

    使用hibernate应该使用xml配置,获取对应文件的获取,文档上介绍的是xml获取效率更高

    <hibernate-mapping>
        <class name="com.test.user.User" table="USER">
            <id name="userId" type="int">
                <column name="USERID" />
                <generator class="increment" />
            </id>
            <property name="name" type="java.lang.String">
                <column name="NAME" />
            </property>
        </class>
    </hibernate-mapping>

    3、获取Configuration  new StandardServiceRegistryBuilder().configure() 

    4、获取SessionFactory

        private static void getSessionFactory() {
            final StandardServiceRegistry sr = new StandardServiceRegistryBuilder().configure().build();
            try {
                sf = new MetadataSources(sr).buildMetadata().buildSessionFactory();
            } catch (Exception e) {
                e.printStackTrace();
                StandardServiceRegistryBuilder.destroy(sr);
            }
        }

    5、获取Session接口操作数据库  

    getSessionFactory();
    s = sf.openSession();
    session.set(s);

    6、获取事务接口Transaction 

    session.beginTransaction();
    // some operations ;
    transaction.commit()

    7、通过 session.createQuery("HQL"); session.createSQLQuery("原生的sql语句"); 获取Query实例

    关于HQL语句

    与原生SQL类似, from、select、where以及其他的运算符 ,HQL可以直接使用对象进行操作。Hibernate中的映射关系需要注意,

    有一对一双/单向、一对多单/双、多对多单/双向的配置问题,下面是一对一双向的配置示例:

    <!-- Person.hbm.xml -->
    <
    hibernate-mapping> <class name="Person" table="PERSON" lazy="true"> <id name="id" type="int"><column name="ID"/><generator class="native"/></id> <property name="name"/> <one-to-one name="idCard" class="IdCard" fetch="join" cascade="all"></one-to-one> </class> </hibernate-mapping>
    <!-- IdCard.hbm.xml --> <hibernate-mapping> <calss name="IdCard" table="ID_CARD" lazy="true"> <id name="id" type="int"> <column name="ID"/> <!-- 引用person的主键作为IdCard的主键和外健 --> <generator class="foreign"> <param name="property">person</param> </generator> <id> <property name="cardNo"/> <!-- 表示IdCard引用了person的主键作为了外健 --> <one-to-one name="person" class="Person" constrained="true"></one-to-one> </class> </hibernate-mapping>

    其相应的Java类

    public class Person {
        private IdCard idCard;
        private String name;
        private int id;
        // get setter....
    }
    
    public class IdCard {
        private Person person;
        private String cardNo;
        private int id;
        // get setter....
    }

    Spring

    IoC/DI

    控制反转/依赖注入,简单来说就是由一个类(也就是Context)去创建bean对象,然后通过注入的方式产生使用类对bean的引用,bean的生命周期由Context控制。

    示例:

    class ADemo { public void methodA() { //...... } }
    class BDemo { public void methodB() { //...... } }

    如果在ADemo中需要使用到BDemo对象,那么我们可以使用Context创建,就跟main函数一样:

    class ADemo {
        private BDemo b;
        public void setB(BDemo b) { this.b = b; }
        public void methodA() { b.methodB(); //...... }
    }
    
    class BDemo {
        public void methodB() { //...... }
    }
    
    class ExampleContext {
        public static void main(String[] args) {
            ADemo a = new ADemo();
            BDemo b = new BDemo();
            // 将b注入到使用者a中,这样a只对b产生了引用,并没有实际拥有
            // 一般想到的方法是向a中声明一个属性,然后通过set方法注入
            a.setB(b);
        }
    }

    当然也是可以使用构造器注入,接口注入(其实相当于方法注入)等等,最主要的思想是将a对b的一个强引用变成弱引用,使得使用者无需考虑其声明周期及内存管理问题,同时还能将这个对象复用,减少多个重复对象的创建。

    在Spring中通过 AnnotationConfigApplicationContext  ClassPathXmlApplicationContext 读取相关的配置,利用Java的反射机制获取相关类并创建实例对象,在需要的时候注入到相关的类中。

    AOP

    AOP为Aspect Oriented Programming的缩写,面向切面编程,在不改动原来代码情况下插入需要执行的代码,可以很好的处理日志打印。简单的理解就是在指定的规则下筛选出符合规定的方法,aop有before、after、around,可以在方法之前、之后、环绕的时候织入代码。说到织入代码,分为两种:静态织入、动态织入,静态织入是需要借助 execution 表达式,表达式的格式为:

    execution(<修饰符模式>?<返回类型模式><方法名模式>(<参数模式>)<异常模式>?)
    // 比如:
    @Before("execution(* com.demo.aop.BDemo.methodB(..))")
        public void methodA(JoinPoint jp) {
        // do something
    }

    动态织入我理解为做标记,由Spring容器发现需要织入的PointCut,首先需要定义一个注解,这个注解就是一个标记符,在告诉Spring 这是一个标记

    // 只能方法使用
    @Target(ElementType.METHOD)
    // 运行时
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ExampleAop {
        String name();
    }

    定义好了标记之后,就需要指定方法需要被关注,直接使用@ExampleAop("some info")来标记

    @ExampleAop(name="注解式拦截的methodA")
    public void methodA() {
        // do something
    }

    做完这些之后,我们需要对这个标记附上意义,就犹如你定义一个“œ”操作符,如果你没规定这个符号代表什么,也就无法使用它,就像我们使用“+”表示两个数的相加一样,那么我们将ExampleAop作为一个筛选的规则,所有打上这个标记的方法都需要执行某段代码。如:

        // 注解式拦截
        @Pointcut("@annotation(com.demo.aop.ExampleAop)")
        public void annotionPointcut() {}    
        
        @Before("annotionPointcut()")
        public void methodBefore(JoinPoint jp) {
            System.out.println("上帝啊,竟然在一个切面里添加多个Before,使用不同的方式拦截");
        }

    所有由标记的方法都会在执行前加上一句打印。

    在Spring MVC中,如果我们使这些打印实现的话,还需要配置文件,这里我贴上代码,就不详细介绍了

    @Configuration
    @ComponentScan("com.demo.aop")
    @EnableAspectJAutoProxy// 开启对AspectJ代理的支持
    public class ConfigAop {
    
    }

    需要了解更多的可以阅读相关文档(Spring家族文档) 

  • 相关阅读:
    Linux安装python3.6
    Python安装常见问题(1):zipimport.ZipImportError: can't decompress data
    ModuleNotFoundError: No module named 'apt_pkg'
    【第九届蓝桥杯大赛决赛真题】JAVA大学C组题解
    Mineweep(扫雷)
    Josephus环的四种解法(约瑟夫环)
    java背包的数组实现,链表实现
    Java 实现栈,队列
    java实现单链表
    MySql8最新配置方式(完美)
  • 原文地址:https://www.cnblogs.com/meilj/p/9563784.html
Copyright © 2011-2022 走看看