发表于: 2018-05-20 17:02:48

2 1199


今天完成的事情:

完成测试部分,回忆了下自己之前做到什么进度

public class ApinformationMapperTest {

@Test
   public void insertApfo() throws Exception{
SqlSession session = DBTools.getSession();
       ApinformationMapper apfomaper = session.getMapper(ApinformationMapper.class);
       Apinformation apfo = new Apinformation("李强",19950809);
       apfomaper.insertApfo(apfo);
       session.commit();
       session.close();
   }

@Test
   public void selectAllUser() {
SqlSession session = DBTools.getSession();
       ApinformationMapper apinformationMapper = session.getMapper(ApinformationMapper.class);
       try {
List<Apinformation> user = apinformationMapper.selectAllUser();
           for(int i=0;i<user.size();i++)
{
Apinformation apfo = user.get(i);
               System.out.println("test"+i+":"+apfo.getId()+apfo.getName()+apfo.getCreateTime()+"\n");
           }
session.commit();
           session.close();
       }catch (Exception e){
e.printStackTrace();
           session.rollback();
           session.close();
       }
}
}

运行Test部分,报错

org.apache.ibatis.exceptions.PersistenceException: 

### Error opening session.  Cause: java.lang.NullPointerException

### Cause: java.lang.NullPointerException

看了下配置文件,想起来自己之前整合了spring,配置文件也更改了.查了下相关资料,准备重新编写测试代码

在mybatis

session工厂使用sqlSessionFactoryBuilder来创建 

先用resource类加载配置文件,使用sqlSessionFactoryBuilder构建SQLSession的工厂 , 而后创建能执行映射文件中sql的sqlSession

public class DBTools {
public static SqlSessionFactory sessionFactory;

   static {
try {
//使用Mybatis提供的Resource类加载Mybatis的配置文件
           Reader reader = Resources.getResourceAsReader("mybatisConfig.xml");
           //构建sqlSession的工厂
           sessionFactory = new SqlSessionFactoryBuilder().build(reader);
       }catch (Exception e){
e.printStackTrace();
       }
}
//创建能执行映射文件中sql的sqlSession
   public static SqlSession getSession(){
return sessionFactory.openSession();
   }
}

在MyBatis-Spring中

使用SqlSessionFactory Bean来替代sqlSessionFactoryBuilderSqlSessionFactory Bean实现了spring的FactoryBean接口。这就说明由spring最终创建的bean不是SqlSessionFactoryBean本身,而是工厂类的getObject()返回的方法结果。这种情况下,spring将会在应用启动时为你创建SqlSessionFactory对象,然后将它以SqlSessionFactory为名来存储。

    <bean id="sqlSessionFactory"
         class="org.mybatis.spring.SqlSessionFactoryBean"
         p:dataSource-ref="dataSource"
         p:configLocation="spring-Mybatis.xml"

         p:mapperLocations="com/study/javaMavenMapper/*.xml"/>


   <!--spring与Mybatis整合配置,扫描所有的dao,即mapper接口-->
   <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"
         p:basePackage="com.study.javaMavenMapper"
         p:sqlSessionTemplateBeanName="sqlSessionFactory"/>

   <!--对数据源进行事务管理
   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
       <property name="dataSource" ref="dataSource"/></bean>-->
   <bean id="transactionManager"
         class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
         p:dataSource-ref="dataSource"/>

1.MapperScannerConfigurer在basepackage下scan对应关于Mapper配置文件的interface,实例化为MapperFactoryBean;

在Mybatis-spring中,不需要直接使用SqlSessionFactory Bean或其对应的 SqlSessionFactory。相反,session工厂将会被注入到MapperFactory Bean或其它扩展了SqlSessionDaoSupport的DAO中。

ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"classpath:application.xml","" +
"classpath:spring-Mybatis.xml"});
apinformationMapper =(ApinformationMapper) context.getBean("ApinformationServiceImpl");

改后测试单元代码如下:

public class ApinformationMapperTest {
private ApinformationMapper apinformationMapper;

   @Before
   public void befor(){
@SuppressWarnings("resource")
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[]{"classpath:application.xml","classpath:spring-Mybatis.xml"});
        apinformationMapper =(ApinformationMapper) context.getBean("ApinformationServiceImpl");
   }
@ Test
   public void insertApfo1() throws Exception {
Apinformation apinformation = new Apinformation();
       apinformation.setName("Junit1");
       apinformation.setCreateTime(20180520);
       System.out.println(apinformationMapper.insertApfo(apinformation));
   }
}

试着运行了一下报错:

警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'apinformationServiceImpl': Unsatisfied dependency expressed through field 'apinformationMapper'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'apinformationMapper' defined in file [G:\study\mybatis\target\classes\com\study\javaMavenMapper\ApinformationMapper.class]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'org.apache.ibatis.session.defaults.DefaultSqlSessionFactory' to required type 'org.mybatis.spring.SqlSessionTemplate' for property 'sqlSessionTemplate'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'org.apache.ibatis.session.defaults.DefaultSqlSessionFactory' to required type 'org.mybatis.spring.SqlSessionTemplate' for property 'sqlSessionTemplate': no matching editors or conversion strategy found

错误信息显示不能将DefaultSqlSessionFactory 转换为SqlSessionTemplate所需的类型.

看样子是配置错误,但是我不记得自己用过SqlSessionTemplate这个属性啊.往回找看哪里用到了这个,然后发现在MyBatis-Spring中是当时一路顺下来没仔细看,

 <!--spring与Mybatis整合配置,扫描所有的dao,即mapper接口-->
   <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"
         p:basePackage="com.study.javaMavenMapper"
         p:sqlSessionTemplateBeanName="sqlSessionFactory"/>

第二个应该是

p:sqlSessionFactoryBeanName="sqlSessionFactory"

改掉之后,运行再次报错

NoSuchBeanDefinitionException: No bean named 'ApinformationServiceImpl' available

将测试代码中的

 apinformationMapper =(ApinformationMapper) context.getBean("ApinformationServiceImpl");

改为

apinformationService =(ApinformationService) context.getBean(ApinformationServiceImpl.class);

运行通过.

查看数据库,成功插入

明天计划的事情:

 log4j
遇到的问题:

dao(也就是mapper),service,serviceimpl之间的关系.

spring几种获得bean的方法

getBean一共有以下四种方法原型:

 getBean(String name)

参数name表示IOC容器中已经实例化的bean的id或者name,且无论是id还是name都要求在IOC容器中是唯一的不能重名。

getBean(Class<T> type)

参数Class<T> type表示要加载的Bean的类型。如果该类型没有继承任何父类(Object类除外)和实现接口的话,那么要求该类型的bean在IOC容器中也必须是唯一的

getBean(String name,Class<T> type)

当类型不唯一时,再通过id或者name来获取bean

getBean(String name,Object[] args)

通过bean的id或者name来获取bean,通过第二个参数Object[] args可以给bean的属性赋值,赋值的方式有两种:构造方法和工厂方法。但是通过这种方式获取的bean必须把scope属性设置为prototype,也就是非单例模式。收获:



返回列表 返回列表
评论

    分享到