mybatis入门截图二

--------------------

线程不安全问题

首先明白什么是线程不安全:

举例:struts2中,每个action中都定义了model模型对象(action类中是全局对象的存在  数据域属性)  用于封装前端页面提交过来的数据  所以就造成了struts2是非线程安全的,

即struts2不能使用单例模式,而只能使用多例模式,因为:当进行多线程并发请求的时候  多个线程会共用一个成员变量的值(例如两个用户请求action时  他们的数据就会有问题)

所以为了解决这个问题  struts2自然就成了多例模式的存在(注解方式配置action时   @Scope(prototype))

所以这句话就可以解释了

----------------------------------------

问题的引出:使用原始的方式开发dao

实现类:

package org.mybatis.dao;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.po.User;

public class UserDaoImpl implements UserDao {
    
    //通过构造注入SqlSessionFactory
    private SqlSessionFactory sqlSessionFacory;
    public UserDaoImpl(){
        
    }
    public UserDaoImpl(SqlSessionFactory sqlSessionFacory){
        this.sqlSessionFacory=sqlSessionFacory;
    }
    
    //问题1:因为sqlSession是非线程安全的  所以不能把sqlSession创建成全局变量  而只能写在每个方法体内 这就造成了问题2的产生
    
    //问题2:这里面把sqlSession在每个方法中都进行了一次创建  以及事务提交 SQLSession关闭  出现大量重复代码   唯独不
    //同的就是 执行的语句不同
    
    //3.解决问题2的方法  就是使用代理模式 在执行真正的增删改查之前   先执行这些公共的代码  执行增删改查之后  执行公共代码

    @Override
    public void deleteUser(int id) throws Exception {
        // TODO Auto-generated method stub
        SqlSession sqlSession=this.sqlSessionFacory.openSession();
        sqlSession.delete("test.deleteUser",id);
        sqlSession.commit();
        sqlSession.close();
    }
    @Override
    public User findUserById(int id) throws Exception {
        // TODO Auto-generated method stub
        SqlSession sqlSession=this.sqlSessionFacory.openSession();
        User user=sqlSession.selectOne("test.findUserById",id);//调用的是user.xml中写好的sql语句
        //sqlSession.commit(); 没有做数据的变更  此代码不写
        sqlSession.close();
        return user;
    }

    @Override
    public void insertUser(User user) throws Exception {
        // TODO Auto-generated method stub
        SqlSession sqlSession=this.sqlSessionFacory.openSession();
        sqlSession.insert("test.insertUser",user);
        sqlSession.commit();
        sqlSession.close();
    }

}

测试代码:

package org.mybatis.dao;

import static org.junit.Assert.*;

import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import org.mybatis.po.User;

public class UserDaoImplTest {
    private SqlSessionFactory sqlSessionFactory;

    //这个代码是在测试方法之前执行的代码
    @Before
    public void setUp() throws Exception {    
        String resource="SqlMapConfig.xml";
        //得到配置文件流
        InputStream resourceAsStream = Resources.getResourceAsStream(resource);
        //创建回话工厂
        this.sqlSessionFactory=new SqlSessionFactoryBuilder().build(resourceAsStream);
    }

    @Test
    public void testFindUserById() throws Exception {
        UserDao userDao=new UserDaoImpl(sqlSessionFactory);
        User user=userDao.findUserById(1);
        System.out.println(user);
    }

}

问题的解决:使用代理模式

测试下面配置的方法

创建接口类  接口中的方法 需要和上面的id一样

namespace需要写成接口类的地址

在mybatis核心配置文件中引入sql语句文件

测试类:

package org.mybatis.mapper;


import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import org.mybatis.dao.UserDao;
import org.mybatis.dao.UserDaoImpl;
import org.mybatis.po.User;

public class UserMapperTest {
    
    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void setUp() throws Exception {
        //
        String resource="SqlMapConfig.xml";
        
        InputStream input=Resources.getResourceAsStream(resource);
        sqlSessionFactory=new SqlSessionFactoryBuilder().build(input);
    }
    @Test
    public void testFindUserById() throws Exception {
//        UserDao userDao=new UserDaoImpl(sqlSessionFactory);
//        User user=userDao.findUserById(1);
//        System.out.println(user);
        SqlSession sqlSession=sqlSessionFactory.openSession();
        //得到代理对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        //通过代理对象  调用UserMapper类中的方法
        User user=mapper.findUserById(1);
        System.out.println(user);
    }

}

 开发思路:开发mapper.xml(UserMapper.xml)  开发mapper接口(UserMapper.java)(不需要实现类  因为sql代码在配置文件中已经创建了)  在核心配置文件中引入mapper.xml  

然后就可以在测试类中通过代理对象

UserMapper mapper = sqlSession.getMapper(UserMapper.class);

 调用mapper接口中的方法

User user=mapper.findUserById(1);
--------------------------------------------
全局配置文件中属性:

------------------------------

1.properties:

 


------------------------------------

---------------------------------------

---------------------------------

-------------------------------------

 

使用代理方式的前提下(1.配置文件中的namespace=对应接口类的全路径   2.接口类中的方法名=配置文件中statement对象【sql标签对象】的id值)    mapper.xml和对应的接口类mapper.java在同一目录下   (接口类名称和xml配置文件名称一样)    加载该类所在的包即可

 -------------------------------------------------------

原文地址:https://www.cnblogs.com/Joke-Jay/p/7445740.html