Mybatis自己实现Dao与使用Mapper的代理实现Dao

来源:互联网 发布:长沙网络公关公司 编辑:程序博客网 时间:2024/06/06 05:34

Mybatis原始的Dao的开发方式(不使用Mapper代理)

主要知识点

insert后如何获取对象的主键的值(自动增长的或者uuid的)

使用selectKey,需要注意的是对于是自动增长的主键还是uuid的主键需要区分开来。

自动增长的主键

<insert id="insertUser" parameterType="com.njust.ml.po.User" >        <!--查询插入后记录的自增长的主键-->        <!--keyProperty:将查询出来的值绑定到po对象的哪一个属性上            order:      在insert语句的前面还是后面执行,这里是在insert的后面执行-->        <selectKey keyProperty="id" resultType="int" order="AFTER" >            select last_insert_id()        </selectKey>        insert into user values(null,#{username},#{birthday},#{sex},#{address})    </insert>

uuid

<insert id="insertUser" parameterType="com.njust.ml.po.User" >        <!--查询插入后记录的自增长的主键-->        <!--keyProperty:将查询出来的值绑定到po对象的哪一个属性上            order:      在insert语句的前面还是后面执行,这里是在insert的前面执行-->        <selectKey keyProperty="id" resultType="int" order="BEFORE" >            select uuid()        </selectKey>        insert into user values(null,#{username},#{birthday},#{sex},#{address})    </insert>

sqlSession的作用范围的问题

将sqlSession定义成方法内部的局部变量
因为SqlSession不是线程安全的,如果定义成成员变量的话,那么Dao层在正常情况下在Web体系中是单例的,而每一次请求都是一个线程在处理,那么多个线程都在使用SqlSession,会造成极度的不安全,例如造成sqlSession内部的一些成员变量在调用过程中被另一个线程修改

public interface UserDao {    User findUserById();    void insertUser(User user);}public class UserDaoImpl implements UserDao {    private SqlSessionFactory sqlSessionFactory;    public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {        this.sqlSessionFactory = sqlSessionFactory;    }    @Override    public User findUserById() {        //为什么将sqlSession定义成方法内部的局部变量        /*        因为SqlSession不是线程安全的,如果定义成成员变量的话,那么Dao层在正常情况下在Web体系中是        单例的,而每一次请求都是一个线程在处理,那么多个线程都在使用SqlSession,会造成极度的不安全        例如造成sqlSession内部的一些成员变量在调用过程中被另一个线程修改         */        //自己实现Dao层方法的弊端???        /*        存在硬编码问题:"test.findUserById"        存在模板化代码的问题,sqlSession的提交,关闭等         */        SqlSession sqlSession = sqlSessionFactory.openSession();        User user = sqlSession.selectOne("test.findUserById", 10);        sqlSession.close();        return user;    }    @Override    public void insertUser(User user) {    }} @Test    public void testMyDao(){        UserDao userDao = new UserDaoImpl(sqlSessionFactory);        User user = userDao.findUserById();        System.out.println(user);    }
//选择自己实现Dao的方式,namespace是可以任意的<mapper namespace="test" >    <select id="findUserById" parameterType="int" resultType="com.njust.ml.po.User">        select * from user where id = #{id}    </select></mapper>

Mapper代理形式的Dao

注意点

  1. mapper.xml中namespace指定为mapper接口的全限定名
  2. mapper.xml中statement的id就是mapper.java中方法名
  3. mapper.xml中statement的parameterType和mapper.java中方法输入参数类型一致
  4. mapper.xml中statement的resultType和mapper.java中方法返回值类型一致.
public interface UserDao {    User findUserById();    void insertUser(User user);}@Testpublic void testInsertProxy(){        SqlSession sqlSession = sqlSessionFactory.openSession();        UserDao userDao = sqlSession.getMapper(UserDao.class);        User user = new User();        user.setUsername("lqdhd");        user.setBirthday(new Date());        user.setSex("女");        user.setAddress("yz");        userDao.insertUser(user);        //这里打印出来的user会有id        System.out.println(user);        sqlSession.commit();        sqlSession.close();    }
<mapper namespace="com.njust.ml.dao.UserDao">    <insert id="insertUser" parameterType="com.njust.ml.po.User" >        <!--查询插入后记录的自增长的主键-->        <!--keyProperty:将查询出来的值绑定到po对象的哪一个属性上            order:      在insert语句的前面还是后面执行,这里是在insert的前面执行-->        <selectKey keyProperty="id" resultType="int" order="BEFORE" >            select uuid()        </selectKey>        insert into user values(null,#{username},#{birthday},#{sex},#{address})    </insert></mapper>
阅读全文
0 0