深入理解Mybatis开发方式

1.  Mybatis开发方式

1.1. Mybatis开发Dao

Mybatis在项目中主要使用的地方就是开发dao(数据访问层),所以下面讲解一下mybatis开发dao的方法。有两种方式:原始dao开发方式mapper代理开发方式(推荐)

1.2. 需求

1、根据用户ID来查询用户信息;

2、根据用户名称来模糊查询用户信息列表;

3、添加用户;

1.3. 原始Dao的开发方式

程序员需要写dao接口和dao实现类。

1.4. 编程步骤:

1、根据需求创建po类

2、编写全局配置文件

3、根据需求编写映射文件

4、加载映射文件

5、编写dao接口

6、编写dao实现类

7、编写测试代码

1.4.1.  开发Dao接口

publicinterface UserDao {

 

    //根据用户ID来查询用户信息

    public User findUserById(int id);

    //根据用户名称来模糊查询用户信息列表

    public ListfindUsersByName(String username);

    //添加用户

    publicvoid insertUser(User user);

}

1.4.2.  开发Dao实现类

l  SqlSessionFactoryBuilder,它的作用只是通过配置文件创建SqlSessionFactory,所以只要创建出SqlSessionFactory,它就可以销毁了。所以说,它的生命周期是在方法之内。

l  SqlSessionFactory,它的作用是创建SqlSession的工厂,工厂一旦创建,除非应用停掉,不要销毁。所以说它的生命周期是在应用范围内。这里可以通过单例模式来管理它。在mybatis整合spring之后,最好的处理方式是把SqlSessionFactory交由spring来做单例管理。

l  SqlSession是一个面向用户(程序员)的接口,它的默认实现是DefaultSqlSession。Mybatis是通过SqlSession来操作数据库的。SqlSession中不仅包含要处理的SQL信息,还包括一些数据信息,所以说它是线程不安全的,因此它最佳的生命周期范围是在方法体之内。

publicclass UserDaoImpl implements UserDao {

 

    //注入SqlSessionFactory

    private SqlSessionFactory sqlSessionFactory;

    //使用构造方法来初始化SqlSessionFactory

    public UserDaoImpl(SqlSessionFactorysqlSessionFactory){

        this.sqlSessionFactory = sqlSessionFactory;

    }

   

    @Override

    public User findUserById(int id) {

        //通过工厂,在方法内部获取SqlSession,这样就可以避免线程不安全

        SqlSessionsqlSession = sqlSessionFactory.openSession();

        //返回结果集

        returnsqlSession.selectOne("test.findUserById", id);

    }

 

    @Override

    public ListfindUsersByName(String username) {

        //通过工厂,在方法内部获取SqlSession,这样就可以避免线程不安全

        SqlSessionsqlSession = sqlSessionFactory.openSession();

        return sqlSession.selectList("test.findUsersByName", username);

    }

 

    @Override

    publicvoid insertUser(User user) {

        //通过工厂,在方法内部获取SqlSession,这样就可以避免线程不安全

        SqlSessionsqlSession = sqlSessionFactory.openSession();

        sqlSession.insert("test.insertUser", user);

    }

 

}

1.4.3.  测试代码

publicclass UserDaoTest {

 

    //声明全局的SqlSessionFactory

    private SqlSessionFactory sqlSessionFactory;

   

    @Before

    publicvoid setUp() throws Exception {

        // 1、读取配置文件

        Stringresource = "SqlMapConfig.xml";

        InputStreaminputStream = Resources.getResourceAsStream(resource);

        // 2、根据配置文件创建SqlSessionFactory

        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

    }

 

    @Test

    publicvoid testFindUserById() {

        //构造UserDao对象

        UserDaouserDao = new UserDaoImpl(sqlSessionFactory);

        //调用UserDao对象的方法

        Useruser = userDao.findUserById(1);

       

        System.out.println(user);

    }

 

    @Test

    publicvoid testFindUsersByName() {

        //构造UserDao对象

        UserDaouserDao = new UserDaoImpl(sqlSessionFactory);

        //调用UserDao对象的方法

        Listlist = userDao.findUsersByName("小明");

       

        System.out.println(list);

    }

 

    @Test

    publicvoid testInsertUser() {

        //构造UserDao对象

        UserDaouserDao = new UserDaoImpl(sqlSessionFactory);

        //构造User对象

        Useruser = new User();

        user.setUsername("东哥3");

        user.setAddress("清河宝盛西里3");

       

        //调用UserDao对象的方法

        userDao.insertUser(user);

       

        System.out.println(user.getId());

    }

 

}

1.4.4.  问题总结

原始dao开发存在一些问题:

Ø  存在一定量的模板代码。比如:通过SqlSessionFactory创建SqlSession;调用SqlSession的方法操作数据库;关闭Sqlsession。

Ø  存在一些硬编码。调用SqlSession的方法操作数据库时,需要指定statement的id,这里存在了硬编码。

1.5. Mapper代理的开发方式

1.5.1.  开发规范

1、mapper接口的全限定名要和mapper映射文件的namespace的值相同。

2、mapper接口的方法名称要和mapper映射文件中的statement的id相同;

3、mapper接口的方法参数只能有一个,且类型要和mapper映射文件中statement的parameterType的值保持一致。

4、mapper接口的返回值类型要和mapper映射文件中statement的resultType值或resultMap中的type值保持一致;

通过规范式的开发mapper接口,可以解决原始dao开发当中存在的问题:

1、模板代码已经去掉;

2、剩下去不掉的操作数据库的代码,其实就是一行代码。这行代码中硬编码的部分,通过第一和第二个规范就可以解决。

 

1.5.2.  编程步骤:

 

 

1、根据需求创建po类

2、编写全局配置文件

3、根据需求编写映射文件

4、加载映射文件

5、编写mapper接口

6、编写测试代码

1.5.2.1.      编写Mapper映射文件

重新定义mapper映射文件UserMapper.xml(内容同Users.xml,除了namespace的值),放到新创建的目录mapper下。

xml version="1.0" encoding="UTF-8"?>

DOCTYPE mapper   

PUBLIC "-//mybatis.org//DTDMapper 3.0//EN"   

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="cn.itcast.mybatis.mapper.UserMapper">

 

   

   

    <select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User">

        SELECT* FROM USER WHERE id = #{id}

    select>

   

   

   

   

    <select id="findUsersByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">

        SELECT* FROM USER WHERE username LIKE '%${value}%'

    select>

   

   

   

    <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">

        <selectKey keyProperty="id" resultType="int"order="AFTER">

            SELECT LAST_INSERT_ID()

        selectKey>

        INSERTINTO USER(username,sex,birthday,address) VALUES (#{username},#{sex},#{birthday},#{address})

    insert>

   

mapper>

1.5.2.2.      加载Mapper映射文件

<mappers>

    <mapper resource="sqlmap/User.xml"/>

    <mapper resource="mapper/UserMapper.xml"/>

mappers>

1.5.2.3.      编写Mapper接口

内容同UserDao接口一样:

publicinterface UserMapper {

    //根据用户ID来查询用户信息

    public User findUserById(int id);

    //根据用户名称来模糊查询用户信息列表

    public ListfindUsersByName(String username);

    //添加用户

    publicvoid insertUser(User user);

}

1.5.2.4.      编写测试代码

publicclass UserMapperTest {

 

    // 声明全局的SqlSessionFactory

    private SqlSessionFactory sqlSessionFactory;

 

    @Before

    publicvoid setUp() throws Exception {

        // 1、读取配置文件

        Stringresource = "SqlMapConfig.xml";

        InputStreaminputStream = Resources.getResourceAsStream(resource);

        // 2、根据配置文件创建SqlSessionFactory

        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

    }

 

    @Test

    publicvoid testFindUserById() {

        // 创建SqlSession

        SqlSessionsqlSession = sqlSessionFactory.openSession();

        // 通过SqlSession,获取mapper接口的动态代理对象

        UserMapperuserMapper = sqlSession.getMapper(UserMapper.class);

        // 调用mapper对象的方法

        Useruser = userMapper.findUserById(1);

 

        System.out.println(user);

        // 关闭SqlSession

        sqlSession.close();

 

    }

 

    @Test

    publicvoid testFindUsersByName() {

        // 创建SqlSession

        SqlSessionsqlSession = sqlSessionFactory.openSession();

        // 通过SqlSession,获取mapper接口的动态代理对象

        UserMapperuserMapper = sqlSession.getMapper(UserMapper.class);

        // 调用mapper对象的方法

        Listlist = userMapper.findUsersByName("小明");

 

        System.out.println(list);

        // 关闭SqlSession

        sqlSession.close();

    }

 

    @Test

    publicvoid testInsertUser() {

        // 创建SqlSession

        SqlSessionsqlSession = sqlSessionFactory.openSession();

        // 通过SqlSession,获取mapper接口的动态代理对象

        UserMapperuserMapper = sqlSession.getMapper(UserMapper.class);

       

        //构造User对象

        Useruser = new User();

        user.setUsername("东哥4");

        user.setAddress("清河宝盛西里4");

       

        // 调用mapper对象的方法

        userMapper.insertUser(user);

 

        System.out.println(user.getId());

       

        //执行SqlSessioncommit操作

        sqlSession.commit();

        // 关闭SqlSession

        sqlSession.close();

    }

 

}

 

 


你可能感兴趣的:(java,JavaEE,深入理解Mybatis开发方式,Mybatis,持久层框架,Mybatis开发方式)