- 浏览: 2046168 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (795)
- java (263)
- 聚类搜索引擎 (9)
- 经验之谈 (67)
- DSP (3)
- C++ (140)
- Linux (37)
- SNMP (6)
- Python (6)
- 数据库 (61)
- 网络 (20)
- 算法 (15)
- 设计模式 (4)
- 笔试题 (38)
- 散文 (35)
- 数据结构 (9)
- 银行知识 (0)
- 榜样 (9)
- Lucene (15)
- Heritrix (6)
- MetaSeeker (0)
- netbeans (12)
- php (3)
- 英语 (8)
- DB2 (0)
- java基础 (5)
- mongodb & hadoop (4)
- Javascript (7)
- Spring (4)
- ibatis & myibatis (1)
- velocity (1)
- 微服务 (0)
- paddle (1)
- 第三方 (0)
- 知识沉淀 (1)
- 建模 (0)
最新评论
-
0372:
标示对java很陌生!
中文乱码解决的4种方式 -
梦留心痕:
Java中\是转意字符, 可是你的这句话我没看懂,只要把得到的 ...
java中如何忽略字符串中的转义字符--转载 -
yanjianpengit:
[b][/b]
java为什么非静态内部类里面不能有静态成员 -
springdata-jpa:
可以参考最新的文档:如何在eclipse jee中检出项目并转 ...
eclipse 如何把java项目转成web项目 -
qq1130127172:
,非常好。
(转)SpringMVC 基于注解的Controller @RequestMapping @RequestParam..
两、三年前说过要坚持写文剖析各种算法、面向对象、框架、架构及各种应用技术,然进展缓慢,一者力有不逮,二者工作变动,无暇它顾。如今咬牙还债,算给自己个交代。这次就从最常用的DAO开始吧, J2EE应用开发中,数据库的使用非常频繁,大多公司里所使用的Framework都有对数据库操作进行封装的被称为DAO层的部分。下面,我结合自己在不同时期所参与的项目,就各种DAO层的封装方式进行一下比照。 在execQuery(String sql)中,做了3件事: 省却了婆婆妈妈的RecordSet, Statement的声明和繁琐重复的异常捕获。把查询结果放进缓存,不用一直维持着数据库的连接,可以减少数据库的数据连接压力。 基本上式是直接使用hibernate进行DAO层操作,未对hibernate进行二次封装; 这段代码会读取hibernate配置文件(hibernate.cfg.xml ), hibernate配置文件中有数据库连接信息,对象与数据库之间的映射文件的地址; 其实就是hibernate的优缺点。这个大家可以参考已经非常丰富的hibernate 资料;从审美角度上看,hibernate使数据存取代码简洁、清晰。而简洁清晰的代码总是更容易使用。 在下一个紧接着的项目中,有的模块对hibernate又进行了一层简单的封装,这样做的目的是为了使之扩展性更强。但实际上这也同时使得代码复杂度增加。这中间的平衡取舍往往不单单是技术问题。 下面我们这里举两种封装例子。 从这个UML中,我们可以看出它的思路,就是尘归尘、土归土,就是user的业务处理归UserManager,user的数据处理归UserManagerDAO.两者互不干扰。假如现在需求有变,数据被要求存在文件里而非数据库中,要做哪些工作呢? 可以看出,已有代码中修改了2处。这正是简单工厂模式的特点。 它减少了Manager这一层,而让用户直接使用DAO.它使用的模式是工厂模式。假如需求也有变,要求把数据存进文件里而非数据库中,要做哪些工作呢? 我们可以看出,这里对已有代码修改了一处。大家都知道OCP原则,即对扩展开放,对修改关闭。其本质就是对于已经存在的代码尽量不去动就能实现新的功能(扩展),其完全实现必然伴随形成热插拔的能力。 这里,仍然对已有代码做了一处修改,必然还需要重新编译。如果把实例化的控制开关放进配置文件中又配置人员来设定,就可以不需要再修改代码再编译,则基本可以看做可热插拔了。 补充一点,所有项目的业务含义就不说了。因为那样做不好。 架构采用 struts+spring+ibatis 组合。 请求被Action接收后, Action–>Logic–>Dao–>Ibatis. 符号"–>"代表调用. 关键的地方在于,所有的调用都是通过Spring的依赖注入实现,而不用程序员去写被调用对象的创建代码(比如写一个工厂类用来创建对象)。省了好多事哦。 Struts是最著名的MVC Framework,它的实现实质就是用一个Servlet统一接收请求,然后根据配置文件分发给不同的action,程序员在action中再调用自己的逻辑模块,处理完后,struts又根据配置文件把结果转发到相应的页面。这就完成了MVC的一个全过程。它是这么著名,以至于到处都是它的资料。所以欲知其详,请google. Ibatis是半自动化数据封装方案。它的实现实质就是通过读取写在配置文件中的SQL语句自动生成数据对象. Spring则发展的最火,因为它的确最棒。但要说它的实现实质,则也是通过读取含有class信息的配置文件,动态的生成类对象。多个class的依赖关系也写在配置文件中,Spring读取依赖关系、进行对象的构造,这就是依赖注入。 捎带提一句,要感谢夏昕为Spring的普及所做的贡献。正是2004年夏昕的 Spring Guide加速了Spring在众多的程序员中的普及进程。 配置文件的例子如下: 这个配置文件中,Department类引用了User类(Spring会自动根据引用构建依赖关系,也可以手工指定依赖关系)。Spring读这些文件,然后通过反射就可以构造出user对象与Department对象。然后再在此基础上发展演化,变成了今天的Spring. 它的基本原理简单,但为什么这样的framework总是被老外开发出来呢?不是中国程序员笨,可能要从历史和大环境找原因吧。 不说闲话,回归正题。这个项目采用了struts+spring+ibatis做架构,我们就来看一下它的使用方式。 这里用一个简单过程来说明。比如用户输入用户名和密码进行Logon,系统校验用户名密码是不是正确。(这是个演示例子,所以后面的代码一切从简)。 用户点击登陆,请求被struts送到了Logonaction,如下: userHandle实例是通过容器(ApplicationContext)获取的,不需要自己写创建对象的代码了。容器实际上是通过读取配置文件加载UserHandle类的,而这个过程对于程序员是透明的。 然后我们再分析下面这一句: userHanle类的通常实现方法可能是这样, 然后就可以想象UserDAO里就是数据库连接,发送SQL的那一套。这样做,程序员就不得不写一个 DBOperator类,用来创建DAO. 而Spring就是用来解放这样的创建工作的,这样 DBOperator这样的类就没必要程序员劳神去写了,只需要这样做: Spring 会根据配置文件中的类的依赖关系,自动的把UserDAO对象注入到 UserHandle对象里,然后程序员去使用userDao就可以了。 既然是根据配置文件来注入的,那么配置文件是什么样子呢?如下: 从这个配置文件里我们可以看到它们的引用关系是:1–>2–>3–>4,即 UserHandle引用UserDAO, UserDAO引用 SqlMapClientFactoryBean, SqlMapClientFactoryBean引用 JndiObjectFactoryBean,JndiObjectFactoryBean负责根据jndiName获得 datasource. 通过这样层层引用的配置,spring就能自动生成对象,不但免了程序员手动写对象生成的代码,还很容易的把ibatis串连起来。 前面我们已经根据代码和配置文件知道了UserHandle是怎么引用和注入 UserDAO的方式,现在我们再看UserDAO是怎么引用 SqlMapClientFactoryBean 这个第三方类的. 根据UserHandle引用UserDAO的方式,我们也应该猜到UserDAO引用 SqlMapClientFactoryBean时应该大致是这样: 但实际上,第三方类已经把set get这样的方法封装好了,你只需要继承第三方类就可以了,如这样: 这样就不用手工写那些set get方法了。原理也不难理解,那些set 和 get方法无非被挪进了SqlMapClientDaoSupport这个Spring提供的第三方类里面而已,我们可以看它的源码片段: 果然看到了getSqlMapClient()和setSqlMapClient()方法。我们仍然根据 UserHandle和UserDAO的注入方式,可以知道UserHandle的属性userDao其实就是UserDAO类的实例注入。同样,配置文件中UserDAO的属性sqlMapClient 也应该是SqlMapClientFactoryBean类的实例注入才对。但 SqlMapClientFactoryBean并不是SqlMapClient类型,这怎么能注入呢? 这是因为Spring的机制的缘故。简单的说,如果一个bean实现了 FactoryBean接口,那么Spring就不会把该bean本身实例化并返回,而是返回该bean的getObject()返回的对象。这是Sprign的游戏规则。我们来看一眼 SqlMapClientFactoryBean的源码片段: Spring这种机制的官方说明: 到此为止,我们已经知道UserDAO与SqlMapClient的关系,接下来看如何使用IBatis Ibatis是半自动化数据对象封装方案。我们看userDao怎么使用Ibatis 结合者段代码以及前面的配置文件的第三段,相信你已经大体明白了Ibatis的使用。这里就做一简单描述。先重新看一下配置文件的第三段: 注意这里有一个sql-map-config.xml文件。这个文件的内容如下: 再看user.xml文件里是什么? 现在,结合UserDAO类,和三个xml文件,应该容易知道它的原理: 逻辑层调用userDAO,userDAO通过Spring的粘合会去调用 Ibatis,Ibatis读取sql-map-config.xml文件,然后顺藤摸瓜,再读取user.xml文件,从中找到id="userid"的map,传递userid 给#userid#,得到完整的sql,执行sql,返回结果。详细的Ibatis的使用请参考相关手册。 Spring DAO是Spring对JDBC的封装。主要利用Template模式实现。先看看它的用法: Template模式配合回调的使用是JdbcTemplate的主要实现方式,下面是它的源码片段: 不用回调,如果用顺调,会是怎样的? 以下是模拟代码: 这样做简单,但两个函数耦合强,execute方法的返回类型与参数都规定的太死,限制了execute方法的使用范围。比如,如下的代码就不容易去使用execute方法: 但如果是接口回调方式,则灵活得多 可以看出,下面的这个方法可满足不同的需要 而下面这种方法相对死板(但也简单了不少) 模板模式请参考:http://hi.baidu.com/dapplehou/blog/item/0830c3ce9ccd4a0f93457e6d.html 相信很容易明白Spring是如何把那些关闭连接的琐事用模板模式封装起来的。 无论由于性能原因对数据库拆分,还是本身就是分布式数据库,都涉及到对多个数据库的操作。这要求程序能动态定位所需数据库,实际上就是在多个数据源中动态定位一个。 可采用把定位库的策略封装进一个中间层来屏蔽程序对于多库的敏感。一般采用Proxy模式封装这种DB路由(即:定位)逻辑。Spring又显身手,它对多库也提供了方案: 相应的配置文件如下: 当然,也可以不集成 AbstractRoutingDataSource . 而是实现DataSource接口,代码片段如下: 实际上,AbstractRoutingDataSource 就是DataSource接口的一个实现,继承 AbstractRoutingDataSource,比自己实现DataSource要少很多工作量,因为 AbstractRoutingDataSource都帮你做了。AbstractRoutingDataSource内部的数据库路由原理和上面的代码一样。 时间有限,先写到这里吧。关于DAO还有太多的东西可以写,还有深的内容可以挖掘,这些内容完全可以写本大厚书。这里主要是从一个Framework的角度来分析了一下大致的用法和实现思路。Table of Contents
1 言前
2 项目1 (久远,尚无SSH流行)
2.1 使用方式
- String dataSourceName 数据源名称(JNDI).
- boolean autoReleaseConnection 是否自动释放链接.
- boolean useStoreProcedure 是否使用存储过程.UserDAO userDAO = new UserDAO(null,false,false);
List allUser = userDAO.getAllUser();
2.2 原理
DataSet ds = execQuery(querySQL);
2.4 优点
2.5 缺点
3 项目2
3.1 使用方式(步骤)
IndexDAO dao = new IndexDAO();
DataSet dataset=this.getDataSet(request);
dao.addData(dataset,user);
ds.set("userstatus", "0");
ds.tablename = "T_Pop_User";dboperator.insertData(ds);
3.2 原理
3.4 优点:
3.5 缺点
4 项目3(大约04年,hibernate)
4.1 使用方式
User user = new User();
user.setID(23);
user.setName("Dapple");
UserManager.updateUser(user);Session s = SessionManager.getSession();
s.update(buyer);
4.2 原理( session 的获取方式 )
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session s = sessionFactory.openSession();
4.4 优缺点
4.5 两个对hibernate使用的例子
5 项目4 (struts+spring+ibatis)
5.1 架构说明
<bean id="user" class="test.User">
<property name="name"><value>张三</value></property>
<property name="age"><value>20</value></property>
</bean>
<bean id="department" class="test.Department">
<property name="user"><ref bean="user"/></property>
</bean>
5.2 使用方式及其原理
protected ActionForward doExecute(ActionMapping mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception{
String name = request.getParameter("name");
String password = request.getParameter("password");
ServletContext sc = request.getSession().getServletContext();
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(ServletContext sc);
UserHandle userHandle = (UserHandle)ctx.getBean("userhandle"); //获取userhanle实例
boolean isSuccess = userHandle.check(name,password);
if(isSuccess){
return mapping.findForward("success");
}else{
return mapping.findForward("failed");
}
}boolean isSuccess = userHandle.check(name,password);
class UserHandle{
public boolean check(String name,String password){
UserDAO userDao = DBOperator.getUserDAO(); //你自己的DB操作的封装类
return userDao.check(name,password);
}
}class UserHandle{
private UserDAO userDao;
public boolean check(String name,String password){
return userDao.check(name,password);
}
public void setUserDao(UserDAO userDao){
this.userDao = userDao;
}
public UserDAO getUserDao(){
return this.userDao;
}
}<beans>
<!--4-->
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>efmweb</value></property>
</bean>
<!--3-->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean" >
<property name="configLocation"><value>WEB-INF/sql-map-config.xml</value></property>
<property name="dataSource"><ref local="dataSource"/></property>
</bean>
<!--2-->
<bean id="userdao" class="UserDAO">
<property name="sqlMapClient"><ref bean="sqlMapClient"/></property>
</bean>
<!--1-->
<bean id="userhandle" class="UserHandle">
<property name="userDao"><ref bean="userdao" /></property>
</bean>
</beans>
5.2.1 UserDAO的实现以及如何使用第三方SqlMapClient.
class UserDAO{
private SqlMapClientFactoryBean sqlMapClient;
public void setSqlMapClient(SqlMapClientFactoryBean sqlMapClient){
this.sqlMapClient = sqlMapClient;
}
public SqlMapClientFactoryBean getSqlMapClient(){
return this.sqlMapClient;
}
...;//你自己定义的其它业务相关userDao逻辑;
}class UserDAO extends SqlMapClientDaoSupport{
...;//你自己定义的其它业务相关userDao逻辑;
}public abstract class SqlMapClientDaoSupport extends DaoSupport {
private SqlMapClientTemplate sqlMapClientTemplate = new SqlMapClientTemplate();
private boolean externalTemplate = false;
/**
* Set the JDBC DataSource to be used by this DAO.
* Not required: The SqlMapClient might carry a shared DataSource.
* @see #setSqlMapClient
*/
public final void setDataSource(DataSource dataSource) {
if (!this.externalTemplate) {
this.sqlMapClientTemplate.setDataSource(dataSource);
}
}
/**
* Return the JDBC DataSource used by this DAO.
*/
public final DataSource getDataSource() {
return this.sqlMapClientTemplate.getDataSource();
}
/**
* Set the iBATIS Database Layer SqlMapClient to work with.
* Either this or a "sqlMapClientTemplate" is required.
* @see #setSqlMapClientTemplate
*/
public final void setSqlMapClient(SqlMapClient sqlMapClient) {
if (!this.externalTemplate) {
this.sqlMapClientTemplate.setSqlMapClient(sqlMapClient);
}
}
/**
* Return the iBATIS Database Layer SqlMapClient that this template works with.
*/
public final SqlMapClient getSqlMapClient() {
return this.sqlMapClientTemplate.getSqlMapClient();
}
/**
* Return the SqlMapClientTemplate for this DAO,
* pre-initialized with the SqlMapClient or set explicitly.
*/
public final SqlMapClientTemplate getSqlMapClientTemplate() {
return this.sqlMapClientTemplate;
}
}
5.2.2 为什么SqlMapClientFactoryBean与SqlMapClient类型不同也可被注入?
public class SqlMapClientFactoryBean implements FactoryBean,InitializingBean {
private SqlMapClient sqlMapClient;
protected SqlMapClient buildSqlMapClient(Resource configLocation,Properties properties) throws IOException {
InputStream is = configLocation.getInputStream();
if (properties != null) {
if (buildSqlMapClientWithInputStreamAndPropertiesMethodAvailable) {
return SqlMapClientBuilder.buildSqlMapClient(is,properties);
} else {
return SqlMapClientBuilder.buildSqlMapClient(new InputStreamReader(is), properties);
}
} else {
if (buildSqlMapClientWithInputStreamMethodAvailable) {
return SqlMapClientBuilder.buildSqlMapClient(is);
} else {
return SqlMapClientBuilder.buildSqlMapClient(new InputStreamReader(is));
}
}
}
//这里就是返回的、并会被注入到其它类里的对象
public Object getObject() {
return this.sqlMapClient;
}
}public interface FactoryBean
Interface to be implemented by objects used within a BeanFactory which are themselves factories. If a bean implements
this interface, it is used as a factory for an object to expose, not directly as a bean instance that will be exposed
itself.
NB: A bean that implements this interface cannot be used as a normal bean. A FactoryBean is defined in a bean style, but
the object exposed for bean references (getObject() is always the object that it creates.
FactoryBeans can support singletons and prototypes, and can either create objects lazily on demand or eagerly on
startup. The SmartFactoryBean interface allows for exposing more fine-grained behavioral metadata.
This interface is heavily used within the framework itself, for example for the AOP ProxyFactoryBean or the
JndiObjectFactoryBean. It can be used for application components as well; however, this is not common outside of
infrastructure code.
NOTE: FactoryBean objects participate in the containing BeanFactory's synchronization of bean creation. There is usually
no need for internal synchronization other than for purposes of lazy initialization within the FactoryBean itself (or
the like).
Since:
08.03.2003
Author:
Rod Johnson, Juergen Hoeller
See Also:
BeanFactory, ProxyFactoryBean, JndiObjectFactoryBean
5.2.3 如何使用IBatis
class UserDAO{
private SqlMapClientFactoryBean sqlMapClient;
public void setSqlMapClient(SqlMapClientFactoryBean sqlMapClient){
this.sqlMapClient = sqlMapClient;
}
public SqlMapClientFactoryBean getSqlMapClient(){
return this.sqlMapClient;
}
//这里是使用Ibatis的地方
public User getUser(String userid) {
return super.getSqlMapClientTemplate().queryForList("userid",
userid);
}
}<!--3-->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean" >
<property name="configLocation"><value>WEB-INF/sql-map-config.xml</value></property>
<property name="dataSource"><ref local="dataSource"/></property>
</bean><sqlMapConfig>
<sqlMap resource="user.xml"/>
</sqlMapConfig><sqlMap>
<select id="userid" resultclass="UserDAO" parameterClass="java.lang.String">
select * from user where userid=#userid#
</select>
</sqlMap>
6 Spring DAO
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.update("Update user set name='Jeff' where id=10");public int update(final String sql) throws DataAccessException {
Assert.notNull(sql, "SQL must not be null");
if (logger.isDebugEnabled()) {
logger.debug("Executing SQL update [" + sql + "]");
}
class UpdateStatementCallback implements StatementCallback,
SqlProvider {
public Object doInStatement(Statement stmt) //<------- 这个函数将被下面的方法回调
throws SQLException {
int rows = stmt.executeUpdate(sql);
if (logger.isDebugEnabled()) {
logger.debug("SQL update affected " + rows
+ " rows");
}
return new Integer(rows);
}
public String getSql() {
return sql;
}
}
return ((Integer) execute(new UpdateStatementCallback()))
.intValue();
}
public Object execute(StatementCallback action) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
Connection con = DataSourceUtils.getConnection(getDataSource());
Statement stmt = null;
try {
Connection conToUse = con;
if (this .nativeJdbcExtractor != null
&& this .nativeJdbcExtractor
.isNativeConnectionNecessaryForNativeStatements()) {
conToUse = this .nativeJdbcExtractor
.getNativeConnection(con);
}
stmt = conToUse.createStatement();
applyStatementSettings(stmt);
Statement stmtToUse = stmt;
if (this .nativeJdbcExtractor != null) {
stmtToUse = this .nativeJdbcExtractor
.getNativeStatement(stmt);
}
Object result = action.doInStatement(stmtToUse); //<------- 这里是回调的地方
handleWarnings(stmt.getWarnings());
return result;
} catch (SQLException ex) {
// Release Connection early, to avoid potential connection pool deadlock
// in the case when the exception translator hasn't been initialized yet.
JdbcUtils.closeStatement(stmt);
stmt = null;
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw getExceptionTranslator().translate(
"StatementCallback", getSql(action), ex);
} finally {
JdbcUtils.closeStatement(stmt);
DataSourceUtils.releaseConnection(con, getDataSource());
}
}public int update(final String sql) throws DataAccessException {
return execute(sql);
}
public int execute(String sql) throws DataAccessException {
Connection con = DataSourceUtils.getConnection();
Statement stmt = null;
stmt = con.createStatement();
int rows = stmt.executeUpdate(sql);
return rows;
//数据库连接关闭等代码略
}public User getUser(int id){
//无法使用int execute(String sql) 函数,因为它只返回一个int,不是想要的。
}public User getUser(int id) throws DataAccessException {
class UpdateStatementCallback implements StatementCallback {
public Object doInStatement(Statement stmt) //<------- 这个函数将被下面的方法回调
throws SQLException {
String sql = "select * from User where id ="+id;
ResultSet rs = stmt.executeUpdate(sql);
//下面略的部分是把rs取回的数据封装进User对象里。
//...略;
User user = getUser(rs);
return user;
}
}
return execute(new UpdateStatementCallback());
}public Object execute(StatementCallback action) throws DataAccessException
public int execute(String sql) throws DataAccessException
7 多库/多数据源
public class DynamicDataSource extends AbstractRoutingDataSource {//1. 继承AbstractRoutingDataSource
static Logger log = Logger.getLogger("DynamicDataSource");
protected Object determineCurrentLookupKey() {
...................; //2. 你的路由逻辑
return dataSourceId; //3. 返回你要使用的datasourceId
}
}<bean id="dataSource0" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>db1</value></property>
</bean>
<bean id="dataSource1" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>db1</value></property>
</bean>
<bean id="dataSource2" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>db1</value></property>
</bean>
<bean id="dataSource" class="xxx.xxx.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.Integer">
<entry key="0" value-ref="dataSource0"/>
<entry key="1" value-ref="dataSource1"/>
<entry key="2" value-ref="dataSource2"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSource0"/>
</bean>
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="classpath:com/bitfone/smartdm/dao/sqlmap/sql-map-config.xml"/>
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="UserInfoDAO" class="com.bitfone.smartdm.dao.impl.UserInfoDAO">
<property name="sqlMapClient" ref="sqlMapClient"/>
</bean>public class DynamicDataSource implements DataSource{
private static String dsDefault;
private Map dataSources;
public void setDsDefault(String dsDefault)
{
this.dsDefault = dsDefault;
}
public Connection getConnection() throws SQLException
{
DataSource targetDS = getDataSource();
return targetDS.getConnection();
}
public DataSource getDataSource()
{
..........
..........//你的路由逻辑
String dbName = ?;
DataSource ds = (DataSource)dataSources.get(dbName);
return ds;
}
......
}
8 结束
发表评论
-
流式计算
2022-02-07 14:31 279private void postHandle(List& ... -
消息队列使用的四种场景介绍
2018-08-09 16:34 2471以下介绍消息队列在实际应用中常用的使用场 ... -
设计模式
2018-04-11 16:49 9801.桥梁模式,将抽象部分与实现部分隔离开,抽象部分持有实现 ... -
Spring boot web可以访问Service和Mapper层
2018-03-26 16:42 2861Spring boot的web层可以访问Service层,然 ... -
FreeMarker的基础语法使用 && 心得和技巧
2018-01-10 10:03 2053FreeMarker是一个模板引 ... -
webService----wss4j+cxf实现WS-Security(基于UsernameToken)
2017-10-23 18:58 1554分享一下wss4j+cxf基于UsernameToken的安 ... -
Spring MVC之LocaleResolver(解析用户区域)
2017-09-23 15:55 2517为了让web应用程序支持国际化,必须识别每个用户的首选区域, ... -
(转)java泛型
2016-11-12 20:29 1646http://www.cnblogs.com/lwbqqyu ... -
java中如何忽略字符串中的转义字符--转载
2016-06-28 16:42 9899原文地址:http://my ... -
(转)关于JAP FetchType.LAZY(hibernate实现)的理解 .
2016-04-27 15:22 5104JPA定义实体之间的关系有如下几种: @OneToOne ... -
(转)hibernate annotation注解方式来处理映射关系
2016-04-26 16:52 1836http://www.cnblogs.com/xiao ... -
代码片段,导出的文件头
2015-11-18 20:34 1600public static void setDownload ... -
(转)为什么要两次调用encodeURI来解决乱码问题
2015-08-03 20:19 2481地址:http://blog.csdn.net/howla ... -
杀死进程
2015-07-21 14:54 1285sudo lsof -i :9000 COMMAND P ... -
批处理batch,执行多个SQL语句
2015-07-15 19:21 10609批处理batch,执行多个SQL语句。 ... -
中文乱码解决的4种方式
2015-07-03 14:20 2627目前收集到4中方法,中文传参一documentPath为例: ... -
GET请求的中文乱码问题及处理意义
2015-07-03 13:47 6631首先看一段乱码的程序 ... -
java.ByteArrayInputStream与ByteArrayOutputStream再次理解
2015-03-16 17:59 3235第一次看到ByteArrayOutputStream的时 ... -
(转)SpringMVC 基于注解的Controller @RequestMapping @RequestParam..
2014-07-28 17:42 2272概述 继 Spring 2.0 对 Spring MVC ... -
java中序列化的serialVersionUID解释
2014-07-25 09:26 1883serialVersionUID: 字面意思上是序列化的版本号 ...
相关推荐
标题中的“论坛转帖工具.rar”表明这是一个用于在论坛之间转移帖子的软件工具,通常用于帮助用户方便地将一个论坛的帖子内容复制到另一个论坛,可能是为了分享信息、讨论或保存重要的帖子。这类工具可能包括自动抓取...
Oracle分析函数是数据库查询中的一个强大工具,它们在处理数据集时提供了高级的聚合功能,可以对一组行进行计算,并返回单个值或一组值。分析函数与聚合函数(如SUM, AVG, COUNT等)类似,但有显著的区别:聚合函数...
总之,编辑人员转帖去水印工具如Teorex Inpaint,为图像编辑提供了便利,通过其独特的算法和技术,我们可以高效地去除图片中的水印,提高内容的质量。但在使用过程中,务必遵守版权法和相关法律法规,以维护良好的...
- **DAO层**:数据访问对象层,处理与数据库的交互,通过SessionFactory获取Session,进行CRUD操作。 在MyEclipse8.0中,开发人员可以享受到IDE提供的便利,如代码提示、自动构建路径、调试支持等,大大提高了开发...
UBB论坛转帖圣手.exeUBB论坛转帖圣手.exe
标题中的“如何在不同的浏览器中打开控制台调试JS”是一个关于网页开发中JavaScript调试的关键话题。在现代Web开发中,浏览器的开发者工具是必不可少的工具,尤其是JavaScript控制台,它可以帮助开发者追踪错误、...
【贴吧转帖工具】是一种专为百度贴吧用户设计的便捷工具,主要用于提高用户在贴吧中的互动效率。通过这款工具,用户可以实现一键转帖和一键8经验签到的功能,极大地简化了传统操作流程,节省了用户的时间,提升了...
3. 数据分析:通过批量发布和转帖,可以进行用户行为分析,了解哪种类型的内容更受论坛用户欢迎。 综上所述,“Discuz! X2转帖工具、采集工具”是提升Discuz! X2论坛运营效率的有效辅助手段,但使用时需谨慎,确保...
在TI论坛看到的帖子,感觉挺好,就整理成word文档了,内容主要是运放datasheet常见参数的解释和分析。TI原帖地址“http://www.deyisupport.com/question_answer/analog/amplifiers/f/52/t/20214.aspx”。感谢原作者...
本文将深入探讨“一键转帖功能插件”在帝国CMS 6.0系统中的应用与实现,该插件适用于GBK及UTF-8编码环境,旨在提升网站内容的分享与传播效率。我们将从安装步骤、工作原理、可能遇到的问题以及解决方案等方面进行...
标题和描述中的“世界编程大赛第一名写的程序”这一知识点,实际上指向了计算机科学与编程竞赛领域的一个重要概念:即在高水平的编程比赛中,优胜者所编写的代码往往蕴含着高级算法、数据结构以及编程技巧。...
1.修改自Convert X转帖工具 2.新增批量替换关键词(原来是单个词语替换,可以利用这个功能删除一些网站的防转帖代码) 3.批量随机新增文字(新增内容可自定义,从而实现伪原创) 4.cookie记录替换和新增关键词(避免每次...
8. **故障排查**:如果在使用过程中遇到问题,如插件不工作、报错等,用户可以查阅插件提供的文档、社区论坛或联系开发者寻求帮助。 总的来说,"转帖工具插件 for PHPwind 7.5 正式版" 提供了一个高效且用户友好的...
HTML2UBBMaxcj 是一款专为Softii论坛设计的转帖工具,它主要用于将HTML格式的帖子内容转换成UBB代码,以便在论坛中更好地显示和分享。UBB(Universal BBCode)是一种轻量级的标记语言,常用于网络论坛,与HTML类似,...
- 加花软件:增加程序的混淆性,使其难以被反作弊系统分析。 3. **操作步骤**: - 使用Actual Search and Replace,将源代码中所有与"cheatengine"相关的字符串替换为其他无关联的字符串,确保生成的文件标题不再...
图形系统开发基础,我是转帖的,感觉不错,属于入门级别。 1:搭建Linux下的图形系统开发环境 图形输出在嵌入式开发中,多数是向FrameBuffer中写数据,然后会显示在LCD中,在Linux下做图形开发的时候,需要模拟各种...
转帖图片提取工具可以对论坛图片附件信息进行清除,只保留图片代码,操作很简单,推荐有需要转帖图片工具的朋友下载 转帖图片提取工具使用方法: 将IP138上处理过的东西复制到上方的编辑框内,点击只要图片,下面...
性能测试在软件质量保证中起着重要的作用,它包括应用在客户端性能测试、应用在网络上性能测试和应用在服务器端性能测试三个方面。通常情况下,这三方面的有效、合理的结合,可以达到对系统性能的全面分析和瓶颈的...
转帖PLCDCSFCS三大控制系统的特点和差异 PLC、DCS、FCS 三大控制系统是自动化技术中的热点,各有其特点和差异。下面对这三大控制系统的特点和差异进行分析。 1.PLC(Programmable Logic Controller) PLC 是一种...
"一键转帖功能插件 for 帝国CMS v1.0.rar" 是一个专为帝国CMS设计的扩展工具,其主要目标是简化用户在网站上分享内容的过程,提高用户体验。这个插件允许用户轻松地将网站上的文章或信息复制并转发到其他平台,如...