MybatisDao层开发的二种方式


原始DAO开发

 

SqlSession使用范围

SqlSessionFactoryBuilder

  • 通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory
  • 将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder。
  • 在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。

SqlSessionFactory

  • 通过SqlSessionFactory创建SqlSession,使用单例模式管理sqlSessionFactory(工厂一旦创建,使用一个实例)。
  • 将来mybatis和spring整合后,使用单例模式管理sqlSessionFactory。

SqlSession

  • SqlSession是一个面向用户(程序员)的接口。
  • SqlSession中提供了很多操作数据库的方法:如:selectOne(返回单个对象)、selectList(返回单个或多个对象)、。
  • SqlSession是线程不安全的,在SqlSesion实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。
  • SqlSession最佳应用场合在方法体内,定义成局部变量使用。
public class User {
   // private String id;
   private Integer id;
    private String username;// 用户姓名
    private String sex;// 性别
    private Date birthday;// 生日
    private String address;// 地址

   /* public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }*/

public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" + "id=" + id + ", username='" + username + '\'' + ", sex='" + sex + '\'' + ", birthday=" + birthday + ", address='" + address + '\'' + '}';
    }
}
POJO
User.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">

<!-- namespace:命名空间,对sql语句进行分类化管理,隔离 paramterType:参数类型 java类型 pojo(保存的时候) resultType:结果类型 数据库的字段名必须和实体类的属性名一致 #{id}:一个占位符 --> <mapper namespace="test"> <!-- id:标识配置文件中唯一的sql 一般称为statement的id --> <select id="findUserById" parameterType="int" resultType="b_dao_origin.pojo.User"> SELECT * FROM USER WHERE id=#{id} </select> </mapper>
public interface UserDao {
    /**
     * 根据id查询
     * @param id
     * @return
     */
    public User getUserById(Integer id);
}
UserDao
UserDaoImpl
 1 public class UserDaoImpl implements UserDao {
 2     private SqlSessionFactory sqlSessionFactory;
 3   //通过构造方法注入sqlSessionFactory
 4     public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
 5         this.sqlSessionFactory = sqlSessionFactory;
 6     }
 7 
 8     /**
 9      * 根据id查询
10      * @param id
11      * @return
12      */
13     @Override
14     public User getUserById(Integer id) {
15         SqlSession sqlSession = sqlSessionFactory.openSession();
16         User user = sqlSession.selectOne("test.findUserById", id);
17         return user;
18     }
19 }
public class Demo {
    SqlSessionFactory sqlSessionFactory = null;
    @Before
    public void before() throws IOException {
        //通过流的方式得到核心配置文件
        InputStream inputStream = Resources.getResourceAsStream("b_dao_origin/sqlMapConfig.xml");
        //通过配置文件创建session工厂
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void test(){
        //如果使用代理增强了方法就不能用UserDaoImpl  要用UserDao
        UserDaoImpl userDao = new UserDaoImpl(sqlSessionFactory);
        User userById = userDao.getUserById(1);
        System.out.println(userById);
    }
}
测试类

存在的问题:

1.如果DAO层有很多方法,实现类中就会出现很多重复的代码。

2.调用sqlsession方法时将statemnt的id硬编码了,不利于维护。

3.调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。

 

Mapper动态代理方式

实现原理:

Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

需要遵循的规范:

(1)Mapper接口和Mapper.xml需要放置在一个目录下,且同名

(2)Mapper.xml中的namespace值等于Mapper接口的全路径

(3)Mapper接口的方法名和statement Id一致

(4)Mapper接口的参数类型和statement paramterType类型一致

(5)Mapper接口的返回值和statement resultType类型一致(注意:返回值可能是list)

注意:mapper接口只能传递一个参数(尽量保证原子操作)、当需要传递多个参数的时候,可以使用pojo或者包装类型pojohashmap

Mapper接口:

public interface UserMapper {
    /**
     * 根据id查询
     * @param id
     * @return
     */
    public List<User> getUserById(Integer id);

    /**
     * 通过姓氏进行模糊查询
     * @param name
     * @return
     */
    public List<User> getUsersByName(String name);
}

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">

<!-- namespace:mapper接口的全路径
paramterType:参数类型  java类型  pojo(保存的时候)
resultType:结果类型  数据库的字段名必须和实体类的属性名一致
#{id}:一个占位符
-->
<mapper namespace="c_dao_mapper.mapper.UserMapper">

    <select id="getUserById" parameterType="int" resultType="user">
      SELECT * FROM USER WHERE id=#{id}
    </select>

    <select id="getUsersByName" parameterType="string" resultType="user">
        SELECT * FROM USER WHERE username LIKE #{value}"%"
    </select>
</mapper>

在sqlMapConfig.xml中配置别名和引入映射文件UserMapper.xml

<typeAliases>
        <!--
        type:类型的全路径
        alias:对应类型的别名   建议类名首字母小写
        -->
       <!-- <typeAlias type="c_dao_mapper.pojo.User" alias="user"></typeAlias>-->

        <!--
        扫描指定的包名  别名:类名,默认首字母小写
        -->
        <package name="c_dao_mapper.pojo"></package>
 </typeAliases>


<!--引入映射文件-->
    <mappers>
       <!-- <mapper resource="c_dao_mapper/mapper/UserMapper.xml"></mapper>
        可以通过xml文件找到class<mapper class="c_dao_mapper.mapper.UserMapper"></mapper>-->

        <!--批量加载 只能在mapper方式开发的时候用-->
        <package name="c_dao_mapper.mapper"></package>
    </mappers>

测试类:

public class Demo {
    SqlSessionFactory sqlSessionFactory = null;
    @Before
    public void before() throws IOException {
        //通过流的方式得到核心配置文件
        InputStream inputStream = Resources.getResourceAsStream("c_dao_mapper/sqlMapConfig.xml");
        //通过配置文件创建session工厂
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void test(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        //生成usermapper代理对象 会实现UserMapper接口里面的方法
        //如果public User getUserById(Integer id);
        //代理对象就会调用selectone方法
        //如果public List<User> getUserById(Integer id);
        //代理对象就会调用selectList方法
        List<User> userById = mapper.getUserById(1);
        System.out.println(userById);
    }

    //模糊查询
    @Test
    public void test2(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = mapper.getUsersByName("w");
        System.out.println(userList);
    }

}

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM