使用Mybatis插入数据时,由于粗心书写错误导致出现Cause: java.sql.SQLException: sql injection violation异常,SQL语句如下:
insert into mmall_product
(
)
values (
#{productId}, #{categoryId}, #{productName}, ${subtitle},
#{mainImage}, #{subImages}, #{detail}, #{productPrice},
#{stock}, #{status},
#{createTime},
now(),
#{updateTime}
now()
)
异常详细堆栈信息如下:
org.springframework.jdbc.UncategorizedSQLException:
### Error updating database. Cause: java.sql.SQLException: sql injection violation, syntax error: syntax error. pos 237, line 9, column 26, token IDENTIFIER phone : insert into mmall_product
(
id, category_id, name, subtitle, main_image, sub_images,
detail, price, stock, status, create_time, update_time
)
values (
?, ?, ?, hello phone,
?, ?, ?, ?,
?, ?,
now(),
now()
)
### SQL: insert into mmall_product ( id, category_id, name, subtitle, main_image, sub_images, detail, price, stock, status, create_time, update_time ) values ( ?, ?, ?, hello phone, ?, ?, ?, ?, ?, ?, now(), now() )
### Cause: java.sql.SQLException: sql injection violation, syntax error: syntax error. pos 237, line 9, column 26, token IDENTIFIER phone : insert into mmall_product
(
id, category_id, name, subtitle, main_image, sub_images,
detail, price, stock, status, create_time, update_time
)
values (
?, ?, ?, hello phone,
?, ?, ?, ?,
?, ?,
now(),
now()
)
; uncategorized SQLException; SQL state [null]; error code [0]; sql injection violation, syntax error: syntax error. pos 237, line 9, column 26, token IDENTIFIER phone : insert into mmall_product
(
id, category_id, name, subtitle, main_image, sub_images,
detail, price, stock, status, create_time, update_time
)
values (
?, ?, ?, hello phone,
?, ?, ?, ?,
?, ?,
now(),
now()
); nested exception is java.sql.SQLException: sql injection violation, syntax error: syntax error. pos 237, line 9, column 26, token IDENTIFIER phone : insert into mmall_product
(
id, category_id, name, subtitle, main_image, sub_images,
detail, price, stock, status, create_time, update_time
)
values (
?, ?, ?, hello phone,
?, ?, ?, ?,
?, ?,
now(),
now()
)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:89)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446)
at com.sun.proxy.$Proxy87.insert(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:278)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:58)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59)
at com.sun.proxy.$Proxy97.insertProduct(Unknown Source)
at com.isoftstone.product.mapper.ProductMapperTest.insertProduct(ProductMapperTest.java:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.sql.SQLException: sql injection violation, syntax error: syntax error. pos 237, line 9, column 26, token IDENTIFIER phone : insert into mmall_product
(
id, category_id, name, subtitle, main_image, sub_images,
detail, price, stock, status, create_time, update_time
)
values (
?, ?, ?, hello phone,
?, ?, ?, ?,
?, ?,
now(),
now()
)
at com.alibaba.druid.wall.WallFilter.checkInternal(WallFilter.java:798)
at com.alibaba.druid.wall.WallFilter.connection_prepareStatement(WallFilter.java:251)
at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:568)
at com.alibaba.druid.filter.FilterAdapter.connection_prepareStatement(FilterAdapter.java:929)
at com.alibaba.druid.filter.FilterEventAdapter.connection_prepareStatement(FilterEventAdapter.java:122)
at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:568)
at com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl.prepareStatement(ConnectionProxyImpl.java:342)
at com.alibaba.druid.pool.DruidPooledConnection.prepareStatement(DruidPooledConnection.java:349)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.instantiateStatement(PreparedStatementHandler.java:87)
at org.apache.ibatis.executor.statement.BaseStatementHandler.prepare(BaseStatementHandler.java:88)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.prepare(RoutingStatementHandler.java:59)
at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:85)
at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:49)
at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63)
at com.sun.proxy.$Proxy100.update(Unknown Source)
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198)
at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:185)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433)
... 36 more
Caused by: com.alibaba.druid.sql.parser.ParserException: syntax error. pos 237, line 9, column 26, token IDENTIFIER phone
at com.alibaba.druid.sql.parser.SQLStatementParser.parseValueClause(SQLStatementParser.java:3323)
at com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser.parseInsert(MySqlStatementParser.java:2553)
at com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser.parseInsert(MySqlStatementParser.java:47)
at com.alibaba.druid.sql.parser.SQLStatementParser.parseStatementList(SQLStatementParser.java:167)
at com.alibaba.druid.sql.parser.SQLStatementParser.parseStatementList(SQLStatementParser.java:83)
at com.alibaba.druid.wall.WallProvider.checkInternal(WallProvider.java:624)
at com.alibaba.druid.wall.WallProvider.check(WallProvider.java:578)
at com.alibaba.druid.wall.WallFilter.checkInternal(WallFilter.java:785)
... 63 more
分析:从错误信息来看是由于SQL语句有注入问题导致SQL解析失败。而导致该问题的罪魁祸首是使用了#{}和${}进行混合取值,通常情况下都是建议使用#{}进行取值,而不推荐使用${}进行取值,${}符号取值容易导致SQL注入,而在我的SQL语句中会发现我不小心将一个属性的取值使用了${}而导致SQL解析错误。
解决方案:将语句中的${}改为#{}。最终的SQL语句:
insert into mmall_product
(
)
values (
#{productId}, #{categoryId}, #{productName}, #{subtitle},
#{mainImage}, #{subImages}, #{detail}, #{productPrice},
#{stock}, #{status},
#{createTime},
now(),
#{updateTime}
now()
)