Mybatis系列4:工厂模式在数据源和事务中的应用

编程入门 行业动态 更新时间:2024-10-08 13:28:41

Mybatis系列4:工厂模式在<a href=https://www.elefans.com/category/jswz/34/1767050.html style=数据源和事务中的应用"/>

Mybatis系列4:工厂模式在数据源和事务中的应用

在数据持久层中,数据源是一个非常重要的组件,其性能直接关系到整个数据持久层的性能 。在实践中比较常见的第三方数据源组件有 Apache Common DBCP,C3PO 、 Proxool 等, MyBatis不仅可以集成第三方数据源组件,还提供了自己的数据源实现。这个过程是一个典型的工厂模式。
另外还有事务的设计也是工厂模式。

1. 什么是工厂模式

1.1介绍

工厂模式具体包含简单工厂模式,工厂方法模式和抽象工厂模式三个类型。
简单工厂就是通过传入的参数来决定创建哪种类型的工厂。简单工厂有一个具体的工厂类,可以生成多个不同类型的产品。
工厂模式适用于产品种类相对较少场景,可以方便快速创建不同的产品。

工厂模式要点
简单工厂模式(静态工厂模式),虽然某个程度不符合设计原则,但实际使用最多。 工厂方法模式:不修改已有类的前提下,通过增加新的工厂类实现扩展。 抽象工厂模式:不可以增加产品,可以增加产品族。
简单工厂就是我们通常写的if else型的代码,根据参数决定创建什么对象。
工厂模式是典型的解耦框架,符合迪米特,依赖倒转和里式替换原则。

简单工厂中,主要包含3中角色:
1.抽象产品,接口 ,定义要创建的产品的属性。
2.具体产品:抽象产品的具体实现类。
3.简单工厂,根据输入的参数决定创建哪个产品。

编程心得

1.2简单工厂

优点:结构简单,根据外部给定的参数快速创建需要的产品。
缺点:工厂类单一,负责所有产品的创建,当产品比较多或者变化比较大时难以维护,违背高聚合原则。
接口:

public interface ICourse {void record();
}

两个具体创建类:

package ch2_factory.simple;public class JavaCourse implements ICourse {public void record() {System.out.println("录制java课程");}
}package ch2_factory.simple;public class PythonCourse implements ICourse {public void record() {System.out.println("录制python课程");}
}

简单工厂:

package ch2_factory.simple;public class CourseFactory {public ICourse createCourse(String parame) {if ("java".equals(parame)) {return new JavaCourse();} else if ("python".equals(parame)) {return new PythonCourse();} else {return null;}}
}

调用接口:

package ch2_factory.simple;
public class MainTest {public static void main(String[] args) {CourseFactory courseFactory = new CourseFactory();ICourse course = courseFactory.createCourse("java");course.record();}
}

1.3 工厂方法

工厂方法也叫多态性工厂模式,将创工厂进行了下沉和抽象,将工厂定义为一个接口,由该接口的实现类决定创建什么产品。
工厂方法模式适用于简单工厂模式的不足的场景,或者创建对象需要大量重复的代码等情况。

抽象工厂有四个角色:
1.抽象产品:定义要创建的产品的属性。
2.具体产品:实际需要的产品的实现类。
3.抽象工厂:工厂创建这些产品的方法是什么
4.具体工厂:根据具体产品的情况,分别是创建。

工厂方法的优点:
(1)比较灵活,新产品的创建比较容易,新添加产品和对应工厂的实现类即可。
(2)解耦效果好。
缺点:
(1)类的个数比较多,代码量比较多。
(2)增加了系统的抽象性和理解的难度。

工厂模式的创建步骤:
创建一个实体的抽象接口,然后有几个实体就有建立几个实现类:

public interface Car{public void run();
}public Audi implements Car{public void run(){System.out.println("Audi run")};
}public Byd implements Car{public void run(){System.out.println("Byd run"};
}

2.定义一个工厂接口,有几个实体类就建立几个工厂实现类。

public interface CarFactory{public void createCar();}public class AudiFactory{private Car car;public Car createCar(car=new Audi();return car;);}public class BydFactory{private Car car;public Car createCar(car=new Byd();return car;);}

3.格式为 实体抽象接口 实体名=new 工厂实现类.创建方法

Car car=new AudiFactory.createCar();
car.run();Car car2=new BydFactory.createCar();
car2.run();

1.4 抽象工厂模式

围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂。
对于增加新的产品,无能为力;支持增加产品族
抽象工厂模式是工厂方法模式的升级版,在有多个业务品种,业务分类时,通过抽象工厂模式产生需要的对象时一种非常好的解决方式。 意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
主要解决:主要解决接口选择的问题。
何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
如何解决:在一个产品族里面,定义多个产品。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
关键代码:在一个工厂里聚合多个同类产品。

抽象工厂适用于需要生产产品族的情景。

抽象工厂的角色也有四个:
1.抽象产品:为一类产品对象声明一个接口。
2.具体产品: 实现创建的具体产品对象的操作。
3.抽象工厂:声明创建抽象产品对象的一个操作接口。
4.具体工厂: 实现创建具体产品的操作。

创建和使用步骤:
确定有几个组件,例如车子有轮胎,发动机,靠椅等,为每个分别建立接口和不同方式的实现类,例如高中低档次等。
建立工厂接口,只记录包含的组件。例如车子,包含创建轮胎,发动机,和靠椅等。然后根据不同的要求建立工厂实现类,实现的接口就是1中的不同实现类。
直接确定使用哪个工厂实现类即可。这一层创建出来的就是各个组件。
发动机组件:

public interface Engine {void run();void start();
}class LuxuryEngine implements Engine {@Overridepublic void run() {System.out.println("转得快");}@Overridepublic void start() {System.out.println("启动快");}
}class LowerEngine implements Engine {@Overridepublic void run() {System.out.println("转得慢");}@Overridepublic void start() {System.out.println("启动慢");}
}

轮胎组件:


public interface Lyre {
void revolve();
}

class LuxuryTyre implements Lyre {

@Override
public void revolve() {System.out.println("不磨损");
}

}

class LowerTyre implements Lyre {

@Override
public void revolve() {System.out.println("磨损快");
}

}


座椅组件:

public interface Seat {void massage();
}class LuxurySeat implements Seat {@Overridepublic void massage() {System.out.println("可以自动按摩");}}class LowSeat implements Seat {@Overridepublic void massage() {System.out.println("不能自动按摩");}
}

然后物体的抽象接口,然后有几种情况就给出几个实现:

public interface CarFactory {Lyre createLyre();Engine createEngine();Seat createSeat();
}public class LoweryCarFactory implements CarFactpory {@Overridepublic Lyre createLyre() {return new LowerTyre();}@Overridepublic Engine createEngine() {return new LowerEngine();}@Overridepublic Seat createSeat() {return new LowSeat();}
}public class LuxuryCarFactory implements CarFactpory {@Overridepublic Lyre createLyre() {return new LuxuryTyre();}@Overridepublic Engine createEngine() {return new LuxuryEngine();}@Overridepublic Seat createSeat() {return new LuxurySeat();}
}

调用:

 public static void main(String[] args) {LoweryCarFactory loweryCarFactory = new LoweryCarFactory();Engine engine= loweryCarFactory.createEngine();engine.run();engine.start();//或者这样直接调用loweryCarFactory.createLyre().revolve();loweryCarFactory.createSeat().massage();    }

2. 工厂模式在数据源的应用

常见的数据源组件都实现了 javax.sql.DataSource 接口, MyBatis自身实现的数据源实现也不例外。 MyBatis 提供了两个 javax.sql.DataSource 接口实现,分别是 PooledDataSource 和UnpooledDataSource 。 Mybatis 使用不同的 DataSourceFactory 接口实现创建不同类型的DataSource ,如图所示,这是工厂方法模式的一个典型应用。

在数据源模块中, DataSourceFactory 接口扮演工厂接口的角色 。 UnpooledDataSourceFactory和 PooledDataSourceFactory 则扮演着具体工厂类的角色。我们从 DataSourceFactory 接口开始分析,其定义如下:

public interface DataSourceFactory {
//设置 Data Source 的相关属性,一般紧跟在初始化完成之后void setProperties(Properties props);
//获取 DataSource 对象DataSource getDataSource();}

在 UnpooledDataSourceFactory 的构造函数中会直接创建 UnpooledDataSource 对象,并初始化 UnpooledDataSourceFactory.dataSource 宇段。 UnpooledDataSourceFactory.setProperties()方法会
完成对 UnpooledDataSource 对象的配置,代码如下:

 public void setProperties(Properties properties) {Properties driverProperties = new Properties();//这里应该是建立了某种关联MetaObject metaDataSource = SystemMetaObject.forObject(dataSource);for (Object key : properties.keySet()) {String propertyName = (String) key;if (propertyName.startsWith(DRIVER_PROPERTY_PREFIX)) {String value = properties.getProperty(propertyName);driverProperties.setProperty(propertyName.substring(DRIVER_PROPERTY_PREFIX_LENGTH), value);} else if (metaDataSource.hasSetter(propertyName)) {String value = (String) properties.get(propertyName);Object convertedValue = convertValue(metaDataSource, propertyName, value);metaDataSource.setValue(propertyName, convertedValue);} else {throw new DataSourceException("Unknown DataSource property: " + propertyName);}}if (driverProperties.size() > 0) {metaDataSource.setValue("driverProperties", driverProperties);}}

Unpoo ledDataSourceFactory.getDataSource()方法实现比较简单 ,它直接返回 dataSource 字段
记录的 UnpooledDataSource 对象 。
PooledDataSourceFactory 继承了 UnpooledDataSourceFactory ,但并没有覆盖 setProperties()
方法和 getDataSource()方法。两者唯一 的区别是 PooledDataSourceFactory 的构造函数会将其
dataSource 字段初始化为 PooledDataSource 对象。

3.工厂模式在事务中的应用

在实践开发 中, 控制数据库事务是一件非常重要的工作, MyBatis 使用 Transaction 接口对数据库事务进行了 抽象,
Transaction 接口有 JdbcTransaction 、 ManagedTransaction 两个实现,其对象分别 由
JdbcTransactionFactory 和 ManagedTransactionFactory 负 责创建 。 如图所示 ,这里也使用了
工厂方法模式。

Transaction 接口的定义如下 :

public interface Transaction {Connection getConnection() throws SQLException;void commit() throws SQLException;void rollback() throws SQLException;void close() throws SQLException;Integer getTimeout() throws SQLException;}
TransactionFactory 接口定义了配置新建 TransactionFactory 对象的 方法 ,以 及 创 建
Transaction 对象的方法,代码如下 :
public interface TransactionFactory {default void setProperties(Properties props) {// NOP}Transaction newTransaction(Connection conn);Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);
}

JdbcTransactionFactory 和 ManagedTransactionFactory 负责创建 JdbcTransaction 和
ManagedTransaction。
不过MyBatis 通常会与Spring集成使用, 数据库的事务是交给 Spring 进行管理的,自身没有提供太多相关的功能。

更多推荐

Mybatis系列4:工厂模式在数据源和事务中的应用

本文发布于:2024-02-14 00:14:21,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1761268.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数据源   工厂   事务   模式   系列

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!