Mybatis(5)之Mybatis开发dao的两种方式

【5】.两种方式:

第一种:原始 dao的开发方式

第二种:mapper代理方式

(1. 原始 dao的开发方式:程序员需要写 dao接口和 dao的实现类;
    2. mapper代理方式:程序员只需要写 dao接口,实现由 mybatis自动生成代理对象)

1. sqlSession的作用范围

SqlSessionFactoryBuilder: 以工具类的方式进行使用,创建一个 SqlSessionFactoryBuilder,通过他再 build出一个SqlSessionFactory;

SqlSessionFactory : 正常开发时,是以单例的方式管理 SqlSessionFactory (即在整个运行程序中,只有一个 SqlSessionFactory 的实例);

SqlSession : 是一个面向用户(程序员)的接口,用户通过此接口对数据库进行操作;SqlSession 是线程非安全,不可使用单例方式;
应用范围:在方法体内部,作为局部变量存在;如下(创建一个使用,使用完关闭):

@Test
public void testDeleteUser(){ 
	SqlSession sqlSession=sqlSessionFactory.openSession(); 
	sqlSession.delete("deleteUser",2); 
	sqlSession.commit(); sqlSession.close();
}

2. 原始 dao的开发方式

1.首先定义接口
2.实现接口
3.原始 dao开发的问题:

      ①实现类中存在大量重复代码;
      ②整个 mybatis操作过程,代码模板重复:
               先创建 sqlSession;
               调用方法(selectOne、selectList、insert、delete、update);
               关闭 sqlSession;
      ③实现类中存在硬编码;(例如 selectOne(“findUserById”,1)此方法中第一个参数是根据 mapper.xml文件中 statement的 id变化而改变)
在这里插入图片描述
UserDao.java: 一个接口,里面有方法 findUserById;

public interface UserDao {
    public User findUserById(int id) throws Exception;
    public List<User> findUserByName(String name) throws Exception;
    public void addUser(User user) throws Exception;
}

UserDaoImpl.java: UserDao的实现类,实现了 findUserById方法;在方法中要用到 sqlSession,通过 sqlSessionFactory 得到;sqlSessionFactory 在此处是通过一个构造方法传进来得到;findUserById方法中得到 user是通过 selectOne(“findUserById”,1):第一个参数是mapper.xml(即User.xml)中对应的方法的 statement的 id,第二个参数是传入的参数。增、删、改操作后要调用 commit()方法。

public class UserDaoImpl implements UserDao {

    private SqlSessionFactory sqlSessionFactory;
    public UserDaoImpl(SqlSessionFactory sqlSessionFactory){
	this.sqlSessionFactory=sqlSessionFactory;
    }

    public User findUserById(int id) throws Exception{
    	SqlSession sqlSession=sqlSessionFactory.openSession();
    	User user=sqlSession.selectOne("findUserById",1);
    	sqlSession.close();
    	return user;
    }
    
   public List<User> findUserByName(String name) throws Exception{
	SqlSession sqlSession=sqlSessionFactory.openSession();
	User user=sqlSession.selectList("findUserByName",username);
	sqlSession.close();
	return list;
    }

    public void addUser(User user) throws Exceptionthrows Exception{
    	SqlSession sqlSession=sqlSessionFactory.openSession();
    	sqlSession.insert("addUser",user);
    	sqlSession.commit();
    	sqlSession.close();
    }
}

AppTest.java: 首先创建 sqlSessionFactory,testFindUserById测试方法中将 sqlSessionFactory传入;

public class AppTest {
    SqlSessionFactory sqlSessionFactory=null;
    @Before
    public void init() throws IOException(){
        InputStream inputStream=Resources.getResourceAsStream("sqlMapConfig.xml");
        sqlSessionFactory=new SqlSessionFactoryBuilder().builde(inputStream);
    }
    @Test
    public void testFindUserById() throws Exception(){
        UserDao userDao=new UserDaoImpl(sqlSessionFactory);
        User user=userDao.findUserById(1);
        System.out.println(user.getId()+","+user.getUsername());
    }
}

3. mapper代理方式

mybatis使用代理对象自动创建 dao接口的实现类;

① mapper.java(类的全限定名)——mapper.xml(namespace的名字)
② mapper.java(方法名)——mapper.xml(statement的 id)
③ mapper.java(输入类型)——mapper.xml(pararmeterType)
④ mapper.java(返回类型)——mapper.xml(resultType)

【必须遵循规则】:
<1> mapper代理方式开发时,mapper.xml中的 namespace指定为 mapper.java接口的全限定名;
<2> mapper.xml中的 statement的 id就是 mapper.java的方法名;
<3> 输入的参数类型,在 mapper.xml中的 statement的 parameterType与 mapper.java中的一致;
<4> 输出类型,在 mapper.xml中的 statement的 resultType与 mapper.java中的返回类型一致;

【实现步骤】:
<1> mapper.xml(映射文件)要求:命名建议:表名+Mapper.xml;
    mapper.xml中 namespace要求是接口全限定名,接口命名建议:表名+Mapper.java;
   为了将 mapper.xml与 mapper.java进行关联(可通过 namespace找到接口);
<2> mapper.java(mapper.java接口的长名作为 mapper.xml中namespace的名字);
   相当于 dao的接口;
   内部方法的声明与 mapper.xml中的 statement的 id名相同,输入类型相同,返回类型相同;

【返回值问题】:
mapper.xml中 resultType无论是返回单条还是多条,定义时都是 pojo类型;
mapper.java指明返回对象还是集合。如果返回的是单条,代理对象通过 selectOne调用,如果返回的是多条,代理对象通过 selectList调用。

在这里插入图片描述
UserMapper.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        
<mapper namespace="com.iotek.mapper.UserMapper">
    <select id="findUserList" parameterType="userQueryVo"  resultType="user">
        select * from Users where username like '%${userCustom.username}%'
    </select>
    
    <select id="findUserCount" parameterType="userQueryVo"  resultType="int">
        select count(*) from Users where username like '%${userCustom.username}%'
    </select>

</mapper>

UserMapper.java: 接口

public interface UserDao {
    public User findUserById(int id) throws Exception;
    public List<User> findUserByName(String name) throws Exception;
    public void addUser(User user) throws Exception;
    public void updateUser(User user) throws Exception; 
    public void deleteUser(int id) throws Exception;      
}

SqlMapConfigxml: 全局配置文件中需要将 UserMapper.xml注册进去:用①或②-2

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
       
<configuration>
    <typeAliase>
        <package name="com.iotek.po"/>
    </typeAliase>
    <properties resource="db.prperties"></properties>
    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    
    <mappers>
        <package name="com.iotek.mapper"/>  //①
        <mapper resource="sqlmap/User.xml"/> //②-1
        <mapper resource="sqlmap/UserMapper.xml"/> //②-2     
    </mappers>
</configuration>

AppTest.java:
下面 ①将 userMapper打印出来,得到:
org.apache.ibatis.binding.MapperProxy@1068452
可知 userMapper是一个代理对象;

public class AppTest {
    SqlSessionFactory sqlSessionFactory=null;
    @Before
    public void init() throws Exception(){
        InputStream inputStream=Resources.getResourceAsStream("sqlMapConfig.xml");
        sqlSessionFactory=new SqlSessionFactoryBuilder().builde(inputStream);
    }
    @Test
    public void testFindUserById() throws Exception(){ //原始dao的开发方式
        UserDao userDao=new UserDaoImpl(sqlSessionFactory);
        User user=userDao.findUserById(1);
        System.out.println(user.getId()+","+user.getUsername());
    }

    @Test
    public void testFindUserById2() throws Exception(){ //mapper动态代理方式
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        //System.out.println(userMapper.toString()); ①
        User user=userMapper.findUserById(1);
        sqlSession.close();
        System.out.println(user.getId()+","+user.getUsername());
    }
    @Test
    public void testFindUserByName() throws Exception(){ 
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        List<User> list=userMapper.findUserByName("tom");
        sqlSession.close();
        for (User user:list) {
            System.out.println(user.getId()+","+user.getUsername());
        }
    }
    @Test
    public void testAddUser() throws Exception(){ 
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        User user=new Uesr("jay",10);
        userMapper.addUser(user);
        sqlSession.commit();
        sqlSession.close();
    }
  
}

猜你喜欢

转载自blog.csdn.net/qq_41029923/article/details/83622407