阿斯顿

第6章

linux语法见第六章笔记。

======================================================================

redis基础类型语法见day22--linux软件安装&Redis入门.pdf,高级语法见day23--Redis.pdf。

redis语法简介:

String:
set a 1/get a/del a:设置a=1/获取a的值(1)/删除a=1
incr a/desc a:给a的值加/减1,a不是数值则报错,不存在则初始化a=1/-1
incrby a 3/decrby a 4:给a的值加3/减4,a不是数值则报错,不存在则初始化a=3/-4
append a fuck:给a后面加上字符串fuck

hash:(相当于dict/map)
hset h1 a 1/hmset h1 b 2 c 3:给map h1 put(a,1)/put(b,2)和put(c,3)
hget h1 a/hmget h1 b c:h1.get(a)/h1.get(b) h1.get(c)
hdel h1 a b/del h1:h1.delete(a) h1.delete(b)/删除整个h1
hincrby h1 a 3:给h1的a增加3,报错和初始化情况同incrby
hexists h1 a/hlen h1:h1里有没有a这个key/h1的长度
hkeys h1/hvals h1:h1的所有key/value

lpush l a b c/rpush l x y z:左/右边依次插入
lrange l 0 -1:遍历全部l,输出c b a x y z
lpop l /rpop l:弹出一个元素
llen l:l的长度
lpushx l a/rpushx l x:当l存在是插入,不存在时不处理

sadd s a b c/srem s a:往集合s里添加a,b,c/从s移除'a'
smembers s/sismember s c:获取s的所有元素/判断c是不是s的元素
scard s:获取s的元素的数量
sdiff/sinter/sunion:返回几个集合的差集/交集/并集

通用方法:
keys *:所有key
del key1 key2:删除key1和key2
exists key:key是否存在
rename oldkey newkey:重命名
type key:返回类型(list/hash/string/set/zset)

select 1:使用1号数据库
move xx 1:把当前数据库的xx移动到1号数据库
quit:退出连接
dbsize:获取当前数据库的keys的数量
info:获取服务器的信息
flushdb:删除当前数据库的所有key
flushall:删除所有数据库的所有key
subscibe cctv1:订阅cctv1
psubscibe cctv*:订阅cctv*,如cctv1,cctvaaa等
publish cctv1 aaa/publish cctv1 'aaa bbb':在cctv1发送信息,能被订阅者收到

======================================================================

redis事务,使用方法和mysql基本一样,测试有效,全部成功或者全部失败,
但是如果不是java报错,而是让redis报错,比如multi.incr("a"),程序不会报错,
所以全部成功:
   @Test
   public void t7() throws SQLException {
      Jedis j = jedisPool.getResource();
      j.select(1);
      Transaction multi = j.multi();
      try {
         multi.set("a", "1");
         System.out.println(1 / 0);
         multi.set("b", "2");
         multi.exec();
      } catch (Exception e) {
         e.printStackTrace();
         multi.discard();
      }
   }

======================================================================

动态代理:newProxyInstance方法用来返回一个代理对象,这个方法总共有3个参数,
ClassLoader loader用来指明生成代理对象使用哪个类装载器,
Class<?>[] interfaces用来指明生成哪个对象的代理对象,通过接口指定,
InvocationHandler h用来指明产生的这个代理对象要做什么事情。
所以我们只需要调用newProxyInstance方法就可以得到某一个对象的代理对象了。

Class<?>[] interfaces = p.getClass().getInterfaces()表示增强p的所有接口的方法,
如果只需要增强部分接口,比如接口Person,可以写Person.getInterfaces()。
但是如果p实现了多个接口,代理类不能用p的类接收,所以似乎实现所以接口没有意义??
   public void t1() {
      final Person p = new NormalPerson();
      ClassLoader loader = p.getClass().getClassLoader();
      Class<?>[] interfaces = p.getClass().getInterfaces();
      Person n = (Person) Proxy.newProxyInstance(loader, interfaces, new InvocationHandler() {
         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if ("f".equals(method.getName())) {
               System.out.println("增强了f方法");
               return method.invoke(p, args);
            } else {
               System.out.println("增强start----->");
               Object o=method.invoke(p, args);
               System.out.println("<------增强over");
               return o;
            }
         }
      });
      n.f("111");
      n.g("222");
   }

更详细的内容见 第6章的day04_框架学习之webjava基础加强笔记.txt。

======================================================================

在filter里用动态代理解决乱码问题:
   public void doFilter(ServletRequest r, ServletResponse s, FilterChain c) throws IOException, ServletException {
      final HttpServletRequest r1 = (HttpServletRequest) r;
      HttpServletRequest r2 = r1;
      String method = r1.getMethod();
      if ("get".equalsIgnoreCase(method)) {
         r2 = (HttpServletRequest) Proxy.newProxyInstance(
               r1.getClass().getClassLoader(),
               r1.getClass().getInterfaces(),
               new InvocationHandler() {
                  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                     String name = method.getName();
                     if ("getParameter".equals(name)) {
                        String v = (String) method.invoke(r1, args);
                        return new String(v.getBytes("iso8859-1"), "utf-8");
                     } else {
                        return method.invoke(r1, args);
                     }
                  }
               });
      } else if ("post".equalsIgnoreCase(method)) {
         r2.setCharacterEncoding("utf-8");
      }
      HttpServletResponse s2 = (HttpServletResponse) s;
      s2.setContentType("text/html;charset=utf-8");
      c.doFilter(r2, s2);
   }

======================================================================

注解配置servlet,需要导入org.apache.tomcat.tomcat-servlet-api:
   @WebServlet(urlPatterns = "/fff")
   public class S7 extends HttpServlet {
      @Override
      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         resp.getWriter().write("fff");
      }
   }

======================================================================

类加载器:
把java文件加载到内存里形成class对象的过程叫做类加载,做这件事的对象就是类加载器。
类加载器的组成:
   引导类加载器(c语言的):加载rt.jar(在jre system library里看)
   应用类加载器AppClassLoad:加载自己写的类
   扩展类加载器ExtClassLoad:加载ext.jar

======================================================================

第7章:
熟悉项目:
1、熟悉这个项目有多少个模块,熟悉模块功能
2、熟悉数据库已经数据库的表
3、熟悉每一个模块功能的数据crud和哪些表有关

======================================================================

https://blog.csdn.net/qq_40693828/article/details/81005811
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能:在运行时判定任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判定任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

======================================================================

右键项目名称,web deployment assembly,add-->java build path entries,
每次在maven里update project都要重复这个操作。



商城项目笔记:
1、购物车和购物项不应该设置public getTotal,所有价格相关的都不能设置set方法!!
2、购物项用map比list更好管理,但由于购物项应该有序,所以用LinkedHashMap

======================================================================

servlet处理文件上传:

前端:
   <form enctype="multipart/form-data" method="post"  action='/d2/product?method=pic'>
      <input type='file' name='fn'/>upload
      <input type='text' name='u' value='u1'/>
      <input type='submit' value='submit'/>
   </form>
这个请求会先通过baseservlet处理,得到method(pic)后调用productservlet的pic方法,
但是enctype="multipart/form-data"的表单无法通过request.getParameter获取,
所以action=/d2/product然后用隐藏域提交method=pic会无法进入pic方法,
这里写成了/d2/product?method=pic。

后台代码(fc,upload,fileitem都来自commons-fileupload包):
public String pic(HttpServletRequest r, HttpServletResponse s) throws Exception {
      String u = r.getParameter("u");
      String fn = r.getParameter("fn");
         //始终打印null --null
      System.out.println(u + "\t--" + fn);
      DiskFileItemFactory fc = new DiskFileItemFactory();
      ServletFileUpload upload = new ServletFileUpload(fc);
      List<FileItem> list = upload.parseRequest(r);
      Map<String, List<FileItem>> map = upload.parseParameterMap(r);
         //list能获取到,map是null
      System.out.println(list);
      System.out.println(map);
      for (FileItem item : list) {
            // 文件的输出是        fn:一堆乱码       01.jpg:false
            // u=1111的输出是     u:u1111       null:true
         System.out.print(item.getFieldName() + ":" + item.getString());
         System.out.println("\t"+item.getName() + ":" + item.isFormField());
         if (!item.isFormField()) {
            File file = new File( "e:/" + item.getName());
            InputStream in = item.getInputStream();
            FileOutputStream out = new FileOutputStream(file);
            byte[] b = new byte[1024];
            int len = 0;
            while ((len = in.read(b)) != -1) {
               out.write(b, 0, len);
            }
            in.close();
            out.close();
         }
      }
      return null;
   }

======================================================================


第8章:
xml约束本地配置:
dtd:window-->preferences-->xml catalog-->add,key type选uri,
key是网络的地址,location填对应dtd文件在本地的地址,可以用file system查找。
xsd:基本同上,不过key type选Schema Location 。

======================================================================

hibernate主键生成策略:
自增的数值型,使用native(mysql用identity,orcale用sequence,native会自动选择);
varchar用uuid由hibernate生成主键,如果要自己生成就用assigned;

不使用increment的原因:hibernate找最大的的主键+1作为新主键,线程不安全。
   可用两个test debug验证。

get:调用方法时立即发送sql语句查询,找不到数据时返回null
load:延时查询,调用对应属性时再查,找不到数据时报错

======================================================================

hibernate对持久化类的要求规范:
1、提供一个无参的构造方法
2、所有属性私有化
3、提供get/set方法
4、不能用final修饰,否则延迟加载失效
5、必须有标识属性(即oid属性,设置表的主键和类的关系)

======================================================================

HQL查询:
   接收一个HQL进行查询:HQL-Hibernate Query Language Hibernate查询语言,与SQL语言语法很相似的一个语言。面向对象。
   @Test
   /** * Query接口   * HQL面向对象的查询.查询都是对象    */
   public void demo1(){
      Session session = HibernateUtils.getCurrentSession();
      Transaction transaction = session.beginTransaction();

      // 查询全部客户信息:
      /*Query query = session.createQuery("from Customer");
      List<Customer> list = query.list();

      for (Customer customer : list) {
         System.out.println(customer);
      }*/

      // 条件查询
      /*Query query = session.createQuery("from Customer where cust_name like ?");
      // 设置参数
      query.setParameter(0, "郝%");
      List<Customer> list = query.list();
      for (Customer customer : list) {
         System.out.println(customer);
      }*/

      // 分页查询:
      Query query = session.createQuery("from Customer");
      // 从哪开始的
      query.setFirstResult(3);
      // 每页显示记录数
      query.setMaxResults(3);

      List<Customer> list = query.list();
      for (Customer customer : list) {
         System.out.println(customer);
      }
      transaction.commit();
   }


QBC查询:
   QBC-Query By Criteria 条件查询。更加面向对象化查询语言。
   @Test
   /**     * QBC查询:Query By Criteria  */
   public void demo2(){
      Session session = HibernateUtils.getCurrentSession();
      Transaction transaction = session.beginTransaction();

      // 查询全部:
   /* Criteria criteria = session.createCriteria(Customer.class);
      List<Customer> list = criteria.list();
      for (Customer customer : list) {
         System.out.println(customer);
      }*/

      // 条件查询
       /**
      * ==   eq     * >   gt       * >= ge       * < lt
       * <=  le     * <>  ne       * in in       * like like        */

      /*Criteria criteria = session.createCriteria(Customer.class);
      // criteria.add(Restrictions.eq("cust_name", "郝天一"));
      criteria.add(Restrictions.like("cust_name", "郝%"));
      List<Customer> list = criteria.list();
      for (Customer customer : list) {
         System.out.println(customer);
      }*/

      // 分页查询
      Criteria criteria = session.createCriteria(Customer.class);
      criteria.setFirstResult(3);
      criteria.setMaxResults(3);
      List<Customer> list = criteria.list();
      for (Customer customer : list) {
         System.out.println(customer);
      }
      transaction.commit();
   }
详细代码见第二天讲义。
hibernate的一对多和多对多的配置和代码,见xml配置/hibernate配置的xml文件。
关联级别的延迟加载:lazy=false见customer.hbm.xml。

======================================================================

hibernate有一套orm的增删改查方法,然后出现了jpa接口,hibernate又实现了jpa,
所有hibernate有两套orm方法。

======================================================================

关于hibernate设置uuid,assigned:
uuid:hibernate管理id,自己设置了也无效;
assigned:必须自己添加id。

======================================================================

第9章:struts2
前端控制器模型思想:
很多servlet有共性的内容,比如处理乱码,上传文件,把这些部分抽取出来统一处理,
处理它们的就是前端控制器。struts2使用的是StrutsPrepareAndExecufilter,
springMVC使用的是baseServlet。

struts2在web.xml配置StrutsPrepareAndExecufilter,用它拦截访问(比如配置成/*),
然后取struts.xml里找对应的action进行处理,不再使用servlet。

======================================================================

org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter:
init方法在服务器启动时执行,只执行一次,主要作用是加载大量的配置文件;
dofilter方法:每次访问都会执行一次dofilter方法,请求转发/重定向额外执行。

======================================================================

线程危机:什么情况容易遇到线程危机?
   多个线程操作共享的数据,就容易遇到线程危机。举例:
      多人用同一个对象的成员属性(单实例),成员属性属于共享数据,有线程危机;
      多人用某对象的成员属性(多实例),每个对象有自己的成员属性,无线程危机;
   serlvet是单实例,所以几乎不在servlet定义成员属性,否则有线程危机;
   action是多实例,在action里写一个无参的构造方法,可以发现每次访问
      该action都会调用这个方法,说明是多实例。
   单实例的好处是无需创建多个实例,减少了时间和空间消耗。

======================================================================

ValueStack值栈是struts2提供的一个接口,我们用的是它的实现类OgnlValueStack,
这个由struts2创建。
在javaweb,我们使用域作为数据中转站  数据-->域-->页面(el,jstl);
在struts2,我们使用值栈作为数据中转站  数据-->值栈对象-->页面(ognl,el也可以)。

浏览器访问action时,被StrutsPrepareAndExecuteFilter拦截并创建值栈对象,
每次访问都会创建。创建后,当前action对象会放入值栈,还会将request,session,
servletContext的底层用来封装数据的map集合也放入值栈,这里放的是地址。
action执行完毕后销毁,值栈也跟着销毁,所以值栈的生命周期和action一样。

======================================================================

ognl表达式:不能在struts2中单独使用,需要嵌套进struts2内置标签中使用,
可以在jsp里获取值栈的数据,需要如下配置:
在jsp里<%@taglib prefix="s" uri="/struts-tags" %>

<s:property value="'heee'.length()"/><hr>  //4


<s:select name="parent.id" list="deptList" headerKey="fuckyou" headerValue="--请选择--" listKey="id" listValue="deptName"></s:select>
在页面上显示:
   <select name="parent.id" id="parent_id">
      <option value="fuckyou">--请选择--</option>
      <option value="40289181670ca07601670ca07e400000">测试部门</option>
      <option value="4028827c4fb6202a014fb6209c730000">总裁办</option>
      <option value="4028827c4fb633bd014fb64467470000">财务部</option>
      <option value="402891816724e769016724e78a050000">测试部门</option>
   </select>
select的id是由name生成的,deptList是put在值栈的,listKey是option的value,listValue是option的文本。

======================================================================

需要注意struts使用属性封装数据时如果用对象,该对象必须被创建实例,即下面的private Page<Dept> page = new Page<Dept>(),如果写成private Page<Dept> page会报错空指针,因为数据封装和获取需要get该对象再set属性。

   public class DeptAction extends BaseAction<Dept> implements ModelDriven<Dept> {
      @Autowired
      private DeptService ds;
      private Dept d = new Dept();
      private Page<Dept> page = new Page<Dept>();

      @Action(value = "deptAction_list")
      public String list() {
         Specification<Dept> spec = new Specification<Dept>() {
            @Override
            public Predicate toPredicate(Root<Dept> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
               return null;
            }
         };
         Pageable pageable = new PageRequest(page.getPageNo() - 1, page.getPageSize());
         org.springframework.data.domain.Page<Dept> page2 = ds.findPage(null, pageable);
         page.setResults(page2.getContent());
         page.setTotalPage(page2.getTotalPages());
         page.setTotalRecord(page2.getTotalElements());
         page.setUrl("${ctx}/sysadmin/deptAction_list");
         push(page);
         return "list";
      }

      public Page getPage() {
         return page;
      }

      public void setPage(Page page) {
         this.page = page;
      }

      @Override
      public Dept getModel() {
         return d;
      }

   }

======================================================================

获得valueStack对象的两种方法:
   public String t1() {
      ActionContext c = ActionContext.getContext();
      ValueStack vs1 = c.getValueStack();
      HttpServletRequest r = ServletActionContext.getRequest();
      Object vs2 = r.getAttribute(ActionContext.VALUE_STACK);
      System.out.println(vs1 == vs2);                //true
      return "t1t1";
   }

======================================================================

struts2处理ajax:不需要其他任何配置
   @Action(value = "roleAction_ajax")
   public String ajax() throws IOException {
      Set<Module> mm = ds.get(d.getId()).getModules();
      HttpServletResponse r = ServletActionContext.getResponse();
      String s = JSON.toJSONString(mm);
      r.setCharacterEncoding("utf-8");
      r.getWriter().write(s);
      return null;
   }

======================================================================

增强方法:具体代码在 /00-一些笔记\复习笔记\例子
1、继承
2、jdk动态代理(java.lang.reflect.Proxy)
3、cglib动态代理(org.springframework.cglib.proxy.Enhancer)
4、装饰者模式

======================================================================

接口I有方法f1、f2,类L实现了I,用代码d增强f1。
连接点:可以被增强的方法,即f1,f2
切入点:要被增强的方法,即f1
通知/增强:用来增强别人的代码,即d
切面:切入点+通知,即f1+d
织入:切入点集成到切面的过程,即实现'代码d增强f1'的过程

======================================================================

spring测试如果要加载applicationContexnt.xml,千万要使用spring整合junit测试,
手动ApplicationContext c = new ClassPathXmlApplicationContext(配置文件)的话,
注解配置的类经常会返回null。

======================================================================

spring-jdbc的crud代码见  xml配置文件\spring的配置\Jdbc代码

======================================================================

第12章:
view的作用:隐藏某些列,将复杂语句做成视图可以用很短的sql语句查询

======================================================================

preferences-->team-->ignored resources-->add pattern,加上target,
可以使svn提交时默认不提交target文件夹。

======================================================================

用js刷新页面:window.location.reload()

======================================================================

url-pattern详解     在web.xml文件中,以下语法用于定义映射: 
l. 以'/'开头和以'/*'结尾的是用来做路径映射的。 
2. 以前缀'*.'开头的是用来做扩展映射的,如*.action。 
3. '/' 是用来定义default servlet映射的。 
4. 剩下的都是用来定义详细映射的。比如: /aa/bb/cc.action 
所以,为什么定义”/admin/*.jsp”这样一个看起来很正常的匹配会错?因为这个匹配即属于路径映射,也属于扩展映射,导致容器无法判断。

======================================================================
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值