First, all Allow directives are evaluated; at least one must match, or the request is rejected. Next, all Deny directives are evaluated. If any matches, the request is rejected. Last, any requests which do not match an Allow or a Deny directive are denied by default.
1
Deny,Allow
First, all Deny directives are evaluated; if any match, the request is denied unless it also matches an Allow directive. Any requests which do not match any Allow or Deny directives are permitted.
4. DirectoryIndex
主页文件设置 一般都是 index.html index.php
5. Deny /Allow
黑白名单书写规则如下:
1 2 3 4 5
Allow from example.org Allow from .net example.edu Allow from 10.1.2.3 Allow from 192.168.1.104 192.168.1.205 Allow all
Alias /download/ "/var/www/download/" #访问时可以输入:http://www.custing.com/download/ <Directory "/var/www/download"> #对该目录进行访问控制设置 Options Indexes MultiViews AllowOverride AuthConfig Order allow,deny Allow from all </Directory>
6、CGI设置
1 2 3 4 5 6 7 8 9
# 访问时可以:http://www.clusting.com/cgi-bin/,但是该目录下的CGI脚本文件要加可执行权限 ScriptAlias /cgi-bin/ "/mnt/software/apache2/cgi-bin/" <Directory "/usr/local/apache2/cgi-bin"> #设置目录属性 AllowOverride None Options None Order allow,deny Allow from all </Directory>
8、日志的设置
(1) 错误日志的设置
ErrorLog logs/error_log :日志的保存位置
LogLevel warn #日志的级别
显示的格式日下:
1
[Mon Oct 10 15:54:29 2005] [error] [client 192.168.10.22] access to /download/ failed, reason: user admin not allowed access
# Ensure that Apache listens on port 80 Listen 80 # Listen for virtual host requests on all IP addresses NameVirtualHost *:80 <VirtualHost *:80> DocumentRoot /www/example1 ServerName www.example1.com ServerAlias example1.com. *.example1.com # Other directives here </VirtualHost> <VirtualHost *:80> DocumentRoot /www/example2 ServerName www.example2.org # Other directives here </VirtualHost>
Listen 80 # This is the "main" server running on 172.20.30.40 ServerName server.domain.com DocumentRoot /www/mainserver # This is the other address NameVirtualHost 172.20.30.50 <VirtualHost 172.20.30.50> DocumentRoot /www/example1 ServerName www.example1.com # Other directives here ... </VirtualHost> <VirtualHost 172.20.30.50> DocumentRoot /www/example2 ServerName www.example2.org # Other directives here ... </VirtualHost>
public class GOF23 { // 饿汉式 private static final List list = new ArrayList();
public static List getInstance() { return list; } }
2.懒汉式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// 懒汉式 // 使用双检锁,并且由于 jvm 指令重排序我们需要使用 volatile 关键字抑制指令重排序 public class GOF{ private static volatile List list1; public static List getInstanceLazy() { synchronized (Object.class) { if (list1 == null) { synchronized (Object.class){ list1 = new ArrayList(); return list; } }else { return list; } } } }
3.静态内部类
1 2 3 4 5 6 7 8 9 10
public class GOF{ // 静态内部类 public static class SingletonClass{ private static final List list2 = new ArrayList(); } // 首先要去加载这个静态内部类,然后这个时候会调用 cinit 方法这个是天然的线程安全的,然后返回这个对象即可 可以延时加载 public List getStaticInstance(){ return SingletonClass.list2; } }
4.枚举
1 2 3 4 5 6
public class GOF23 { // 采用枚举的方式 不能延时加载 由 jvm 底层完成的 public enum SingleInstanceEnum{ INSTANCE_ENUM } }
public class Audi implements Car { @Override public void run() { System.out.println("audi run"); } }
public class Daben implements Car { @Override public void run() { System.out.println("daben run"); } }
public class CarFactory { public static Car createCar(String type) { if (type.equals("daben")) { return new Daben(); } else if (type.equals("audi")) { return new Audi(); }else { return null; } } }
public class CarClient { public static void main(String[] args) { Daben daben = (Daben) CarFactory.createCar("daben"); daben.run(); } }
// 座椅类型 public interface Seat { public void desc(); }
class LuxurySeat implements Seat {
@Override public void desc() { System.out.println("high quality seat"); } }
class LowSeat implements Seat {
@Override public void desc() { System.out.println("low seat"); } }
// 引擎类型 public interface Engine { public void run(); }
class LuxuryEngine implements Engine {
@Override public void run() { System.out.println("high speed engine"); } }
class LowEngine implements Engine {
@Override public void run() { System.out.println("low engine"); } }
// 车的抽象工厂 public interface AbstractCarFactory { public Seat createSeat(); public Engine creaateEngine(); }
// 两个工厂的实现,分别是高级车工厂,低级车工厂 public class LuxuryCarFactory implements AbstractCarFactory { @Override public Seat createSeat() { return new LuxurySeat(); }
@Override public Engine creaateEngine() { return new LuxuryEngine(); } }
public class LowCarFactory implements AbstractCarFactory{ @Override public Seat createSeat() { return new LowSeat(); }
@Override public Engine creaateEngine() { return new LowEngine(); } }
@AllArgsConstructor public class SimpleHandler implements InvocationHandler { RealObject real; public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("heihei"); return (Object) method.invoke(real, args); } }
被代理对象
1 2 3 4 5 6 7 8 9
public interface ObjectInterface { public void hello(); }
public class RealObject implements ObjectInterface { public void hello(){ System.out.println("hello"); } }
生成代理对象的过程
1 2 3 4 5 6 7 8
public class JdkClient { public static void main(String[] args) { RealObject realObject = new RealObject(); SimpleHandler simpleHandler = new SimpleHandler(realObject); ObjectInterface proxyInstance = (ObjectInterface) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{ObjectInterface.class}, simpleHandler); proxyInstance.hello(); } }
七、桥接模式
桥接模式就是为了处理两个维度的事情,比如说我们定义一个电脑类,那么我们如果需要售卖笔记本、平板、台式机而这些东西又有不同的品牌那么我们就需要建立很多的类在电脑这个类下面。但是我们采用桥接的话我们抽出一个接口这个接口代表了品牌,然后有一个抽象类(电脑类型)包含了品牌的引用,我们只需要在不同的电脑类型下面建立各个类型,在创建一个品牌类型的电脑的时候直接 new 出来就行了。
public static void main(String[] args) { // Utility utility = new Utility(); 构造函数为私有的, System.out.println(Utility.getName());
}
13.@Cleanup
用于流等可以不需要关闭使用流对象.
1 2 3 4 5 6 7 8 9 10
@Cleanup OutputStream outStream = new FileOutputStream(new File("text.txt")); @Cleanup InputStream inStream = new FileInputStream(new File("text2.txt")); byte[] b = new byte[65536]; while (true) { int r = inStream.read(b); if (r == -1) break; outStream.write(b, 0, r); }
其实我们在任何一个 Java 应用程序中都会存在 class 对象,这个 class 对象其实就是每一个类、类型、数组、接口 等等被加载的时候在 jvm 中创建的。也就是这些类型的一个映射,这些类型在虚拟机中的实体。正是由于存在这个对象在 Jvm 中我们可以通过一定的方式获取这个对象然后去用这个对象去对我们的各种类型做一些加载获取属性等等操作,当然主要是对类进行操作并能够执行他的方法,探知未知的类的各种信息。
2.官方文档解释
这是我摘录的 Class 类的 javadoc 内容:
Instances of the class Class represent classes and interfaces in a running Java application.
An enum is a kind of class and an annotation is a kind of interface.
Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions.
The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects.
Class has no public constructor.Instead Class objects are constructed automatically by the Java Virtual Machine as classes are loaded and by calls to the defineClass method in the class loader.
其实里面主要说了这么几件事:
1.class 对象代表类和接口
这个比较好理解其实我们可以看一个例子就能明白:
1
Class clazz = Long.class;
前面是 Class 类型后面就是一个具体的变量,那么为什么我们没有 new 这个对象就能获取到呢? 其实在这里我们使用了 Long 这个类,那么这个类就会被 jvm 加载之后在 jvm 中形成了他所对应的 class 对象,我们在赋值的时候直接从 jvm 取到即可,这里我们也比较好理解这个类的对象其实在内存中只有一份,也就是单例的,这是因为没必要存在多份,他只是一个类的一个内存映射。
<selectid="getEmp"resultType="lwen.entries.Employee"> select * from employee where <iftest="id!=null"> id=#{id} </if> <iftest="name!=null"> and name=#{name} </if> </select>
但是注意的一点就是假如我们没有传入我们的 id 字段的话,我们的sql就会报错,因为拼接会出问题啊。那么出来的 sql 就会是:
1
select * from employee whereandname=#{name}
显然会报错!
解决方案1:
1 2 3 4 5 6 7 8 9 10 11 12 13
<selectid="getEmp"resultType="lwen.entries.Employee"> select * from employee where <iftest="1=1"> 1=1 </if> <iftest="id!=null"> and id=#{id} </if> <iftest="name!=null"> and name=#{name} </if> </select>
解决方案2:
2.where标签
1 2 3 4 5 6 7 8 9 10 11 12
<selectid="getEmpWhere"resultType="lwen.entries.Employee"> select * from employee <where> <iftest="id!=null"> id=#{id} </if> <iftest="name!=null"> and name=#{name} </if> </where> </select>
可以看到我们删除了 where 关键字而是加上了 where标签这样的话虽然我们不传 id 我们的 sql 也是拼装正常的,不会报错。注意的一点就是我们的 where 标签只能解决当我们的 条件前面多出来的 and 或者 or 而不能解决后面的 and 比如说我们的 sql写成了:
1 2 3 4 5 6 7 8 9 10 11 12
<selectid="getEmpWhere"resultType="lwen.entries.Employee"> select * from employee <where> <iftest="id!=null"> id=#{id} and </if> <iftest="name!=null"> name=#{name} </if> </where> </select>
如果不传 name 的话就会报错。
可以看到我们的sql 语句是这样的:
1
EmployeeDynamicMapper.getEmpWhere1 - ==> Preparing: select * from employee where id=? and ;
3.trim标签
trim标签就是可以给一个语句加上一个前缀一个后缀,删除某个前缀删除某个后缀。
prefix:加前缀
prefixOverrides:删前缀
suffix:加后缀
suffixOverrides:删后缀
1 2 3 4 5 6 7 8 9 10 11 12
<selectid="getEmpWhere1"resultType="lwen.entries.Employee"> select * from employee <trimprefix="where"suffixOverrides="and"> <iftest="id!=null"> id=#{id} and </if> <iftest="name!=null"> name=#{name} </if> </trim>; </select>
解决上述问题呢。
4.choose标签
这个标签的功能就类似于带有 break 的 switch-case 语句,就是只会进入一个分支。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
<selectid="getEmpWhere2"resultType="lwen.entries.Employee"> select * from employee <where> <choose> <whentest="id!=null"> id=#{id} </when> <whentest="name!=null"> name like #{name} </when> <otherwise> age=1 </otherwise> </choose> </where> </select>
同样的既然我们上面可以使用 trim 做一个通用的查询,那我们肯定可以使用 trim 做一个更通用的更新
6.foreach标签
1 2 3 4 5 6 7
<selectid="getEmpIn"resultType="lwen.entries.Employee"> select * from employee where id in <foreachcollection="ids"item="id"separator=","open="("close=")"index="index"> #{id} </foreach> </select>
主要用于 in 这种枚举类型的。自然的我们也是可以批量保存的 就是采用这种方式,也就是 values 的位置数据很多。
<mappernamespace="lwen.dao.EmployeeMapper"> <selectid="selectOneEmployee"resultType="lwen.entries.Employee"> select * from employee where id=#{id} </select>
// get names from @Param annotations for (int paramIndex = 0; paramIndex < paramCount; paramIndex++) { if (isSpecialParameter(paramTypes[paramIndex])) { // skip special parameters continue; } String name = null; for (Annotation annotation : paramAnnotations[paramIndex]) { if (annotation instanceof Param) { hasParamAnnotation = true; name = ((Param) annotation).value(); break; } } if (name == null) { // @Param was not specified. if (config.isUseActualParamName()) { name = getActualParamName(method, paramIndex); } if (name == null) { // use the parameter index as the name ("0", "1", ...) // gcode issue #71 name = String.valueOf(map.size()); } } map.put(paramIndex, name); }
<selectid="getEmplByResultMap"resultMap="MyEmp"> select * from employee where id = #{id}; </select>
可以看到重点就是写我们的 resultMap 标签,然后再标签中我们自己封装规则。注意的一点就是如果说我们在 result 中没有封装 bean 中的其他属性他会自动帮我们封装,也就是我们可以把一些特殊的字段和我们的 bean 结合起来。其他的正常的自动封装。然后就是 id 字段我们在 resultMap 中指明以后Mybatis就会帮我们自动封装,并且做一些查询优化。
5.关联查询
1.union
1 2 3 4
<selectid="getById"resultMap="EmpNew"> select employee.id id,employee.name name,age,d_id did,department.name dname from employee,department where employee.id=#{id} and employee.d_id=department.id; </select>
我们采用的联合查询,得到了关联查询的结果,这也是常用的套路,但是注意的一点就是我们的 result 的封装并不是使用的自带的封装规则而是采用了 我们自定义的 resultMap 因为我们的 employee 中有一个 department 的对象,我们无法直接封装,至少列名都没办法对应。
<selectid="getByIdAssociation"resultMap="EmpNew1"> select employee.id id,employee.name name,age,d_id did,department.name dname from employee,department where employee.id=#{id} and employee.d_id=department.id; </select>
3.association多步查询
当我们需要 department 的 id 然后作为我们封装 Employee 的条件的时候我们就需要用 id 查询这个 Department