java jdbc 命名参数_让JAVA的JDBC支持命名参数的SQL语句

JAVA 的JDBC连接数据库时,传递参数的方式是通过索引位置实现(根据SQL中?号出现的顺序,例如 SELECT * FROM [table] WHERE [name] =? OR [title]=?);这让使用SQL语句变得比较麻烦也不符合使用习惯。

为此专门创建了一个类NSQL用于支持命名方式给SQL语句传递参数(例如 SELECT * FROM [table] WHERE [name] =?name OR [title]=?title)。其基本原理是,以?号为参数标识,后跟参数名称,在编写SQL语句时候采用命名参数方式,然后由NSQL类将其分析后生成JDBC可用的基于?号顺序的SQL语句,同时记录参数顺序。这样既可实现命名参数的SQL语句。

代码如下所示:

/**

* 2017年2月16日

*/

package com.kiy.service.data;

import java.sql.PreparedStatement;

import java.sql.SQLException;

import java.util.ArrayList;

import java.util.List;

import java.util.Map;

import java.util.concurrent.ConcurrentHashMap;

/**

* SQL语句抽象,提供基于命名参数的SQL语句功能

*

* @author Simon(ZhangXi)

*

*/

public final class NSQL {

// 静态集合缓存使用过的NSQL

private static Map caches = new ConcurrentHashMap();

private String sql_naming;

private String sql_execute;

private String[] names;

private NSQL() {

// 用户不能实例化对象

// 通过get方法获取可用实例

}

public boolean hasName() {

return names.length > 0;

}

public void setParameter(PreparedStatement ps, String name, Object value) throws SQLException {

for (int a = 0, b = names.length - 1; a <= b; a++, b--) {

if (names[a].equals(name)) {

ps.setObject(a + 1, value);

}

if (a != b && names[b].equals(name)) {

ps.setObject(b + 1, value);

}

}

}

public void setParameters(PreparedStatement ps, Map values) throws SQLException {

for (int index = 0; index < names.length; index++) {

ps.setObject(index + 1, values.get(names[index]));

}

}

/**

* 获取用于数据库执行的SQL语句

*

* @return

*/

public String getSql() {

return sql_execute;

}

/**

* 获取用户定义的命名SQL语句

*

* @return

*/

public String getNamingSql() {

return sql_naming;

}

/**

* 获取对象实例,此方法将缓存分析过的SQL语句以提高性能

*

* @param sql

* @return

*/

public static NSQL get(String sql) {

NSQL nsql = caches.get(sql);

if (nsql == null) {

nsql = NSQL.parse(sql);

caches.put(sql, nsql);

}

return nsql;

}

/**

* 分析命名SQL语句获取抽象NSQl实例;java(JDBC)提供SQL语句命名参数而是通过?标识参数位置,

* 通过此对象可以命名参数方式使用SQL语句,命名参数以?开始后跟名称?name。

* 例如:SELECT * FROM table WHERE name = ?key AND email = ?key;

*

* @param sql

* @return

*/

public static NSQL parse(String sql) {

// SELECT * FROM table WHERE name = ?key AND email = ?key;

// A~Z a~z 01~9 _

if (sql == null)

throw new NullPointerException("SQL String is null");

char c;

List names = new ArrayList();

StringBuilder sql_builder = new StringBuilder();

StringBuilder name_builder = new StringBuilder();

for (int index = 0; index < sql.length(); index++) {

c = sql.charAt(index);

sql_builder.append(c);

if ('?' == c) {

while (++index < sql.length()) {

c = sql.charAt(index);

if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= '0' && c <= '9')) {

name_builder.append(c);

} else {

sql_builder.append(c);

break;

}

}

names.add(name_builder.toString());

name_builder.setLength(0);

}

}

NSQL dbsql = new NSQL();

dbsql.sql_naming = sql;

dbsql.sql_execute = sql_builder.toString();

dbsql.names = names.toArray(dbsql.names = new String[names.size()]);

return dbsql;

}

public String toString() {

return "NAMING: " + sql_naming + "\nEXECUTE: " + sql_execute;

}

}

NSQL类的使用如下所示:

public boolean CreateUser(User u) {

NSQL sql1 = NSQL.get("INSERT INTO `users` (`id`,`name`,`password`,`enable`,`realname`,`mobile`,`phone`,`email`,`remark`,`created`,`updated`) VALUES (?id,?name,?password,?enable,?realname,?mobile,?phone,?email,?remark,?created,?created)");

Connection connection = dbc.get();

try (PreparedStatement s1 = connection.prepareStatement(sql1.getSql())) {

sql1.setParameter(s1, "id", u.getId());

sql1.setParameter(s1, "name", u.getName());

sql1.setParameter(s1, "password", u.getPassword());

sql1.setParameter(s1, "enable", u.getEnable());

sql1.setParameter(s1, "realname", u.getRealname());

sql1.setParameter(s1, "mobile", u.getMobile());

sql1.setParameter(s1, "phone", u.getPhone());

sql1.setParameter(s1, "email", u.getEmail());

sql1.setParameter(s1, "remark", u.getRemark());

sql1.setParameter(s1, "created", u.getCreated());

return s1.executeUpdate() == 1;

} catch (SQLException ex) {

Log.error(ex);

return false;

} finally {

dbc.put(connection);

}

如此即可通过命名方式使用SQL语句了,欢迎大家多多交流。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值