build模式入门,build模式理解(转载)

问:为何要用?

 

普通做法:

1.创建pojo

public class Person {

private String name;

private int age;

private double height;

private double weight;

public Person(String name) {

this.name = name;

}

public Person(String name, int age) {

this.name = name;

this.age = age;

}

public Person(String name, int age, double height) {

this.name = name;

this.age = age;

this.height = height;

}

public Person(String name, int age, double height, double weight) {

this.name = name;

this.age = age;

this.height = height;

this.weight = weight;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public double getHeight() {

return height;

}

public void setHeight(double height) {

this.height = height;

}

public double getWeight() {

return weight;

}

public void setWeight(double weight) {

this.weight = weight;

}

}

2.创建对象

Person p1 = new Person();

Person p2 = new Person("张三");

Person p3 = new Person("李四", 18);

Person p4 = new Person("王五", 21, 180);

Person p5 = new Person("赵六", 17, 170, 65.4);

 

或者使用setName()、setWeight()等set方法

 

 

这样创建是没问题,

使用构造函数,前提是你自己很熟悉这个Person里面的参数顺序是什么,比如p4对象的21和180,抛开常理,这两个都是数字,你怎么知道那个是年龄那个是身高呢,这样就产生问题,如果数字类型的参数过多,那简直就是灾难,你自己都不知道每个数字代表什么,所以builder模式就很好解决了这个问题。

使用set方法,有可能导致对象不一致

 

构造模式的使用:

 
public class Person {

private String name;

private String sex;

private int age;

private int weight;

private int hight;

 

/**

* 带参构造

* @param name

* @param sex

* @param age

* @param weight

* @param hight

*/

public Person(String name, String sex, int age, int weight, int hight) {

super();

this.name = name;

this.sex = sex;

this.age = age;

this.weight = weight;

this.hight = hight;

}

 

/**

* getter和setter

* @return

*/

public String getName() {

return name;

}

 

public void setName(String name) {

this.name = name;

}

 

public String getSex() {

return sex;

}

 

public void setSex(String sex) {

this.sex = sex;

}

 

public int getAge() {

return age;

}

 

public void setAge(int age) {

this.age = age;

}

 

public int getWeight() {

return weight;

}

 

public void setWeight(int weight) {

this.weight = weight;

}

 

public int getHight() {

return hight;

}

 

public void setHight(int hight) {

this.hight = hight;

}

 

@Override

public String toString() {

return "Person [name=" + name + ", sex=" + sex + ", age=" + age + ", weight=" + weight + ", hight=" + hight

+ "]";

}

 

 

 

/**

* builder模式

*/

static class Builder {

private String name;

private String sex;

private int age;

private int weight;

private int hight;

 

public Builder name(String name) {

this.name = name;

return this;//返回自身对象,在后面的链式调用中就可以自身对象的属性和方法了

}

 

public Builder sex(String sex) {

this.sex = sex;

return this;//返回自身对象,在后面的链式调用中就可以自身对象的属性和方法了

}

 

public Builder age(int age) {

this.age = age;

return this;//返回自身对象,在后面的链式调用中就可以自身对象的属性和方法了

}

 

public Builder weight(int weight) {

this.weight = weight;

return this;//返回自身对象,在后面的链式调用中就可以自身对象的属性和方法了

}

 

public Builder hight(int hight) {

this.hight = hight;

return this;//返回自身对象,在后面的链式调用中就可以自身对象的属性和方法了

}

 

public Person build() {

return new Person(name, sex, age, weight, hight);

}

}

 

public static void main(String[] args) {

Person p1= new Person.Builder().age(18).hight(180).name("lx").build();

System.out.println(p1.toString());

}

这里注意一下几点基础知识:

1、类中的再声明一个类

java类里面还可以定义一个类,即内部类,但是要注意:1.内部类不能通过普通方式访问,内部类时外部类的一个普通成员,所以内部类可以方位外部类成员,即使这些类时private;2.若内部类声明成static时,就只能访问同样声明为static的外部类成员了。

2、只能有一个public 修饰的类(因为一个类文件中类名必须和文件名一致,而文件名根据规则必须是public修饰的那个类名)

 

做了这么多的铺垫,重点来了 ,build模式的应用场景在什么地方呢?

1、mybatis

mybatis四大核心,

SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper

1、SqlSessionFactoryBuilder

从命名上可以看出,这个是一个 Builder 模式的,用于创建 SqlSessionFactory 的类。SqlSessionFactoryBuilder 根据配置来构造 SqlSessionFactory。

2、SqlSessionFactory

SqlSessionFactory 顾名思义,是用于生产 SqlSession 的工厂。

通过如下的方式来获取 SqlSession 实例:

SqlSession session = sqlSessionFactory.openSession();

3、
SqlSession

SqlSession 包含了执行 SQL 的所有的方法(执行持久化的操作对象)。以下是示例:

SqlSession session = sqlSessionFactory.openSession();
try {
Blog blog = session.selectOne(
"org.mybatis.example.BlogMapper.selectBlog", 101);
} finally {
session.close();
}

当然,下面的方式可以做到类型安全:

SqlSession session = sqlSessionFactory.openSession();
try {
BlogMapper mapper = session.getMapper(BlogMapper.class);//面向接口编程
Blog blog = mapper.selectBlog(101);
} finally {
session.close();
}
4、Mapper

Mapper 顾名思义,是用做 Java 与 SQL 之间的映射的。包括了 Java 映射为 SQL 语句,以及 SQL 返回结果映射为 Java。

 

比如,下面是一个常见的 Mapper 接口映射文件:

<?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="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
</select>
</mapper>

其中 “org.mybatis.example.BlogMapper” 就是我们要射射的接口,selectBlog 就是BlogMapper上的方法。而这个 selectBlog 具体就是要执行“select * from Blog where id = #{id}”这个 SQL 语句。

这样,我们就能通过

Blog blog = session.selectOne(
"org.mybatis.example.BlogMapper.selectBlog", 101);

或者是

BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);

来获取到执行的结果。

当然,如果是采用注解的方式的话,可以省去 XML 文件:

public interface BlogMapper {
@Select("SELECT * FROM blog WHERE id = #{id}")
Blog selectBlog(int id);
}
 

 

posted @ 2020-02-28 09:09  夹竹桃  阅读(1602)  评论(0编辑  收藏  举报