public class SimplePizzaFactory {
public Pizza CreatePizza(String ordertype) {
Pizza pizza = null;
if (ordertype.equals("cheese")) {
pizza = new CheesePizza();
} else if (ordertype.equals("greek")) {
pizza = new GreekPizza();
} else if (ordertype.equals("pepper")) {
pizza = new PepperPizza();
}
return pizza;
}
}
public class PreloadSingleton {
public static PreloadSingleton instance = new PreloadSingleton();
//其他的类无法实例化单例类的对象
private PreloadSingleton() {
};
public static PreloadSingleton getInstance() {
return instance;
}
}
很明显,没有使用该单例对象,该对象就被加载到了内存,会造成内存的浪费。
2.2 懒加载
为了避免内存的浪费,我们可以采用懒加载,即用到该单例对象的时候再创建。
public class Singleton {
private static Singleton instance=null;
private Singleton(){
};
public static Singleton getInstance()
{
if(instance==null)
{
instance=new Singleton();
}
return instance;
}
}
public abstract class ComputerBuilder {
protected Computer computer;
public Computer getComputer() {
return computer;
}
public void buildComputer() {
computer = new Computer();
System.out.println("生成了一台电脑!!!");
}
public abstract void buildMaster();
public abstract void buildScreen();
public abstract void buildKeyboard();
public abstract void buildMouse();
public abstract void buildAudio();
}
HPComputerBuilder定义各个组件:
public class HPComputerBuilder extends ComputerBuilder {
@Override
public void buildMaster() {
// TODO Auto-generated method stub
computer.setMaster("i7,16g,512SSD,1060");
System.out.println("(i7,16g,512SSD,1060)的惠普主机");
}
@Override
public void buildScreen() {
// TODO Auto-generated method stub
computer.setScreen("1080p");
System.out.println("(1080p)的惠普显示屏");
}
@Override
public void buildKeyboard() {
// TODO Auto-generated method stub
computer.setKeyboard("cherry 青轴机械键盘");
System.out.println("(cherry 青轴机械键盘)的键盘");
}
@Override
public void buildMouse() {
// TODO Auto-generated method stub
computer.setMouse("MI 鼠标");
System.out.println("(MI 鼠标)的鼠标");
}
@Override
public void buildAudio() {
// TODO Auto-generated method stub
computer.setAudio("飞利浦 音响");
System.out.println("(飞利浦 音响)的音响");
}
}
Director类对组件进行组装并生成产品
public class Director {
private ComputerBuilder computerBuilder;
public void setComputerBuilder(ComputerBuilder computerBuilder) {
this.computerBuilder = computerBuilder;
}
public Computer getComputer() {
return computerBuilder.getComputer();
}
public void constructComputer() {
computerBuilder.buildComputer();
computerBuilder.buildMaster();
computerBuilder.buildScreen();
computerBuilder.buildKeyboard();
computerBuilder.buildMouse();
computerBuilder.buildAudio();
}
}
public static void main(String[] args) {
int i = 0;
int MAX_COUNT = 10;
EventTemplate et = new EventTemplate("9月份信用卡账单", "国庆抽奖活动...");
long start = System.currentTimeMillis();
while (i < MAX_COUNT) {
// 以下是每封邮件不同的地方
Mail mail = new Mail(et);
mail.setContent(getRandString(5) + ",先生(女士):你的信用卡账单..." + mail.getTail());
mail.setReceiver(getRandString(5) + "@" + getRandString(8) + ".com");
// 然后发送邮件
sendMail(mail);
i++;
}
long end = System.currentTimeMillis();
System.out.println("用时:" + (end - start));
}
用时:10001
使用clone,发送十个邮件
public static void main(String[] args) {
int i = 0;
int MAX_COUNT = 10;
EventTemplate et = new EventTemplate("9月份信用卡账单", "国庆抽奖活动...");
long start=System.currentTimeMillis();
Mail mail = new Mail(et);
while (i < MAX_COUNT) {
Mail cloneMail = mail.clone();
mail.setContent(getRandString(5) + ",先生(女士):你的信用卡账单..."
+ mail.getTail());
mail.setReceiver(getRandString(5) + "@" + getRandString(8) + ".com");
sendMail(cloneMail);
i++;
}
long end=System.currentTimeMillis();
System.out.println("用时:"+(end-start));
}
public class AdapterUSB2VGA extends USBImpl implements VGA {
@Override
public void projection() {
super.showPPT();
}
}
Projector将USB映射为VGA,只有VGA接口才可以连接上投影仪进行投影
public class Projector<T> {
public void projection(T t) {
if (t instanceof VGA) {
System.out.println("开始投影");
VGA v = new VGAImpl();
v = (VGA) t;
v.projection();
} else {
System.out.println("接口不匹配,无法投影");
}
}
}
public abstract class AdapterUSB2VGA implements VGA {
USB u = new USBImpl();
@Override
public void projection() {
u.showPPT();
}
@Override
public void b() {
};
@Override
public void c() {
};
}
AdapterUSB2VGA实现,不用去实现b()和c()方法。
public class AdapterUSB2VGAImpl extends AdapterUSB2VGA {
public void projection() {
super.projection();
}
}
public class Decorator extends Drink {
private Drink Obj;
public Decorator(Drink Obj) {
this.Obj = Obj;
};
@Override
public float cost() {
// TODO Auto-generated method stub
return super.getPrice() + Obj.cost();
}
@Override
public String getDescription() {
return super.description + "-" + super.getPrice() + "&&" + Obj.getDescription();
}
}
装饰者实例化(加牛奶)。这里面要对被修饰的对象进行实例化。
public class Milk extends Decorator {
public Milk(Drink Obj) {
super(Obj);
// TODO Auto-generated constructor stub
super.setDescription("Milk");
super.setPrice(2.0f);
}
}
public class CoffeeBar {
public static void main(String[] args) {
Drink order;
order = new Decaf();
System.out.println("order1 price:" + order.cost());
System.out.println("order1 desc:" + order.getDescription());
System.out.println("****************");
order = new LongBlack();
order = new Milk(order);
order = new Chocolate(order);
order = new Chocolate(order);
System.out.println("order2 price:" + order.cost());
System.out.println("order2 desc:" + order.getDescription());
}
}
public class DynamicProxyHandler implements InvocationHandler {
private Object object;
public DynamicProxyHandler(final Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("买房前准备");
Object result = method.invoke(object, args);
System.out.println("买房后装修");
return result;
}
}
第二步:编写测试类
public class DynamicProxyTest {
public static void main(String[] args) {
BuyHouse buyHouse = new BuyHouseImpl();
BuyHouse proxyBuyHouse = (BuyHouse) Proxy.newProxyInstance(BuyHouse.class.getClassLoader(), new
Class[]{BuyHouse.class}, new DynamicProxyHandler(buyHouse));
proxyBuyHouse.buyHosue();
}
}
public class CPU {
public void start() {
System.out.println("cpu is start...");
}
public void shutDown() {
System.out.println("CPU is shutDown...");
}
}
public class Disk {
public void start() {
System.out.println("Disk is start...");
}
public void shutDown() {
System.out.println("Disk is shutDown...");
}
}
public class Memory {
public void start() {
System.out.println("Memory is start...");
}
public void shutDown() {
System.out.println("Memory is shutDown...");
}
}
然后是,门面类Facade
public class Computer {
private CPU cpu;
private Memory memory;
private Disk disk;
public Computer() {
cpu = new CPU();
memory = new Memory();
disk = new Disk();
}
public void start() {
System.out.println("Computer start begin");
cpu.start();
disk.start();
memory.start();
System.out.println("Computer start end");
}
public void shutDown() {
System.out.println("Computer shutDown begin");
cpu.shutDown();
disk.shutDown();
memory.shutDown();
System.out.println("Computer shutDown end...");
}
}
最后为,客户角色
public class Client {
public static void main(String[] args) {
Computer computer = new Computer();
computer.start();
System.out.println("=================");
computer.shutDown();
}
}
public interface Software {
public void run();
}
public class AppStore implements Software {
@Override
public void run() {
System.out.println("run app store");
}
}
public class Camera implements Software {
@Override
public void run() {
System.out.println("run camera");
}
}
抽象:
public abstract class Phone {
protected Software software;
public void setSoftware(Software software) {
this.software = software;
}
public abstract void run();
}
public class Oppo extends Phone {
@Override
public void run() {
Coming Soon();
}
}
public class Vivo extends Phone {
@Override
public void run() {
Coming Soon();
}
}
public interface Component {
public void add(Component c);
public void remove(Component c);
public Component getChild(int i);
public void operation();
}
2 叶子
public class Leaf implements Component{
private String name;
public Leaf(String name) {
this.name = name;
}
@Override
public void add(Component c) {}
@Override
public void remove(Component c) {}
@Override
public Component getChild(int i) {
// TODO Auto-generated method stub
return null;
}
@Override
public void operation() {
// TODO Auto-generated method stub
System.out.println("树叶"+name+":被访问!");
}
}
3 树枝
public class Composite implements Component {
private ArrayList<Component> children = new ArrayList<Component>();
public void add(Component c) {
children.add(c);
}
public void remove(Component c) {
children.remove(c);
}
public Component getChild(int i) {
return children.get(i);
}
public void operation() {
for (Object obj : children) {
((Component) obj).operation();
}
}
}
public interface Strategy {
public int calc(int num1,int num2);
}
2、定义具体策略角色
public class AddStrategy implements Strategy {
@Override
public int calc(int num1, int num2) {
// TODO Auto-generated method stub
return num1 + num2;
}
}
public class SubstractStrategy implements Strategy {
@Override
public int calc(int num1, int num2) {
// TODO Auto-generated method stub
return num1 - num2;
}
}
3、环境角色
public class Environment {
private Strategy strategy;
public Environment(Strategy strategy) {
this.strategy = strategy;
}
public int calculate(int a, int b) {
return strategy.calc(a, b);
}
}
4、测试
public class MainTest {
public static void main(String[] args) {
Environment environment=new Environment(new AddStrategy());
int result=environment.calculate(20, 5);
System.out.println(result);
Environment environment1=new Environment(new SubstractStrategy());
int result1=environment1.calculate(20, 5);
System.out.println(result1);
}
}
public abstract class Dish {
/**
* 具体的整个过程
*/
protected void dodish(){
this.preparation();
this.doing();
this.carriedDishes();
}
/**
* 备料
*/
public abstract void preparation();
/**
* 做菜
*/
public abstract void doing();
/**
* 上菜
*/
public abstract void carriedDishes ();
}
b. 下来做两个番茄炒蛋(EggsWithTomato)和红烧肉(Bouilli)实现父类中的抽象方法
public class EggsWithTomato extends Dish {
@Override
public void preparation() {
System.out.println("洗并切西红柿,打鸡蛋。");
}
@Override
public void doing() {
System.out.println("鸡蛋倒入锅里,然后倒入西红柿一起炒。");
}
@Override
public void carriedDishes() {
System.out.println("将炒好的西红寺鸡蛋装入碟子里,端给客人吃。");
}
}
public class Bouilli extends Dish{
@Override
public void preparation() {
System.out.println("切猪肉和土豆。");
}
@Override
public void doing() {
System.out.println("将切好的猪肉倒入锅中炒一会然后倒入土豆连炒带炖。");
}
@Override
public void carriedDishes() {
System.out.println("将做好的红烧肉盛进碗里端给客人吃。");
}
}
c. 在测试类中我们来做菜:
public class MainTest {
public static void main(String[] args) {
Dish eggsWithTomato = new EggsWithTomato();
eggsWithTomato.dodish();
System.out.println("-----------------------------");
Dish bouilli = new Bouilli();
bouilli.dodish();
}
}
public class WechatServer implements Subject {
private List<Observer> list;
private String message;
public WechatServer() {
list = new ArrayList<Observer>();
}
@Override
public void registerObserver(Observer o) {
// TODO Auto-generated method stub
list.add(o);
}
@Override
public void removeObserver(Observer o) {
// TODO Auto-generated method stub
if (!list.isEmpty()) {
list.remove(o);
}
}
@Override
public void notifyObserver() {
// TODO Auto-generated method stub
for (Observer o : list) {
o.update(message);
}
}
public void setInfomation(String s) {
this.message = s;
System.out.println("微信服务更新消息: " + s);
// 消息更新,通知所有观察者
notifyObserver();
}
}
4、定义具体观察者,微信公众号的具体观察者为用户User
public class User implements Observer {
private String name;
private String message;
public User(String name) {
this.name = name;
}
@Override
public void update(String message) {
this.message = message;
read();
}
public void read() {
System.out.println(name + " 收到推送消息: " + message);
}
}
5、编写一个测试类
public class MainTest {
public static void main(String[] args) {
WechatServer server = new WechatServer();
Observer userZhang = new User("ZhangSan");
Observer userLi = new User("LiSi");
Observer userWang = new User("WangWu");
server.registerObserver(userZhang);
server.registerObserver(userLi);
server.registerObserver(userWang);
server.setInfomation("PHP是世界上最好用的语言!");
System.out.println("----------------------------------------------");
server.removeObserver(userZhang);
server.setInfomation("JAVA是世界上最好用的语言!");
}
}
public abstract class Approver {
Approver successor;
String Name;
public Approver(String Name)
{
this.Name=Name;
}
public abstract void ProcessRequest( PurchaseRequest request);
public void SetSuccessor(Approver successor) {
// TODO Auto-generated method stub
this.successor=successor;
}
}
2 客户端以及请求
public class PurchaseRequest {
private int Type = 0;
private int Number = 0;
private float Price = 0;
private int ID = 0;
public PurchaseRequest(int Type, int Number, float Price) {
this.Type = Type;
this.Number = Number;
this.Price = Price;
}
public int GetType() {
return Type;
}
public float GetSum() {
return Number * Price;
}
public int GetID() {
return (int) (Math.random() * 1000);
}
}
public class Client {
public Client() {
}
public PurchaseRequest sendRequst(int Type, int Number, float Price) {
return new PurchaseRequest(Type, Number, Price);
}
}
3 组长、部长。。。继承决策者抽象类
public class GroupApprover extends Approver {
public GroupApprover(String Name) {
super(Name + " GroupLeader");
// TODO Auto-generated constructor stub
}
@Override
public void ProcessRequest(PurchaseRequest request) {
// TODO Auto-generated method stub
if (request.GetSum() < 5000) {
System.out.println("**This request " + request.GetID() + " will be handled by " + this.Name + " **");
} else {
successor.ProcessRequest(request);
}
}
}
public class DepartmentApprover extends Approver {
public DepartmentApprover(String Name) {
super(Name + " DepartmentLeader");
}
@Override
public void ProcessRequest(PurchaseRequest request) {
// TODO Auto-generated method stub
if ((5000 <= request.GetSum()) && (request.GetSum() < 10000)) {
System.out.println("**This request " + request.GetID()
+ " will be handled by " + this.Name + " **");
} else {
successor.ProcessRequest(request);
}
}
}
4测试
public class MainTest {
public static void main(String[] args) {
Client mClient = new Client();
Approver GroupLeader = new GroupApprover("Tom");
Approver DepartmentLeader = new DepartmentApprover("Jerry");
Approver VicePresident = new VicePresidentApprover("Kate");
Approver President = new PresidentApprover("Bush");
GroupLeader.SetSuccessor(VicePresident);
DepartmentLeader.SetSuccessor(President);
VicePresident.SetSuccessor(DepartmentLeader);
President.SetSuccessor(GroupLeader);
GroupLeader.ProcessRequest(mClient.sendRequst(1, 10000, 40));
}
}
public interface Command {
public void excute();
public void undo();
}
2 具体命令对象
public class TurnOffLight implements Command {
private Light light;
public TurnOffLight(Light light) {
this.light = light;
}
@Override
public void excute() {
// TODO Auto-generated method stub
light.Off();
}
@Override
public void undo() {
// TODO Auto-generated method stub
light.On();
}
}
3 实现者
public class Light {
String loc = "";
public Light(String loc) {
this.loc = loc;
}
public void On() {
System.out.println(loc + " On");
}
public void Off() {
System.out.println(loc + " Off");
}
}
4 请求者
public class Contral{
public void CommandExcute(Command command) {
// TODO Auto-generated method stub
command.excute();
}
public void CommandUndo(Command command) {
// TODO Auto-generated method stub
command.undo();
}
}
public interface State {
public void stop();
public void move();
}
2 状态实例
public class PlaceA implements State {
private Player context;
public PlaceA(Player context) {
this.context = context;
}
@Override
public void move() {
System.out.println("处于地点A,开始向B移动");
System.out.println("--------");
context.setDirection("AB");
context.setState(context.onMove);
}
@Override
public void stop() {
// TODO Auto-generated method stub
System.out.println("正处在地点A,不用停止移动");
System.out.println("--------");
}
}
3 context(player)拥有状态的对象
public class Player {
State placeA;
State placeB;
State onMove;
private State state;
private String direction;
public Player() {
direction = "AB";
placeA = new PlaceA(this);
placeB = new PlaceB(this);
onMove = new OnMove(this);
this.state = placeA;
}
public void move() {
System.out.println("指令:开始移动");
state.move();
}
public void stop() {
System.out.println("指令:停止移动");
state.stop();
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public void setDirection(String direction) {
this.direction = direction;
}
public String getDirection() {
return direction;
}
}
INSERT INTO ProductCopy (product_id, product_name, product_type,sale_price, purchase_price, regist_date)
SELECT product_id, product_name, product_type, sale_price, purchase_price, regist_date
FROM Product;
INSERT 语句中的SELECT 语句,也可以使用WHERE 子句或者GROUP BY 子句等。
INSERT INTO ProductType (product_type, sum_sale_price, sum_purchase_price)
SELECT product_type, SUM(sale_price), SUM(purchase_price)
FROM Product
GROUP BY product_type;
2、从表中查询出需要的列(SELECT)
SELECT product_id, product_name, purchase_price
FROM Product;
查询出所有的列
SELECT *
FROM Product;
为列设定别名(AS)
SELECT product_id AS id,
product_name AS name,
purchase_price AS “价格”
FROM Product;
将查询出的一列指定为常数
SELECT ‘2009-02-24’ AS date, product_id, product_name
FROM Product;
从查询结果中删除重复行(DISTINCT)
SELECT DISTINCT product_type
FROM Product;
3、指定查询的条件(WHERE)
SELECT product_name, product_type
FROM Product;
WHERE product_type = '衣服';
4、算数运算符和比较运算符
算数运算符
加 +
减 –
乘 *
除 /
注意:所有包含NULL 的计算,结果肯定是NULL。
SELECT product_name, sale_price, sale_price * 2 AS "sale_price_x2"
FROM Product;
比较运算符
等于 =
不等于 <>
大于 >
大于等于 >=
小于 <
小于等于 <=
SELECT product_name, product_type, regist_date
FROM Product
WHERE regist_date < '2009-09-27';
将算数运算符和比较运算符结合使用:
SELECT product_name, sale_price, purchase_price
FROM Product
WHERE sale_price - purchase_price >= 500;
注意:不能对NULL使用比较运算符,正确的方法是:
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price IS NULL;
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price IS NOT NULL;
5、逻辑运算符(NOT、AND、OR)
NOT
SELECT product_name, product_type, sale_price
FROM Product
WHERE NOT sale_price >= 1000;
(也就是sale_price<1000)
AND
AND运算符在其两侧的查询条件都成立时整个查询条件才成立,其意思相当于“并且”。
SELECT product_name, purchase_price
FROM Product
WHERE product_type = '厨房用具'
AND sale_price >= 3000;
OR
运算符在其两侧的查询条件有一个成立时整个查询条件都成立,其意思相当于“或者”。
SELECT product_name, purchase_price
FROM Product
WHERE product_type = '厨房用具'
OR sale_price >= 3000;
6、对表进行聚合查询
常用的五个聚合函数:
COUNT: 计算表中的记录数(行数)
SUM: 计算表中数值列中数据的合计值
AVG: 计算表中数值列中数据的平均值
MAX: 求出表中任意列中数据的最大值
MIN: 求出表中任意列中数据的最小值
计算全部数据的行数(包含NULL)
SELECT COUNT(*)
FROM Product;
计算某一列的行数(不包含NULL)
SELECT COUNT(purchase_price)
FROM Product;
计算删除重复数据后的行数
SELECT COUNT(DISTINCT product_type)
FROM Product;
(所有的聚合函数都可以使用DISTINCT)
SUM/AVG函数只能对数值类型的列使用,而MAX/MIN函数原则上可以适用于任何数据类型的列
SELECT MAX(regist_date), MIN(regist_date)
FROM Product;
7、对表进行分组(GROUP BY)
SELECT product_type, COUNT(*)
FROM Product
GROUP BY product_type;
GROUP BY和WHERE并用时SELECT语句的执行顺序:
FROM → WHERE → GROUP BY → SELECT
SELECT purchase_price, COUNT(*)
FROM Product
WHERE product_type = '衣服'
GROUP BY purchase_price;
为聚合结果指定条件(HAVING)
SELECT product_type, COUNT(*)
FROM Product
GROUP BY product_type
HAVING COUNT(*) = 2;
8、对查询结果进行排序(ORDER BY)
子句的书写顺序
SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY
子句的执行顺序:
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
SELECT product_id, product_name, sale_price, purchase_price
FROM Product
ORDER BY sale_price;
升序(ASC)或降序(DESC)
SELECT product_id, product_name, sale_price, purchase_price
FROM Product
ORDER BY sale_price DESC;
注意:默认升序
9、数据的删除(DELETE)
清空表
DELETE FROM Product;
指定删除对象(搜索型DELETE)
DELETE FROM Product
WHERE sale_price >= 4000;
10、数据的更新(UPDATE)
更新整列
UPDATE Product
SET regist_date = '2009-10-10';
指定条件的更新(搜索型UPDATE)
UPDATE Product
SET sale_price = sale_price * 10
WHERE product_type = '厨房用具';
多列更新
UPDATE Product
SET sale_price = sale_price * 10,
purchase_price = purchase_price / 2
WHERE product_type = '厨房用具';
11、视图
创建视图(CREATE VIEW)
CREATE VIEW ProductSum (product_type, cnt_product)
AS
SELECT product_type, COUNT(*)
FROM Product
GROUP BY product_type;
注意:定义视图时不能使用ORDER BY子句
使用视图
SELECT product_type, cnt_product
FROM ProductSum;
删除视图(DROP VIEW)
DROP VIEW ProductSum;
12、子查询(一次性视图)
-- 在FROM子句中直接书写定义视图的SELECT语句
SELECT product_type, cnt_product
FROM ( SELECT product_type, COUNT(*) AS cnt_product
FROM Product
GROUP BY product_type ) AS ProductSum;
标量子查询
在WHERE子句中使用标量子查询
SELECT product_id, product_name, sale_price
FROM Product
WHERE sale_price > (SELECT AVG(sale_price)
FROM Product);
注意:能够使用常数或者列名的地方,无论是SELECT 子句、GROUP BY 子句、HAVING 子句,还是ORDER BY 子句,几乎所有的地方都可以使用标量子查询。
关联子查询
SELECT product_type, product_name, sale_price
FROM Product AS P1
WHERE sale_price > (SELECT AVG(sale_price)
FROM Product AS P2
WHERE P1.product_type = P2.product_type
GROUP BY product_type);
SELECT *
FROM SampleLike
WHERE strcol LIKE 'ddd%';
也可用_(下划线)代替%,但_只能代表一个字符
SELECT *
FROM SampleLike
WHERE strcol LIKE 'abc_';
中间一致查询:
SELECT *
FROM SampleLike
WHERE strcol LIKE '%ddd%';
后方一致查询:
SELECT *
FROM SampleLike
WHERE strcol LIKE '%ddd';
BETWEEN谓词
SELECT product_name, sale_price
FROM Product
WHERE sale_price BETWEEN 100 AND 1000;
BETWEEN 的特点就是结果中会包含100 和1000 这两个临界值。
IS NULL和IS NOT NULL谓词
为了选取出某些值为NULL 的列的数据,不能使用=,而只能使用特定的谓词IS NULL
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price IS NULL;
IN谓词
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price IN (320, 500, 5000);
也可以用NOT IN
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price NOT IN (320, 500, 5000);
注意:在使用IN 和NOT IN 时是无法选取出NULL 数据的。
使用子查询作为IN谓词的参数:
SELECT product_name, sale_price
FROM Product
WHERE product_id IN (SELECT product_id
FROM ShopProduct
WHERE shop_id = '000C');
EXIST谓词
SELECT product_name, sale_price
FROM Product AS P
WHERE EXISTS (SELECT *
FROM ShopProduct AS SP
WHERE SP.shop_id = '000C'
AND SP.product_id = P.product_id);
也可以用NOT EXIST
15、CASE表达式
SELECT product_name,
CASE WHEN product_type = '衣服'
THEN CONCAT('A:', product_type)
WHEN product_type = '办公用品'
THEN CONCAT('B:', product_type)
WHEN product_type = '厨房用具'
THEN CONCAT('C:',product_type)
ELSE NULL
END AS abc_product_type
FROM Product;
16、表的加减法
表的加法(UNION)
SELECT product_id, product_name
FROM Product
UNION
SELECT product_id, product_name
FROM Product2;
通过UNION 进行并集运算时可以使用任何形式的SELECT 语句,WHERE、GROUP BY、HAVING 等子句都可以使用,但是ORDER BY 只能在最后使用一次。
注意:UNION会删去两个表中的重复记录。如果想保留重复记录,可以在UNION后面加ALL
选取表中的公共部分(INTERSECT)
MySQL不支持INTERSECT
表的减法(EXCEPT)
MySQL不支持EXCEPT
17、以列为单位对表进行联结(JOIN)
内联结(INNER JOIN)
SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name, P.sale_price
FROM ShopProduct AS SP INNER JOIN Product AS P
ON SP.product_id = P.product_id;
像这样使用联结运算将满足相同规则的表联结起来时,WHERE、GROUP BY、HAVING、ORDER BY 等工具都可以正常使用.
外联结(OUTER JOIN)
SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name, P.sale_price
FROM ShopProduct AS SP LEFT OUTER JOIN Product AS P ①
ON SP.product_id = P.product_id;
三张以上的表的联结
SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name, P.sale_price, IP.inventory_quantity
FROM ShopProduct AS SP INNER JOIN Product AS P ①
ON SP.product_id = P.product_id
INNER JOIN InventoryProduct AS IP ②
ON SP.product_id = IP.product_id
WHERE IP.inventory_id = 'P001';
Ⅲ. DCL(Data Control Language,数据控制语言)
1、创建事务(START TRANSACTION) – 提交处理(COMMIT)
START TRANSACTION;
-- 将运动T恤的销售单价降低1000日元
UPDATE Product
SET sale_price = sale_price - 1000
WHERE product_name = '运动T恤';
-- 将T恤衫的销售单价上浮1000日元
UPDATE Product
SET sale_price = sale_price + 1000
WHERE product_name = 'T恤衫';
COMMIT;
2、取消处理(ROLLBACK)
START TRANSACTION;
-- 将运动T恤的销售单价降低1000日元
UPDATE Product
SET sale_price = sale_price - 1000
WHERE product_name = '运动T恤';
-- 将T恤衫的销售单价上浮1000日元
UPDATE Product
SET sale_price = sale_price + 1000
WHERE product_name = 'T恤衫';
ROLLBACK;
以下是一个事务的例子, 它先以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令:
redis 127.0.0.1:6379> MULTI
OK
redis 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days"
QUEUED
redis 127.0.0.1:6379> GET book-name
QUEUED
redis 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series"
QUEUED
redis 127.0.0.1:6379> SMEMBERS tag
QUEUED
redis 127.0.0.1:6379> EXEC
1) OK
2) "Mastering C++ in 21 days"
3) (integer) 3
4) 1) "Mastering Series"
2) "C++"
3) "Programming"
“这是官网上的说明 From redis docs on transactions: It’s important to note that even when a command fails, all the other commands in the queue are processed – Redis will not stop the processing of commands.
比如:
redis 127.0.0.1:7000> multi
OK
redis 127.0.0.1:7000> set a aaa
QUEUED
redis 127.0.0.1:7000> set b bbb
QUEUED
redis 127.0.0.1:7000> set c ccc
QUEUED
redis 127.0.0.1:7000> exec
1) OK
2) OK
3) OK
Spring 框架是什么? Spring 是于 2003 年兴起的一个轻量级的Java 开发框架,它是为了解决企业应用开发的复杂性而创建的。Spring 的核心是控制反转(IoC)和面向切面编程(AOP)。Spring 是可以在Java SE/EE 中使用的轻量级开源框架。 Spring 的主要作用就是为代码“解耦”,降低代码间的耦合度。就是让对象和对象(模块和模块)之间关系不是使用代码关联,而是通过配置来说明。即在 Spring 中说明对象(模块)的关系。 Spring 根据代码的功能特点,使用Ioc 降低业务对象之间耦合度。IoC 使得主业务在相互调用过程中,不用再自己维护关系了,即不用再自己创建要使用的对象了。而是由 Spring 容器统一管理,自动“注入”,注入即赋值。 而AOP 使得系统级服务得到了最大复用,且不用再由程序员手工将系统级服务“混杂”到主业务逻辑中了,而是由 Spring 容器统一完成“织入”。 官网:https://spring.io/ Spring的优点? Spring 是一个框架,是一个半成品的软件。有 20 个模块组成。它是一个容器管理对象,容器是装东西的,Spring 容器不装文本,数字。装的是对象。Spring 是存储对象的容器。 (1) 轻量 Spring 框架使用的jar 都比较小,一般在 1M 以下或者几百 kb。Spring 核心功能的所需的jar 总共在 3M 左右。 Spring 框架运行占用的资源少,运行效率高。不依赖其他jar (2) 针对接口编程,解耦合 Spring 提供了Ioc 控制反转,由容器管理对象,对象的依赖关系。原来在程序代码中的对象创建方式,现在由容器完成。对象之间的依赖解耦合。 (3) AOP 编程的支持 通过 Spring 提供的 AOP 功能,方便进行面向切面的编程,许多不容易用传统OOP 实现的功能可以通过AOP 轻松应付在 Spring 中,开发人员可以从繁杂的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。 (4) 方便集成各种优秀框架 Spring 不排斥各种优秀的开源框架,相反 Spring 可以降低各种框架的使用难度,Spring 提供了对各种优秀框架(如Struts,Hibernate、MyBatis)等的直接支持。简化框架的使用。 Spring 像插线板一样,其他框架是插头,可以容易的组合到一起。需要使用哪个框架,就把这个插头放入插线板。不需要可以轻易的移除。 Spring 体系结构
Spring 由 20 多个模块组成,它们可以分为数据访问/集成(Data Access/Integration)、Web、面向切面编程(AOP, Aspects)、提供JVM 的代理(Instrumentation)、消息发送(Messaging)、核心容器(Core Container)和测试(Test)。 IoC 控制反转 控制反转(IoC,Inversion of Control),是一个概念,是一种思想。指将传统上由程序代码直接操控的对象调用权交给容器,通过容器来实现对象的装配和管理。控制反转就是对对象控制权的转移,从程序代码本身反转到了外部容器。通过容器实现对象的创建,属性赋值,依赖的管理。 IoC 是一个概念,是一种思想,其实现方式多种多样。当前比较流行的实现方式是依赖注入。应用广泛。 依赖:classA 类中含有classB 的实例,在 classA 中调用classB 的方法完成功能,即 classA 对 classB 有依赖。 Ioc 的实现: 依赖注入:DI(Dependency Injection),程序代码不做定位查询,这些工作由容器自行完成。 依赖注入 DI 是指程序运行过程中,若需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部容器,由外部容器创建后传递给程序。 Spring 的依赖注入对调用者与被调用者几乎没有任何要求,完全支持对象之间依赖关系的管理。 Spring 框架使用依赖注入(DI)实现IoC。 Spring 容器是一个超级大工厂,负责创建、管理所有的Java 对象,这些Java 对象被称为Bean。Spring 容器管理着容器中Bean 之间的依赖关系, Spring 使用“依赖注入”的方式来管理Bean 之间的依赖关系。使用IoC 实现对象之间的解耦和。 开发工具准备 开发工具:idea2017 以上依赖管理:maven3 以上jdk:1.8 以上 需要设置maven 本机仓库:
Spring 的第一个程序 举例:01-primay 创建maven 项目
引入maven 依赖 pom.xml
定义接口与实体类
创建Spring 配置文件 在src/main/resources/目录现创建一个xml 文件,文件名可以随意,但Spring 建议的名称为applicationContext.xml。 spring 配置中需要加入约束文件才能正常使用,约束文件是 xsd 扩展名。
<bean />:用于定义一个实例对象。一个实例对应一个bean 元素。
id:该属性是 Bean 实例的唯一标识,程序通过 id 属性访问Bean,Bean与Bean 间的依赖关系也是通过 id 属性关联的。
基于 XML 的 DI 举例:项目di-xml 注入分类 bean 实例在调用无参构造器创建对象后,就要对bean 对象的属性进行初始化。初始化是由容器自动完成的,称为注入。 根据注入方式的不同,常用的有两类:set 注入、构造注入。 (1) set 注入(掌握) set 注入也叫设值注入是指,通过setter 方法传入被调用者的实例。这种注入方式简单、直观,因而在 Spring 的依赖注入中大量使用。 A、 简单类型
创建java.util.Date 并设置初始的日期时间: Spring 配置文件:
测试方法:
B、引用类型 当指定bean 的某属性值为另一bean 的实例时,通过ref 指定它们间的引用关系。ref 的值必须为某bean 的 id 值。
[root@VM-8-8-centos ~]# yum install gcc-c++
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
Package gcc-c++-4.8.5-39.el7.x86_64 already installed and latest version
Nothing to do
events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接,常用的设置包括是否开启对多 work process 下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求,每个 word process 可以同时支持的最大连接数等。 上述例子就表示每个 work process 支持的最大连接数为 1024,这部分的配置对 Nginx 的性能影响较大,在实际中应该灵活配置。
通过 git status 命令可以看到文件当前状态 Changes not staged for commit:(改动文件未提交到暂存区)
On branch daily/0.0.1
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README.md
no changes added to commit (use "git add" and/or "git commit -a")
git add
“添加文件变动到暂存区
git add README.md
通过指定文件名 README.md 可以将该文件添加到暂存区,如果想添加所有文件可用 git add . 命令,这时候可通过 git status 看到文件当前状态 Changes to be committed: (文件已提交到暂存区)
On branch daily/0.0.1
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.md
将 create 方法里返回的ID放到 store 后面,此时在栈里真正创建了一个记录,但当前修改或删除的文件并未从工作区移除
$ git stash create
09eb9a97ad632d0825be1ece361936d1d0bdb5c7
$ git stash store 09eb9a97ad632d0825be1ece361936d1d0bdb5c7
$ git stash list
stash@{0}: Created via "git stash store".
操作历史
git log
“显示提交历史记录
git log -p
显示带提交差异对比的历史记录
git log demo.html
显示 demo.html 文件的历史记录
git log --since="2 weeks ago"
显示2周前开始到现在的历史记录,其它时间可以类推
git log --before="2 weeks ago"
显示截止到2周前的历史记录,其它时间可以类推
git log -10
显示最近10条历史记录
git log f5f630a..HEAD
显示从提交ID f5f630a 到 HEAD 之间的记录,HEAD 可以为空或其它提交ID
git log --pretty=oneline
在一行中输出简短的历史记录
git log --pretty=format:"%h"
格式化输出历史记录
Git 用各种 placeholder 来决定各种显示内容,我挑几个常用的显示如下:
%H: commit hash
%h: 缩短的commit hash
%T: tree hash
%t: 缩短的 tree hash
%P: parent hashes
%p: 缩短的 parent hashes
%an: 作者名字
%aN: mailmap的作者名
%ae: 作者邮箱
%ad: 日期 (–date= 制定的格式)
%ar: 日期, 相对格式(1 day ago)
%cn: 提交者名字
%ce: 提交者 email
%cd: 提交日期 (–date= 制定的格式)
%cr: 提交日期, 相对格式(1 day ago)
%d: ref名称
%s: commit信息标题
%b: commit信息内容
%n: 换行
git cherry-pick
“合并分支的一条或几条提交记录到当前分支末梢
git cherry-pick 170a305
合并提交ID 170a305 到当前分支末梢
git reset
“将当前的分支重设(reset)到指定的 <commit> 或者 HEAD
git reset --mixed <commit>
--mixed 是不带参数时的默认参数,它退回到某个版本,保留文件内容,回退提交历史
git reset --soft <commit>
暂存区和工作区中的内容不作任何改变,仅仅把 HEAD 指向 <commit>
git reset --hard <commit>
自从 <commit> 以来在工作区中的任何改变都被丢弃,并把 HEAD 指向 <commit>
git rebase
“重新定义分支的版本库状态
git rebase branch_name
合并分支,这跟 merge 很像,但还是有本质区别,看下图:
合并过程中可能需要先解决冲突,然后执行 git rebase --continue
git rebase -i HEAD~~
打开文本编辑器,将看到从 HEAD 到 HEAD~~ 的提交如下
pick 9a54fd4 添加commit的说明
pick 0d4a808 添加pull的说明
# Rebase 326fc9f..0d4a808 onto d286baa
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#