sqlsession关闭后程序报错

sqlsession关闭后程序报错,第1张

你好,看见你用hibernate了,这个引起的原因很多,可以查看下oracle的session,看是不是事务没有及时的关闭。除此之外可以从以下几点查看下原因:

1、检查程序,优化数据库 *** 作及SQL语句,如该关闭的数据库链接要及时关闭、查询语句该简化的简化;

2、检查网络状况,排除网络原因;

3、调整数据库配置参数,比如:会话超时时间、每秒最大连接数、最大连接数等等;

4、看看数据库的版本,有没有升级的可能,也许会解决这个问题;

在这些控件里要达到分页的效果,一般都会传2个参数,第一个是表示当前页的索 引(一般从0开始),第二个表示当前页展示多少条业务记录,然后将相应的参数传递给List<T> getList(PagenateArgs args)方法,最终实现数据库中的分页时候可以使用limit关键词(针对mysql)进行分页,如果是oracle或者sql server他们都有自带的rownum函数可以使用。

针对上述思路,首先在 demomybatismodel下面新建一个名为PagenateArgs的分页参数实体类与一个名为SortDirectionEnum的枚举 类,里面包含当前页面索引pageIndex, 当前页展示业务记录数pageSize, pageStart属性表示从第几条开始,(pageStart=pageIndexpageSize)因为limit关键词用法是表示limit 起始条数(不包含),取几条,orderFieldStr排序字段,orderDirectionStr 排序方向,所以具体创建如下:

package davidmybatismodel;

/

  分页参数实体类

 /

public class PagenateArgs {

    private int pageIndex;

    private int pageSize;

    private int pageStart;

    private String orderFieldStr;

    private String orderDirectionStr;

    public PagenateArgs() {

        // TODO Auto-generated constructor stub

    }

    public PagenateArgs(int pageIndex, int pageSize, String orderFieldStr, String orderDirectionStr) {

        thispageIndex = pageIndex;

        thispageSize = pageSize;

        thisorderFieldStr = orderFieldStr;

        thisorderDirectionStr = orderDirectionStr;

        pageStart = pageIndex  pageSize;

    }

    public int getPageIndex() {

        return pageIndex;

    }

    public int getPageStart() {

        return pageStart;

    }

    public int getPageSize() {

        return pageSize;

    }

    public String orderFieldStr() {

        return orderFieldStr;

    }

    public String getOrderDirectionStr() {

        return orderDirectionStr;

    }

}

package davidmybatismodel;

/

  排序枚举

 /

public enum SortDirectionEnum {

    /

      升序

     /

    ASC,

    

    /

      降序

     /

    DESC

}

完成上面的步骤以后在IVisitorOperation接口类中继续添加一个方法public List<Visitor> getListByPagenate(PagenateArgs args),这次的分页其实也就是在这个的基础上稍加改动即可,IVisitorOperation接口类 改动后如下所示:

package davidmybatisdemo;

import javautilList;

import davidmybatismodelPagenateArgs;

import davidmybatismodelVisitor;

import davidmybatismodelVisitorWithRn;

public interface IVisitorOperation {

    /

      基础查询

     /

    public Visitor basicQuery(int id);

    /

      添加访问者

     /

    public int add(Visitor visitor);

    

    /

      删除访问者

     /

    public int delete(int id);

    

    /

      更新访问者

     /

    public int update(Visitor visitor);

    

    /

      查询访问者

     /

    public Visitor query(int id);

    

    /

      查询List

     /

    public List<Visitor> getList();

    

    /

      分页查询List

     /

    public List<Visitor> getListByPagenate(PagenateArgs args);    

}

接下来改动VisitorMapperxml配置文件了,新增一个<select>节点id与参数类型参照前几章的方式配置好,如下此处新增的id就为getListByPagenate,配置好以后如下

<xml version="10" encoding="UTF-8">

<!DOCTYPE mapper

  PUBLIC "-//mybatisorg//DTD Mapper 30//EN"

  ">

这里面的字段属性都是针对PagenateArgs参数类中的属性名,保持一致。

<if test="pageStart>-1 and pageSize>-1">

    limit #{pageStart}, #{pageSize}

</if>

在DemoRun类中创建测试方法:

/

  分页参数

 /

public static void queryVisitorListWithPagenate(int pageIndex, int pageSize, String orderField, String orderDire) {

    PagenateArgs args = new PagenateArgs(pageIndex, pageSize, orderField, orderDire);

    SqlSession session = MybatisUtilsgetSqlSession();

    IVisitorOperation vOperation = sessiongetMapper(IVisitorOperationclass);

    List<Visitor> visitors = vOperationgetListByPagenate(args);

    for (Visitor visitor : visitors) {

        Systemoutprintln(visitor);

    }

    MybatisUtilscloseSession(session);

    MybatisUtilsshowMessages(CRUD_EnumList, visitorssize());

}

DemoRunqueryVisitorListWithPagenate(0, 100, "id", SortDirectionEnumDESCtoString());

运行后下测试结果,先按Id倒序排列,查的Visitor表一共有14条记录,

假设取在第2页取5条,执行下面也就是6-10条数据,这样传参数就行了

DemoRunqueryVisitorListWithPagenate(1, 5, "id", SortDirectionEnumDESCtoString());

结果如下:

实现了一个分页逻辑

以注解方式

不同数据源在不同的java中

注解MapperScan指定SqlSessionFactory,添加sqlSessionFactoryRef =“xxxxxx”

eg:

数据源1:

@Configuration

@EnableTransactionManagement

@MapperScan(basePackages = {" comabcxxxdaodb1 "},sqlSessionFactoryRef = "xxxSqlSessionFactory")

public class xxxAutoConfigure {

@Bean(name = "xxxSqlSessionFactory")

public SqlSessionFactory sqlSessionFactory(@Qualifier("xxxDataSource") DataSource dataSource) throws Exception {

SqlSessionFactoryBean bean = new SqlSessionFactoryBean();

beansetDataSource(dataSource);

beansetMapperLocations(new PathMatchingResourcePatternResolver()getResources("classpath:mapper/xxx/xml"));

return beangetObject();

}

}

数据源2:

@Configuration

@EnableTransactionManagement

@MapperScan(basePackages = {" comabcxxxdaodb2 "},sqlSessionFactoryRef = "yyySqlSessionFactory")

public class yyyAutoConfigure {

@Bean(name = "yyySqlSessionFactory")

public SqlSessionFactory sqlSessionFactory(@Qualifier("yyyDataSource") DataSource dataSource) throws Exception {

SqlSessionFactoryBean bean = new SqlSessionFactoryBean();

beansetDataSource(dataSource);

beansetMapperLocations(new PathMatchingResourcePatternResolver()getResources("classpath:mapper/yyy/xml"));

return beangetObject();

}

}

MyBatis是什么?MyBatis是一款一流的支持自定义SQL、存储过程和高级映射的持久化框架。MyBatis几乎消除了所有的JDBC代码,也基本不需要手工去设置参数和获取检索结果。MyBatis能够使用简单的XML格式或者注解进行来配置,能够映射基本数据元素、Map接口和POJOs(普通java对象)到数据库中的记录。简介每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。SqlSessionFactoryBuilder可以从一个xml配置文件或者一个预定义的配置类的实例获得。用xml文件构建SqlSessionFactory实例是非常简单的事情。推荐在这个配置中使用类路径资源(classpathresource),但你可以使用任何Reader实例,包括用文件路径或file://开头的url创建的实例。MyBatis有一个实用类----Resources,它有很多方法,可以方便地从类路径及其它位置加载资源。MyBatis工作流程(1)加载配置并初始化触发条件:加载配置文件配置来源于两个地方,一处是配置文件,一处是Java代码的注解,将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。(2)接收调用请求触发条件:调用Mybatis提供的API传入参数:为SQL的ID和传入参数对象处理过程:将请求传递给下层的请求处理层进行处理。(3)处理 *** 作请求触发条件:API接口层传递请求过来传入参数:为SQL的ID和传入参数对象处理过程:(A)根据SQL的ID查找对应的MappedStatement对象。(B)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。(C)获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。(D)根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。(E)释放连接资源。(4)返回处理结果将最终的处理结果返回。

一、Mybatis介绍

MyBatis是一款一流的支持自定义SQL、存储过程和高级映射的持久化框架。MyBatis几乎消除了所有的JDBC代码,也基本不需要手工去 设置参数和获取检索结果。MyBatis能够使用简单的XML格式或者注解进行来配置,能够映射基本数据元素、Map接口和POJOs(普通java对 象)到数据库中的记录。

二、MyBatis工作流程

(1)加载配置并初始化

触发条件:加载配置文件

配置来源于两个地方,一处是配置文件,一处是Java代码的注解,将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。

(2)接收调用请求

触发条件:调用Mybatis提供的API

传入参数:为SQL的ID和传入参数对象

处理过程:将请求传递给下层的请求处理层进行处理。

(3)处理 *** 作请求 触发条件:API接口层传递请求过来

传入参数:为SQL的ID和传入参数对象

处理过程:

(A)根据SQL的ID查找对应的MappedStatement对象。

(B)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。

(C)获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。

(D)根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。

(E)释放连接资源。

(4)返回处理结果将最终的处理结果返回。

orm工具的基本思想

无论是用过的hibernate,mybatis,你都可以法相他们有一个共同点:

从配置文件(通常是XML配置文件中)得到 sessionfactory

由sessionfactory  产生 session

在session 中完成对数据的增删改查和事务提交等

在用完之后关闭session 。

在java 对象和 数据库之间有做mapping 的配置文件,也通常是xml 文件。

功能架构

Java框架篇---Mybatis 入门

Mybatis的功能架构分为三层:

API接口层:提供给外部使用的接口API,开发人员通过这些本地API来 *** 纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。

数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库 *** 作。

基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。

多需要添加的驱动包:

Java框架篇---Mybatis 入门

下面进行快速入门:

目录如下:

Java框架篇---Mybatis 入门

实体类User

package comoumyyemodel;

public class User {

  private String id;

  private String name;

  private  int age;

  public String getId() {

      return id;

  }

  public void setId(String id) {

      thisid = id;

  }

  public String getName() {

      return name;

  }

  public void setName(String name) {

      thisname = name;

  }

  public int getAge() {

      return age;

  }

  public void setAge(int age) {

      thisage = age;

  }

  @Override

  public String toString() {

      return "User [id=" + id + ", name=" + name + ", age=" + age + "]";

  }

}

映射文件UserMappingxml

<xml version="10" encoding="UTF-8" >

<!DOCTYPE mapper PUBLIC "-//mybatisorg//DTD Mapper 30//EN" ">

<mapper namespace="comoumyyemappingUserMapping">

  <!-- 在select标签中编写查询的SQL语句, 设置select标签的id属性为getUser,id属性值必须是唯一的,不能够重复

  使用parameterType属性指明查询时使用的参数类型,resultType属性指明查询返回的结果集类型

  resultType="comoumyyemodelUser"就表示将查询结果封装成一个User类的对象返回

  User类就是users表所对应的实体类

  -->

  <!--

      根据id查询得到一个user对象

   -->

  <select id="getUser" parameterType="String"

      resultType="comoumyyemodelUser">

      select from user where id=#{id}

  </select>

</mapper>

资源文件mybatisxml

<xml version="10" encoding="UTF-8">

<!DOCTYPE configuration PUBLIC "-//mybatisorg//DTD Config 30//EN" ">

<configuration>

  <environments default="development">

      <environment id="development">

          <transactionManager type="JDBC" />

          <!-- 配置数据库连接信息 -->

          <dataSource type="POOLED">

              <property name="driver" value="commysqljdbcDriver" />

              <property name="url" value="jdbc:mysql://localhost:3306/mybatis" />

              <property name="username" value="root" />

              <property name="password" value="root" />

          </dataSource>

      </environment>

  </environments>

  <mappers>

<mapper resource="com/oumyye/mapping/userMappingxml"/>

   </mappers>

</configuration>

测试类:

package test;

import javaioInputStream;

import orgapacheibatissessionSqlSession;

import orgapacheibatissessionSqlSessionFactory;

import orgapacheibatissessionSqlSessionFactoryBuilder;

import orgjunitTest;

import comoumyyemodelUser;

public class Tests {

@Test

public void test(){

String resource = "mybatisxml";

      //使用类加载器加载mybatis的配置文件(它也加载关联的映射文件)

      InputStream is = TestsclassgetClassLoader()getResourceAsStream(resource);

      //构建sqlSession的工厂

      SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder()build(is);

SqlSession session = sessionFactoryopenSession();

      /

        映射sql的标识字符串,

        comoumyyemappingUserMapping是userMapperxml文件中mapper标签的namespace属性的值,

        getUser是select标签的id属性值,通过select标签的id属性值就可以找到要执行的SQL

       /

      String statement = "comoumyyemappingUserMappinggetUser";//映射sql的标识字符串

      //执行查询返回一个唯一user对象的sql

      User user = sessionselectOne(statement, "1123");

      Systemoutprintln(usertoString());

}

}

结果:

第二步优化:SQL统一存取

问题描述:通过JDBC的方式,可读性很差,不利于维护以及做性能调优;改动Java代码需要重新编译、打包部署。不利于取出SQL在数据库客户端执行(取出后还得删掉中间的Java代码,编写好的SQL语句写好后还得通过+号在Java进行拼凑)。

解决问题:把SQL语句统一集中放到配置文件,通过SQL语句的key值去获取对应的SQL语句。

第三步优化:传入参数映射和动态SQL

问题描述:很多情况下,我们都可以通过在SQL语句中设置占位符来达到使用传入参数的目的,这种方式本身就有一定局限性,它是按照一定顺序传入参数的,要与占位符一一匹配。但是,如果我们传入的参数是不确定的(比如列表查询,根据用户填写的查询条件不同,传入查询的参数也是不同的,有时是一个参数、有时可能是三个参数),那么我们就得在后台代码中自己根据请求的传入参数去拼凑相应的SQL语句,这样的话还是避免不了在Java代码里面写SQL语句的命运。

解决问题:通过专门的SQL解析器来解析SQL语句,SQL语句经过解析后就可以动态的生成符合上下文的SQL语句,同时使用#变量名#表示占位符变量,使用$变量名$表示非占位符变量

第四步优化:结果映射和结果缓存

问题描述:执行SQL语句、获取执行结果、对执行结果进行转换处理、释放相关资源是一整套下来的。假如是执行查询语句,那么执行SQL语句后,返回的是一个ResultSet结果集,这个时候我们就需要将ResultSet对象的数据取出来,不然等到释放资源时就取不到这些结果信息了。我们从前面的优化来看,以及将获取连接、设置传入参数、执行SQL语句、释放资源这些都封装起来了,只剩下结果处理这块还没有进行封装,如果能封装起来,每个数据库 *** 作都不用自己写那么一大堆Java代码,直接调用一个封装的方法就可以搞定了

解决问题:一般对执行结果的有哪些处理,有可能将结果不做任何处理就直接返回,也有可能将结果转换成一个JavaBean对象返回、一个Map返回、一个List返回等等,结果处理可能是多种多样的。从这里看,我们必须告诉SQL处理器两点:第一,需要返回什么类型的对象;第二,需要返回的对象的数据结构怎么跟执行的结果映射,这样才能将具体的值copy到对应的数据结构上。

接下来,我们可以进而考虑对SQL执行结果的缓存来提升性能。缓存数据都是key-value的格式,那么这个key怎么来呢?怎么保证唯一呢?即使同一条SQL语句几次访问的过程中由于传入参数的不同,得到的执行SQL语句也是不同的。那么缓存起来的时候是多对。但是SQL语句和传入参数两部分合起来可以作为数据缓存的key值。

第五步优化:解决重复SQL语句问题

问题描述:将所有SQL语句都放到配置文件中,这个时候会遇到一个SQL重复的问题,几个功能的SQL语句其实都差不多,有些可能是SELECT后面那段不同、有些可能是WHERE语句不同。有时候表结构改了,那么我们就需要改多个地方,不利于维护。

解决问题:通过将SQL片段模块化,将重复的SQL片段独立成一个SQL块,然后在各个SQL语句引用重复的SQL块,这样需要修改时只需要修改一处即可。

3 优化的总结

对JDBC的优化和封装:

(1) 使用数据库连接池对连接进行管理

(2) SQL语句统一存放到配置文件

(3) SQL语句变量和传入参数的映射以及动态SQL

(4) 动态SQL语句的处理

(5) 对数据库 *** 作结果的映射和结果缓存

(6) SQL语句的重复使用

三.框架整体设计

1 总体流程

mybatis_1

(1)加载配置并初始化

触发条件:加载配置文件

配置来源于两个地方,一处是配置文件,一处是Java代码的注解,将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。

(2)接收调用请求

触发条件:调用Mybatis提供的API

传入参数:为SQL的ID和传入参数对象

处理过程:将请求传递给下层的请求处理层进行处理。

(3)处理 *** 作请求

触发条件:API接口层传递请求过来

传入参数:为SQL的ID和传入参数对象

处理过程:

(A)根据SQL的ID查找对应的MappedStatement对象。

(B)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。

(C)获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。

(D)根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。

(E)释放连接资源。

(4)返回结果处理

将最终的处理结果返回

2 功能架构设计

mybatis_2

把Mybatis的功能架构分为三层:

(1)API接口层:提供给外部使用的接口API,开发人员通过这些本地API来 *** 纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。

(2)数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库 *** 作。

(3)基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。

3 框架架构设计

mybatis_3

框架架构讲解:

(1)加载配置:配置来源于两个地方,一处是配置文件,一处是Java代码的注解,将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。

(2)SQL解析:当API接口层接收到调用请求时,会接收到传入SQL的ID和传入对象(可以是Map、JavaBean或者基本数据类型),Mybatis会根据SQL的ID找到对应的MappedStatement,然后根据传入参数对象对MappedStatement进行解析,解析后可以得到最终要执行的SQL语句和参数。

(3) SQL执行:将最终得到的SQL和参数拿到数据库进行执行,得到 *** 作数据库的结果。

(4)结果映射:将 *** 作数据库的结果按照映射的配置进行转换,可以转换成HashMap、JavaBean或者基本数据类型,并将最终结果返回。

四.Mybatis入门

每一个Mybatis应该都是以一个SqlSessionFactory实例为中心的,一个SqlSessionFactory实例都可以使用SqlSessionFactoryBuilder来创造。从配置类中创造的定制SqlSessionFactoryBuilder 实例,可以使用XML配置文件来生成一个SqlSessionFactory 实例。

1 从xml中创造SqlSessionFactory

MyBatis 有一个Resources 通用类,类中有许多方法可以简单地从类路径和其他地址中加载资源。

String resource = "org/mybatis/example/Configurationxml";

Reader reader = ResourcesgetResourceAsReader(resource);

sqlMapper = new SqlSessionFactoryBuilder()build(reader);

XML 文件包含了许多MyBatis 的核心设置,包括一个获取数据库连接(Connection)实例的数据源(DataSource),一个决定事务作用域和 *** 作的TransactionManager。全部的XML 配置文件的内容将在以后提到,先给出一个简单的样子。

<xml version="10" encoding="UTF-8" >

<!DOCTYPE configuration

PUBLIC "-//mybatisorg//DTD Config 30//EN"

">

以上就是关于sqlsession关闭后程序报错全部的内容,包括:sqlsession关闭后程序报错、MyBatis怎样实现MySQL动态分页、springboot 多数据源等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9559806.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存