Jodd DB上手指南

13 篇文章 0 订阅

传统的jdbc样板代码太多。现在提供对jdbc简化的轻量级工具或框架也不少,Spring JDBC Template,jodd db,commons-dbutils,...。我只用过这几个,可能还有更多.这里不谈论orm与jdbc的优劣.为什么要简介这个呢?因为jodd足够轻量并且对官方的api提供了更贴近工作的封闭.适度而灵活.本文只谈一些让您快速上手的api简述


jodd.db.DbManager
通过DBManager可以获取到的关键对象:ConnectionProvider,DbSessionProvider,DbTransactionMode.下面会一一谈到


其实常写jdbc的同仁对上面几个词(Connection,Session,Transaction)并不陌生,我们来一起看看JDBC的代码需要的步骤
1.获取Connection
2.创建一个Statement
3.如果是查询可能会到ResultSet


来一起看一看jodd db是怎样简化的
1:获取Connection / ConnectionProvider
通过DbManager.getConnectionProvider() 或者 ConnectionProvider接口的实现类
ConnectionPoolDataSourceConnectionProvider, 
CoreConnectionPool, 
DataSourceConnectionProvider, 
DriverManagerConnectionProvider, 
XADataSourceConnectionProvider


相关对象:DbSession
和hibernate中的session意思一样,对事务的设置或调用都是在此对象上进行
创建方式:
方式1:DbManager.getSessionProvider() .getDbSession()
方式2:new DbSession(ConnectionProvider类实例构造)


到此为止,为下一步工作需要的对象都介绍到了.看一看代码吧:

	public static DbSession getJNDIInstance(){
		return new DbThreadSession(new DataSourceConnectionProvider(config.getConfig("jndi")));
	}
	
	public static DbSession getInstance(){
		if(config.getConfig("debug").equals("1")) return getJNDIInstance();
		
		String dc=config.getDbConfig().getDriver();//"com.mysql.jdbc.Driver";
		String url=config.getDbConfig().getUrl();//"jdbc:mysql://localhost:3306/iqido";
		String un=config.getDbConfig().getUsername();//"root";
		String up=config.getDbConfig().getPassword();//"root";
		return new DbThreadSession(new DriverManagerConnectionProvider(dc,url,un,up));
	}

2.创建一个Statement / DbQuery[DbOomQuery]
DbQuery是DbOomQuery的父类,DbOomQuery对查询进行一些处理,在后面提到注解时会提到,也可以实现jodd.db.QueryMapper<T>来封装查询的jdbc样板代码,spring jdbc也有这一概念.


创建一个DbQuery对象需要参数.
DbQuery(DbSession session, java.lang.String sqlString) 
DbOomQuery(DbSession session, java.lang.String sqlString) 
还有两个其它的构造函数

		String SQL="SELECT 列 FROM 表名 WHERE 条件";
		DbSession session = ConnectionInstance.getInstance();
		
		DbOomQuery q=new DbOomQuery(session,SQL);

3.如果是查询可能会到ResultSet / QueryMapper<T>
传统的jdbc在涉及ResultSet时有大量的代码.我们前后对比一下

			rs=ps.executeQuery();
			while(rs!=null && rs.next()){
				p=new Provide();
				p.setDomain(rs.getString("domain"));
				p.setHost(rs.getString("host"));
				p.setName(rs.getString("name"));
				p.setChannels(rs.getInt("channels"));
			}

QueryMapper<T>就是把while中的代码封装到它的唯一方法中:
public <T> process(ResultSet rs) throws SQLException {}

	class ProvideMapper implements QueryMapper<Provide>{

		@Override
		public Provide process(ResultSet rs) throws SQLException {
			// TODO Auto-generated method stub
			Provide p=new Provide();
			p.setPid(rs.getInt("pid"));
			p.setDomain(rs.getString("domain"));
			p.setName(rs.getString("name"));
			p.setHost(rs.getString("host"));
			p.setChannels(rs.getInt("channels"));
			return p;
		}
	}


DbOomQuery在此时用下列方法可以简化jdbc查询时的样板代码
<T> T                find(QueryMapper<T> queryMapper)
<T> java.util.List<T> list(QueryMapper<T> queryMapper)
<T> java.util.Set<T> listSet(QueryMapper<T> queryMapper)

	@Override
	public Provide getProvide(int pid) {
		// TODO Auto-generated method stub
		String SQL="SELECT pid,domain,name,host,channels FROM king_provide WHERE pid=?";
		Provide p=null;
		DbSession session = ConnectionInstance.getInstance();
		
		DbOomQuery q = new DbOomQuery(session,SQL);
		q.forcePreparedStatement();
		q.setInteger(1, pid);
		p=q.find(new ProvideMapper());
		
		ConnectionInstance.closeInstance(q,session);
		return p;
	}

当然写个QueryMapper接口实现类还是觉得麻烦,这时可以使用jodd db注解

类级用:@DbTable,如果类名与表名不一样,可以用value指定表名:

@DbTable(value="king_provide")
public class Provide {}

属性用:@DbColumn,如果属性与表的列名不一样,可以用value指定列名

主键用:@DbId,如果属性与表的列名不一样,可以用value指定列名

注解接口在:jodd.db.oom.meta包中

@DbTable(value="king_provide")
public class Provide {
	@DbId
	int pid;
	/**
	 * 域名
	 */
	@DbColumn
	String domain;
	/**
	 * 名称
	 */
	@DbColumn
	String name;
	/**
	 * 主机
	 */
	@DbColumn
	String host;
	/**
	 * 频道数量
	 */
	@DbColumn
	int channels;
}

注解后,哪么就不需用QueryMapper接口实现类了,直接使用
<T> T                find(java.lang.Class... types) 
<T> java.util.List<T> list(java.lang.Class... types) 
<T> java.util.Set<T> listSet(java.lang.Class... types)

	@Override
	public Provide getProvide(int pid) {
		// TODO Auto-generated method stub
		String SQL="SELECT pid,domain,name,host,channels FROM king_provide WHERE pid=?";
		Provide p=null;
		DbSession session = ConnectionInstance.getInstance();
		
		DbOomQuery q = new DbOomQuery(session,SQL);
		q.forcePreparedStatement();
		q.setInteger(1, pid);
		p=q.find(Provide.class);
		ConnectionInstance.closeInstance(q,session);
		return p;
	}


写在最后:
1.如果提示事务是只读,可以用DbTransactionMode.setReadOnly(DbTransactionMode.READ_WRITE ) 
  事务的开启,提交,回滚跟jdbc差不多
  
2.生成主键,jdbc用
ps=conn.prepareStatement(SQL,new String[]{"pid"});
//...
rs=ps.getGeneratedKeys();


jodd示例

		DbOomQuery q = new DbOomQuery(session,SQL);
		q.setGeneratedColumns("pid");
		//...
		ResultSet rs = q.getGeneratedColumns();

或者

		DbOomQuery q = new DbOomQuery(session,SQL);
		q.setGeneratedColumns("pid");
		//...
		long id = q.getGeneratedKey();


3.jodd db也支持SQL的模板参数.官方提供的示例中有

@PetiteBean
public class AppService {

	@Transaction
	public List<Message> findLastMessages(int count) {
		DbSqlBuilder dbsql =
			sql("select $C{m.*} from $T{Message m} " +
				"order by $m.messageId desc limit :count");
		DbOomQuery dbquery = query(dbsql);
		dbquery.setInteger("count", count);

		return dbquery.list(Message.class);
	}
	//...
}


4.PreparedStatement中的参数设置方法还是原来的用法.setXXX(),getXXX()


5.关于批量sql

jdbc:

  void addBatch(String sql)throws SQLException
  int[] executeBatch()
  
 jodd db截止到3.6还没有提供类spring jdbcTemplate中的批量操作.所以只能从session中获得 connection,由jdbc来实现,它提供的

  JbQuery.public void setBatch(java.lang.String name,java.lang.Object[] array,int startingIndex)

只是生成sql的占位符数量

  
6.更多的说明文档请访问: http://jodd.org/doc/db/index.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值