如何建设网站兴田德润怎么联系,软件开发项目经理的工资一般多少,html使用wordpress,泰州网站建设开发我遇到了由ORM引起的性能问题。 尽管我不得不承认大多数这些问题确实是由您造成的#xff0c;但是我开始认为在只读操作中使用ORM是不值得的。 我开始寻找实现这些操作的替代方法。 这就是我遇到jOOQ的方式 #xff0c;它指出#xff1a; jOOQ从您的数据库生成Java代码但是我开始认为在只读操作中使用ORM是不值得的。 我开始寻找实现这些操作的替代方法。 这就是我遇到jOOQ的方式 它指出 jOOQ从您的数据库生成Java代码并允许您通过其流畅的API构建类型安全的SQL查询。 这看起来非常有趣因此我决定给jOOQ一炮而红并与您分享我的发现。 这篇博客文章是我的“将jOOQ与Spring结合使用”系列的第一部分它描述了如何获取所需的依赖关系并配置应用程序的应用程序上下文。 让我们开始吧。 使用Maven获取所需的依赖关系 我们的应用程序的依赖项是 Spring Framework 3.2.6。 此时我们的示例使用aop bean core context context-support jdbc和tx模块。 cglib 3.1。 BoneCP 0.8.0。 我们使用BoneCP作为示例应用程序的连接池。 jOOQ 3.2.2。 H2 1.3.174。 我们使用H2作为示例应用程序的数据库。 如果您想获得有关Spring Framework模块的更多信息请阅读Spring Framework Reference Documentation的1.2节 。 该示例应用程序使用Spring Framework 3.2.6而不是4.0的原因是目前spring-test-dbunit与Spring Framework 4.0不兼容 。 pom.xml文件的相关部分如下所示 dependencygroupIdorg.springframework/groupIdartifactIdspring-aop/artifactIdversion3.2.6.RELEASE/version
/dependency
dependencygroupIdorg.springframework/groupIdartifactIdspring-beans/artifactIdversion3.2.6.RELEASE/version
/dependency
dependencygroupIdorg.springframework/groupIdartifactIdspring-core/artifactIdversion3.2.6.RELEASE/version
/Dependency
dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion3.2.6.RELEASE/version
/dependency
dependencygroupIdorg.springframework/groupIdartifactIdspring-context-support/artifactIdversion3.2.6.RELEASE/version
/dependency
dependencygroupIdorg.springframework/groupIdartifactIdspring-expression/artifactIdversion3.2.6.RELEASE/version
/dependency
dependencygroupIdorg.springframework/groupIdartifactIdspring-jdbc/artifactIdversion3.2.6.RELEASE/version
/dependency
dependencygroupIdorg.springframework/groupIdartifactIdspring-tx/artifactIdversion3.2.6.RELEASE/version
/dependencydependencygroupIdcglib/groupIdartifactIdcglib/artifactIdversion3.1/version
/dependencydependencygroupIdcom.jolbox/groupIdartifactIdbonecp/artifactIdversion0.8.0.RELEASE/version
/dependencydependencygroupIdorg.jooq/groupIdartifactIdjooq/artifactIdversion3.2.2/version
/dependencydependencygroupIdcom.h2database/groupIdartifactIdh2/artifactIdversion1.3.174/version
/dependency 此博客文章的示例应用程序还具有其他依赖性。 通过查看pom.xml文件可以看到完整的依赖项列表。 让我们继续研究如何将jOOQ抛出的异常转换为Spring DataAccessExceptions 。 将jOOQ异常转换为Spring DataAccessExceptions 为什么我们要将jOOQ抛出的异常转换为Spring DataAccessExceptions 这样做的一个原因是我们希望我们的集成工作与Spring Framework的DAO支持相同。 这种支持的重要组成部分是一致的异常层次结构 Spring提供了从技术特定的异常如SQLException到其自己的异常类层次结构以DataAccessException作为根异常的便捷转换。 这些异常包装了原始异常因此永远不会冒任何可能丢失任何错误信息的风险。 换句话说如果我们希望我们的应用程序是“好公民”那么确保我们的配置将jOOQ抛出的异常转换为Spring DataAccessExceptions是有意义的。 我们可以按照以下步骤创建提供此功能的组件 创建一个JOOQToSpringExceptionTransformer类该类扩展了DefaultExecuteListener类。 DefaultExecuteListener类是ExecuteListener接口的公共默认实现该接口为单个查询执行的不同生命周期事件提供侦听器方法。 重写DefaultExecuteListener类的exceptionExecuteContext ctx方法 。 如果在执行生命周期的任何时刻引发异常则调用此方法。 通过执行以下步骤来实现该方法 从jOOQ配置中获取一个SQLDialect对象。 通过遵循以下规则创建一个实现SQLExceptionTranslator接口的对象 如果找到已配置的SQL方言请创建一个新的SQLErrorCodeSQLExceptionTranslator对象并将SQL方言的名称作为构造函数参数传递。 此类通过分析供应商特定的错误代码来“选择”正确的DataAccessException 。 如果找不到SQL方言请创建一个新的SQLStateSQLExceptionTranslator对象。 此类通过分析存储到SQLException的SQL状态来“选择”正确的DataAccessException 。 通过使用创建的SQLExceptionTranslator对象创建DataAccessException 对象 。 将抛出的DataAccessException转发给作为方法参数给出的ExecuteContext对象。 JOOQToSpringExceptionTransformer类的源代码如下所示 import org.jooq.ExecuteContext;
import org.jooq.SQLDialect;
import org.jooq.impl.DefaultExecuteListener;
import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
import org.springframework.jdbc.support.SQLExceptionTranslator;
import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;public class JOOQToSpringExceptionTransformer extends DefaultExecuteListener {Overridepublic void exception(ExecuteContext ctx) {SQLDialect dialect ctx.configuration().dialect();SQLExceptionTranslator translator (dialect ! null)? new SQLErrorCodeSQLExceptionTranslator(dialect.name()): new SQLStateSQLExceptionTranslator();ctx.exception(translator.translate(jOOQ, ctx.sql(), ctx.sqlException()));}
} 这不是我的主意 。 我从亚当·泽尔Adam Zell的要旨Gist中得到了这个想法。 补充阅读 jOOQ用户手册的第4.2.5节“自定义ExecuteListeners” Spring框架参考文档的第14.2.3节“ SQLExceptionTranslator” 我们的工作还没有完成。 让我们放在一起通过配置示例应用程序的应用程序上下文来完成我们的工作。 配置应用程序上下文 本节说明如何使用Java配置来配置应用程序的应用程序上下文。 让我们开始创建一个属性文件其中包含示例应用程序的配置。 实际应用程序的构建过程基于Maven配置文件。 这确保了我们可以在不同的环境中使用不同的配置。 您可以阅读我的博客文章“ 使用Maven创建配置文件特定的配置文件”以获取有关此内容的更多信息。 创建属性文件 我们可以按照以下步骤创建属性文件 配置数据库连接。 我们需要配置JDBC驱动程序类JDBC URL数据库用户的用户名和数据库用户的密码。 配置使用的SQL方言的名称。 配置创建示例应用程序数据库的SQL脚本的名称这是一个可选步骤如果您的应用程序不使用嵌入式数据库则不需要此步骤。 application.properties文件如下所示 #Database Configuration
db.driverorg.h2.Driver
db.urljdbc:h2:target/jooq-example
db.usernamesa
db.password#jOOQ Configuration
jooq.sql.dialectH2#DB Schema
db.schema.scriptschema.sql SQLDialect枚举的Javadoc指定jOOQ支持的数据库方言列表。 让我们继续研究如何使用Java配置来配置应用程序的应用程序上下文。 创建配置类 我们可以按照以下步骤配置应用程序的应用程序上下文 创建一个PersistenceContext类。 通过使用Configuration批注注释该类确保将创建的类识别为配置类。 确保在组件扫描期间找到了我们应用程序的jOOQ存储库。 我们可以通过使用ComponentScan注释对配置类进行注释来实现。 通过使用EnableTransactionManagement注释对配置类进行注释以启用注释驱动的事务管理。 确保从类路径中找到的application.properties文件中加载了我们应用程序的配置。 我们可以通过使用PropertySource注释对配置类进行注释来执行此操作。 将环境字段添加到配置类中并使用Autowired批注对该字段进行批注。 我们使用Environment对象获取从application.properties文件加载的配置属性的属性值。 配置数据源 bean。 因为我们的应用程序使用BoneCP所以我们创建了一个BoneCPDataSource对象作为我们的数据源。 配置LazyConnectionDataSourceProxy bean。 该bean确保延迟获取数据库连接即在创建第一条语句时。 配置TransactionAwareDataSourceProxy bean。 该bean确保所有JDBC连接都知道Spring管理的事务。 换句话说JDBC连接参与线程绑定的事务。 配置DataSourceTransactionManager bean。 创建新的DataSourceTransactionManager对象时必须将LazyConnectionDataSourceProxy Bean作为构造函数参数传递 。 配置DataSourceConnectionProvider bean。 jOOQ将从作为构造函数参数给出的数据源中获取使用的连接。 创建新的DataSourceConnectionProvider对象时必须将TransactionAwareDataSourceProxy bean作为构造函数参数传递 。 这样可以确保创建的jOOQ查询参与Spring管理的事务。 配置JOOQToSpringExceptionTransformer bean。 配置DefaultConfiguration bean。 此类是Configuration接口的默认实现我们可以使用它来配置jOOQ。 我们必须配置三件事 我们必须设置的ConnectionProvider这是用来获取和释放数据库连接。 我们必须配置自定义执行侦听器 。 换句话说我们必须将JOOQToSpringExceptionTransformer bean添加到创建的DefaultConfiguration对象中。 这确保了jOOQ抛出的异常被转换为Spring DataAccessExceptions 。 我们必须配置使用的SQL方言。 配置DefaultDSLContext bean。 在使用jOOQ创建数据库查询时将使用此bean。 配置DataSourceInitializer bean。 启动应用程序时我们使用此bean创建H2数据库的数据库架构如果您不使用嵌入式数据库则不必配置此bean。 PersistenceContext类的源代码如下所示 import com.jolbox.bonecp.BoneCPDataSource;
import org.jooq.SQLDialect;
import org.jooq.impl.DataSourceConnectionProvider;
import org.jooq.impl.DefaultConfiguration;
import org.jooq.impl.DefaultDSLContext;
import org.jooq.impl.DefaultExecuteListenerProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.transaction.annotation.EnableTransactionManagement;import javax.sql.DataSource;Configuration
ComponentScan({net.petrikainulainen.spring.jooq.todo})
EnableTransactionManagement
PropertySource(classpath:application.properties)
public class PersistenceContext {Autowiredprivate Environment env;Bean(destroyMethod close)public DataSource dataSource() {BoneCPDataSource dataSource new BoneCPDataSource();dataSource.setDriverClass(env.getRequiredProperty(db.driver));dataSource.setJdbcUrl(env.getRequiredProperty(db.url));dataSource.setUsername(env.getRequiredProperty(db.username));dataSource.setPassword(env.getRequiredProperty(db.password));return dataSource;}Beanpublic LazyConnectionDataSourceProxy lazyConnectionDataSource() {return new LazyConnectionDataSourceProxy(dataSource());}Beanpublic TransactionAwareDataSourceProxy transactionAwareDataSource() {return new TransactionAwareDataSourceProxy(lazyConnectionDataSource());}Beanpublic DataSourceTransactionManager transactionManager() {return new DataSourceTransactionManager(lazyConnectionDataSource());}Beanpublic DataSourceConnectionProvider connectionProvider() {return new DataSourceConnectionProvider(transactionAwareDataSource());}Beanpublic JOOQToSpringExceptionTransformer jooqToSpringExceptionTransformer() {return new JOOQToSpringExceptionTransformer();}Beanpublic DefaultConfiguration configuration() {DefaultConfiguration jooqConfiguration new DefaultConfiguration();jooqConfiguration.set(connectionProvider());jooqConfiguration.set(new DefaultExecuteListenerProvider(jooqToSpringExceptionTransformer()));String sqlDialectName env.getRequiredProperty(jooq.sql.dialect);SQLDialect dialect SQLDialect.valueOf(sqlDialectName);jooqConfiguration.set(dialect);return jooqConfiguration;}Beanpublic DefaultDSLContext dsl() {return new DefaultDSLContext(configuration());}Beanpublic DataSourceInitializer dataSourceInitializer() {DataSourceInitializer initializer new DataSourceInitializer();initializer.setDataSource(dataSource());ResourceDatabasePopulator populator new ResourceDatabasePopulator();populator.addScript(new ClassPathResource(env.getRequiredProperty(db.schema.script)));initializer.setDatabasePopulator(populator);return initializer;}
} 如果要使用XML配置文件配置应用程序上下文则示例应用程序也具有有效的XML配置文件 。 学分 此配置基于jOOQ用户手册的3.4.3节 。 Sergey Epik发布的消息帮助我弄清楚了如何向jOOQ配置添加自定义ExecuteListeners。 Peter Ertl给了我一个使用LazyConnectionDataSourceProxy的想法。 我们如何知道此配置有效 这是一个好问题。 我们将在下一节中讨论。 这真的有效吗 当我开始研究如何确保用jOOQ创建的数据库查询参与Spring管理的事务时我注意到这不是一个容易解决的问题 。 这篇博客文章的示例应用程序具有一些集成测试这些测试可以确保事务提交和回滚在非常简单的场景中正常工作。 但是使用此博客文章中描述的解决方案时必须考虑两件事 1.使用jOOQ创建的所有数据库查询必须在事务内执行。 TransactionAwareDataSourceProxy类的Javadoc指出 委托DataSourceUtils自动参与线程绑定的事务例如由DataSourceTransactionManager管理。 返回的Connection上的getConnection调用和close调用将在事务中正常运行即始终在事务Connection上运行。 如果不在事务内则将应用正常的DataSource行为。 换句话说如果您执行多个复杂的操作而没有事务则jOOQ将为每个操作使用不同的连接。 这可能会导致竞赛条件错误。 在阅读Ben Manes撰写的这篇评论时我注意到了这个问题。 2. Javadoc不建议使用TransactionAwareDataSourceProxy 。 TransactionAwareDataSourceProxy类的Javadoc具有如下部分 该代理允许数据访问代码与普通JDBC API一起使用并且仍然参与Spring管理的事务这与J2EE / JTA环境中的JDBC代码类似。 但是如果可能即使没有目标DataSource的代理也可以使用Spring的DataSourceUtils JdbcTemplate或JDBC操作对象来获取事务参与从而避免了首先定义此类代理的麻烦。 这是一个模糊的评论因为它没有解释为什么我们不应该使用它。 Adam Zell建议 由于该类使用反射因此使用反射可能会导致性能问题。 如果您遇到性能问题则可能要使用 亚当·泽尔的要点 。 摘要 现在我们已经成功配置了示例应用程序的应用程序上下文。 本教程教了四件事 我们了解了如何使用Maven获得所需的依赖关系。 我们学习了如何将jOOQ引发的异常转换为Spring DataAccessExceptions 。 我们学习了如何配置使用jOOQ和Spring的应用程序的应用程序上下文。 当我们使用此博客文章中描述的方法时我们快速考虑了必须考虑的事项。 本教程的下一部分描述了我们可以使用jOOQ的代码生成支持 。 Github上提供了此博客文章的示例应用程序。 补充阅读 Vlad Mihalcea也写了有关jOOQ的文章 。 查看他的博客 参考 将jOOQ与Spring结合使用来自Petri Kainulainen博客的JCG合作伙伴 Petri Kainulainen进行的配置 。 翻译自: https://www.javacodegeeks.com/2014/01/using-jooq-with-spring-configuration.html