我目前正在尝试构建一个使用Spring,Hibernate和Maven(在tomcat上运行)的小型webapp.它工作得很好,除了我无法使我的嵌入式数据库工作.我希望你能帮助我.
当我将webapp部署到Tomcat时,我总是面临这个错误:
匹配的通配符是严格的,但是找不到元素'jdbc:embedded-database'的声明
在我的调查过程中,我了解到这条消息指向缺少的图书馆.因此我添加了我的pom.xml,我添加了工件spring-jdbc.
你能帮我找到错误吗?非常感谢!
这是我的spring-configuration文件,它会在webapp初始化期间导致错误:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jdbc="http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd">
<bean id="sessionFactory" class=
"org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="embeddedDatasource" />
<property name="packagesToScan" value="org.rest" />
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.hbm2ddl.auto=update
hibernate.show_sql=false
</value>
</property>
</bean>
<jdbc:embedded-database id="embeddedDatasource" type="HSQL"/>
<bean id="txManager" class=
"org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
</beans>
Run Code Online (Sandbox Code Playgroud)
这是我的pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.marcus</groupId>
<artifactId>maven-webapp-archetype</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>maven-webapp-archetype Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency> …Run Code Online (Sandbox Code Playgroud) 问题是关于RowMapper在主/详细场景中的最佳实践用法,我们希望使用spring jdbc急切地获取详细信息.
假设我们同时拥有Invoice和InvoiceLine类.
public class Invoice{
private BigDecimal invId;
private Date invDate;
private List<InvoiceLine> lines;
}
public class InvoiceLine{
private int order;
private BigDecimal price;
private BigDecimal quantity;
}
Run Code Online (Sandbox Code Playgroud)
当使用带有行映射器的Spring Jdbc时,我们通常会有一个
public class InvoiceMapper implements RowMapper<Invoice>{
public Invoice mapRow(ResultSet rs, int rowNum) throws SQLException {
Invoice invoice = new Invoice();
invoice.setInvId(rs.getBigDecimal("INVID"));
invoice.setInvDate(rs.getDate("INVDATE"));
return invoice;
}
}
Run Code Online (Sandbox Code Playgroud)
现在问题是我想急切地获取与此发票实例相关的InvoiceLine.如果我在rowmapper类中查询数据库会没关系吗?或者任何人更喜欢另一种方式?我使用下面的模式,但不满意.
public class InvoiceMapper implements RowMapper<Invoice>{
private JdbcTemplate jdbcTemplate;
private static final String SQLINVLINE=
"SELECT * FROM INVOICELINES WHERE INVID = ?";
public Invoice …Run Code Online (Sandbox Code Playgroud) Spring JDBC中的数据库方法接受单个参数源.例如 -
int org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(String sql, SqlParameterSource paramSource) throws DataAccessException
Run Code Online (Sandbox Code Playgroud)
是否可以将多个参数源组合在一起?例如,假设我有一个豆Order-
class Order {
int id;
float price;
int customerId;
Date date;
//Lots of other fields
}
Run Code Online (Sandbox Code Playgroud)
我想用一些额外的字段保存这个bean,比如recordModificationTime和accessLevel.
如果我使用MapSqlParameterSource存在于bean之外的这些额外字段,我无法使用,BeanPropertySqlParameterSource因为该方法只接受一个参数源.必须使用MapSqlParameterSource我的所有数据意味着我必须手动提取所有bean属性,这是很多工作.
处理这个问题的最佳方法是什么?
我按照以下方式使用SimpleJdbcTemplate和MapSqlParameterSource:
MapSqlParameterSource parameterSource = new MapSqlParameterSource();
parameterSource.addValue("typeId", typeId, Types.BIGINT);
List<Long> ids = _jdbcTemplate.query(_selectIdByParameters, new EntityIdRowMapper(), parameterSource);
Run Code Online (Sandbox Code Playgroud)
当typeId(是a Long)是null,则查询以下列方式查找:
SELECT id FROM XXX WHERE typeId = null
Run Code Online (Sandbox Code Playgroud)
而我希望它会产生
SELECT id FROM XXX WHERE typeId IS NULL
Run Code Online (Sandbox Code Playgroud)
我已经报告了这个问题并且回应是这样的
您必须根据查询参数提供适当的SQL语句.
结果我的代码充满了空检查.
是否有更优雅的方式处理发送到SimpleJdbcTemplate?的空参数?
My Domain对象有几个Joda-Time DateTime字段.当我使用SimpleJdbcTemplate读取数据库值时:
患者患者= jdbc.queryForObject(sql,new BeanPropertyRowMapper(Patient.class),patientId);
它只是失败,令人惊讶的是,没有记录任何错误.我想这是因为timestamp解析DateTime不适用于Jdbc.
如果可以继承和覆盖BeanPropertyRowMapper并指示转换all java.sql.Timestamp和java.sql.Dateto DateTime,那就太棒了,可以节省很多额外的代码.
有什么建议?
我有一个批量进程,它执行Bulk UPDATE语句.
在使用Spring JDBC 4.1.6和Oracle Jdbc驱动程序(ojdbc7和ucp)实现批处理支持后,对各个更新请求(批处理)中受影响的记录数始终检索为-2(Statement.SUCCESS_NO_INFO).
有没有办法知道各个更新请求受影响的行(批处理中设置的参数),因为我必须在此之后用INSERT语句重试相同的参数?
从技术上来说,尝试将其作为UPSERT实现来开发
我尝试了三种不同方式的批量更新,并且在所有三种方法中结果都相同 - (它只是告诉我Statement.SUCCESS_NO_INFO(-2))
方法1 - 直接UCP连接和PreparedStatement
connectionPoolMgr.startConnectionPool("mgr_pool");
Connection connection = pds.getConnection();
PreparedStatement pstmt = connection.prepareStatement(dmlSQL);
pstmt.setInt(1, pkId);
pstmt.setInt(2, idx * 10);
pstmt.addBatch();
// EVERY ELEMENT IN THIS ARRAY IS ALWAYS returned as -2
int updatedRows[] = pstmt.executeBatch();
Run Code Online (Sandbox Code Playgroud)
方法2 - Spring JdbcTemplate和batchUpdate()
MapSqlParameterSource[] paramsArray = getSqlParameterList().toArray(new MapSqlParameterSource[0]);
// EVERY ELEMENT IN THIS ARRAY IS ALWAYS returned as -2
int[] batchUpdateResult = getNamedParameterJdbcTemplate().batchUpdate(sqlStatement, paramsArray);
Run Code Online (Sandbox Code Playgroud)
方法3 - Spring BatchSqlUpdate实现
BatchInsert batchInsert = new BatchInsert(dataSource);
for …Run Code Online (Sandbox Code Playgroud) 当jdbcTemplate.batchUpdate(...)正在运行时,我可以看到DB行数逐渐增加(通过count(*)在表中运行),最初是2k然后是3k并且直到10k.2k和3k不是确切的数字有时我得到235然后4567.
我期待一次性提交10 k行(批量大小).根据我的理解,如果最初,我得到行计数0然后下一行计数应该是10k.我不希望逐个插入性能原因,这就是为什么使用批量更新功能,似乎它也不会一次性全部提交.
我想将数据(10k行)仅发送到DB服务器一次,用于我的批量大小.为此,我应该在配置中指定什么?
下面是我编写jdbcTemplate批量更新批量大小为10k的方式.
public void insertRows(...) {
...
jdbcTemplate.batchUpdate(query, new BatchPreparedStatementSetter(){
@Override public void
setValues(PreparedStatement ps, int i) throws SQLException {
...
}
@Override public int getBatchSize() {
if(data == null){
return 0;
}
return data.size();
}
});
}
Run Code Online (Sandbox Code Playgroud)
编辑:将@Transactional添加到isertRows方法仍然可以看到相同的行为.使用Transnational它会在10k行之后提交,但是当我看到count使用UR时(从mytable中选择count(*)与ur)它会显示逐渐更新的数据(2k 4k,直到10k).这意味着数据以块的形式进入服务器(可能是一个再见).我如何一次性发送所有内容.这个问题表明它是使用mysql中的rewriteBatchedStatements实现的,我们在DB2中也有类似的东西.
我正在使用DataSource实现com.ibm.db2.jcc.DB2BaseDataSource
我想做这样的事情:
INSERT INTO TABLEA
(
COLUMN1, COLUMN2, COLUMN 3
)
SELECT FOOBAR, DOOBAR, ?
FROM TABLEB
Run Code Online (Sandbox Code Playgroud)
然后通过Spring JDBC将其发送给JDBC进行更新......
simpleJdbcTemplate.update( mySqlFromAbove, someVariableToReplaceQuestionMark );
Run Code Online (Sandbox Code Playgroud)
这甚至可能吗?如果我在构建SQL查询时用硬编码的值替换问号,它会正常工作,但我不想打开自己的SQL注入...
编辑 -
我得到
嵌套异常是com.ibm.db2.jcc.c.SqlException:DB2 SQL错误:SQLCODE:-418,SQLSTATE:42610,SQLERRMC:null
这似乎表明
参数标记的使用无效?
是否有类似Spring JDBC Template的Java库,具有相同质量的代码和文档以及类似的数据访问异常层次结构,但没有依赖于其他Spring模块(根据http://mvnrepository.com/artifact/org的核心/ bean/context模块).springframework/spring-jdbc/3.0.6.RELEASE)?
我试图使用Spring的JdbcTemplate类连接到基于本教程的简单MySql数据库.实际上,我使用了他们的项目设置:
的pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>jdbc-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.14.8</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Run Code Online (Sandbox Code Playgroud)
Lombok依赖是针对getter和setter的.
然后是Application类:
package test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.jdbc.core.JdbcTemplate;
@SpringBootApplication
public class Application implements CommandLineRunner {
public static void main(String args[]) {
SpringApplication.run(Application.class, args);
}
@Autowired
JdbcTemplate jdbcTemplate; …Run Code Online (Sandbox Code Playgroud) spring-jdbc ×10
java ×8
spring ×6
jdbc ×3
db2 ×1
db2-9.7 ×1
jdbctemplate ×1
jodatime ×1
maven ×1
maven-3 ×1
mysql ×1
oracle ×1
spring-boot ×1
sql ×1
tomcat7 ×1