更改会话以在MyBatis中设置日期格式

时间:2013-07-10 18:34:18

标签: java sql spring oracle mybatis

如何在同一个交易会话中执行此操作?

alter session set nls_date_format = 'yyyy/mm/dd hh24:mi:ss'

我需要在它们之前执行一些程序和插入。 我试图在同一个方法中制作另一种方法,但它仍然不起作用。

我将MyBatis与Spring集成在一起。我不知道它是否有任何区别。

任何人都可以帮助我吗?

感谢。

解决方案:

我通过改变Spring和MyBatis通过SqlSession集成的方式来管理它。

1 个答案:

答案 0 :(得分:3)

以下是两种可能的解决方案。

扩展SqlSessionFactory

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.TransactionIsolationLevel;
import org.apache.ibatis.session.defaults.DefaultSqlSessionFactory;
import org.apache.log4j.Logger;

public class CustomSqlSessionFactory extends DefaultSqlSessionFactory
{
    private static Logger   msLogger    = Logger.getLogger(CustomSqlSessionFactory.class);

    public CustomSqlSessionFactory(Configuration configuration)
    {
        super(configuration);
    }

    @Override
    public SqlSession openSession()
    {
        SqlSession session = super.openSession();
        alterSession(session);
        return session;
    }

    protected void alterSession(SqlSession session)
    {
        try
        {
            Statement statement = session.getConnection().createStatement();
            statement.addBatch("alter session set nls_date_format = 'yyyy/mm/dd hh24:mi:ss'");
            statement.addBatch("ALTER SESSION SET NLS_COMP = LINGUISTIC");
            statement.addBatch("ALTER SESSION SET NLS_SORT = XTURKISH_AI");
            statement.executeBatch();
            msLogger.debug("Altered newly created session parameters.");
            statement.close();
        }
        catch (SQLException e)
        {
            msLogger.error("Alter session failed!", e);
        }
    }

    @Override
    public SqlSession openSession(boolean autoCommit)
    {
        SqlSession session = super.openSession(autoCommit);
        alterSession(session);
        return session;
    }

    @Override
    public SqlSession openSession(Connection connection)
    {
        SqlSession session = super.openSession(connection);
        alterSession(session);
        return session;
    }

    @Override
    public SqlSession openSession(ExecutorType execType)
    {
        SqlSession session = super.openSession(execType);
        alterSession(session);
        return session;
    }

    @Override
    public SqlSession openSession(ExecutorType execType, boolean autoCommit)
    {
        SqlSession session = super.openSession(execType, autoCommit);
        alterSession(session);
        return session;
    }

    @Override
    public SqlSession openSession(ExecutorType execType, Connection connection)
    {
        SqlSession session = super.openSession(execType, connection);
        alterSession(session);
        return session;
    }

    @Override
    public SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level)
    {
        SqlSession session = super.openSession(execType, level);
        alterSession(session);
        return session;
    }

    @Override
    public SqlSession openSession(TransactionIsolationLevel level)
    {
        SqlSession session = super.openSession(level);
        alterSession(session);
        return session;
    }
}

如果您使用的是spring,还要创建一个CustomSqlSessionFactoryBuilder

import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class CustomSqlSessionFactoryBuilder extends SqlSessionFactoryBuilder
{
    @Override
    public SqlSessionFactory build(Configuration config)
    {
        return new CustomSqlSessionFactory(config);
    }
}

并通过修改SqlSessionFactoryBean配置附加CustomSqlSessionFactoryBuilder

<bean id="mySqlSessionFactoryBuilder" class="your.package.CustomSqlSessionFactoryBuilder" />    

<bean id="mySessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="myDataSource" />
    <property name="sqlSessionFactoryBuilder" ref="mySqlSessionFactoryBuilder" />
</bean>

每次借用操作都会更改会话。但是,如果使用池化连接,则此方法会降低执行性能。因此,每次从池中检出连接时,都会调用openSession。

如果您正在使用池化数据源,那么在数据源级别上处理会话更改操作将会快得多。第二个解决方案修改C3P0池数据源以改变会话。

修改池数据源(C3P0和Spring)

创建连接定制程序类[1]

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import org.apache.log4j.Logger;

import com.mchange.v2.c3p0.AbstractConnectionCustomizer;

public class ConnectionCustomizer extends AbstractConnectionCustomizer
{
    private static Logger   msLogger    = Logger.getLogger(ConnectionCustomizer.class);

    public void onAcquire(Connection c, String pdsIdt)
    {
        try
        {
            Statement statement = c.createStatement();
            statement.addBatch("alter session set nls_date_format = 'yyyy/mm/dd hh24:mi:ss'");
            statement.addBatch("ALTER SESSION SET NLS_COMP = LINGUISTIC");
            statement.addBatch("ALTER SESSION SET NLS_SORT = XTURKISH_AI");
            statement.executeBatch();
            msLogger.debug("Altered newly created session parameters.");
            statement.close();
        }
        catch (SQLException e)
        {
            msLogger.error("Alter session failed!", e);
        }
    }   
}

修改数据源配置bean并将创建的类添加为 connectionCustomizerClassName

<!-- 
    driverClass : Driver class that will be used to connect to database.
    jdbcUrl : jdbc url defining the database connection string.
    user : username of the database user.
    password : password of the database user.
    acquireIncrement : how many connections will be created at a time when there will be a shortage of connections.
    idleConnectionTestPeriod : after how much delay a connection will be closed if it is no longer in use.
    maxPoolSize : Max number of connections that can be created.
    maxStatements : Max number of SQL statements to be executed on a connection.
    minPoolSize : Minimum number of connections to be created.
    connectionCustomizerClassName : Custom connection customizer to enable session alterations and jobs on acquiring/closing - checking in/out physical connections 
-->
<bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />
    <property name="jdbcUrl" value="${app.jdbc.url}" />
    <property name="user" value="${app.jdbc.username}" />
    <property name="password" value="${app.jdbc.password}" />
    <property name="acquireIncrement" value="3" />
    <property name="maxPoolSize" value="50" />
    <property name="maxStatements" value="50" />
    <property name="minPoolSize" value="5" />
    <property name="idleConnectionTestPeriod" value="60" />
    <property name="preferredTestQuery" value="SELECT 1 FROM DUAL" />
    <property name="testConnectionOnCheckout" value="true" />
    <property name="connectionCustomizerClassName" value="your.package.name.ConnectionCustomizer" />
</bean>


[1]: http://www.mchange.com/projects/c3p0/