美文网首页
[java]40、MyBatis-dao

[java]40、MyBatis-dao

作者: 史记_d5da | 来源:发表于2022-05-08 11:42 被阅读0次

    1、使用MyBatis实现dao层

    1.1、使用MyBatis实现dao层的几种方式

    1、自定义dao实现类,在实现中调用SqlSession的相关方法(使用XML
    2、只定义dao接口类,SqlSessiongetMapper方法生成dao的代理对象(使用XML
    3、只定义dao接口类,SqlSessiongetMapper方法生成dao的代理对象(使用注解)
    目前的注解的功能并没有XML强大,所以也可以XML+注解混合使用

    1.2、getMapper + XML实现dao

    1、两个配置要求
    mappernamespace必须是dao接口类的全类名
    mapperselectupdateinsertdeleteid值必须和dao的方法名一致
    2、如果updateinsertdelete方法的返回值是Boolean类型
    代理对象内部是影响记录数大于0就返回true
    参考源码org.apache.ibatis.binding.MapperMethod

    private Object rowCountResult(int rowCount) {
        final Object result;
        if (method.returnsVoid()) {
          result = null;
        } else if (Integer.class.equals(method.getReturnType()) || Integer.TYPE.equals(method.getReturnType())) {
          result = rowCount;
        } else if (Long.class.equals(method.getReturnType()) || Long.TYPE.equals(method.getReturnType())) {
          result = (long) rowCount;
        } else if (Boolean.class.equals(method.getReturnType()) || Boolean.TYPE.equals(method.getReturnType())) {
          result = rowCount > 0; // 通过返回值类型确定需要返回的类型
        } else {
          throw new BindingException("Mapper method '" + command.getName() + "' has an unsupported return type: " + method.getReturnType());
        }
        return result;
      }
    

    skill.xml的代码如下

    <mapper namespace="com.sj.dao.SkillDao">
        <sql id="sqlList">SELECT * FROM skill</sql>
    
        <select id="get" parameterType="int" resultType="skill">
            <include refid="sqlList" /> WHERE id = #{id}
        </select>
        <select id="list" parameterType="int" resultType="skill">
            <include refid="sqlList"/>
        </select>
        <update id="update" parameterType="skill">
            UPDATE skill SET name = #{name}, level = #{level} WHERE id = #{id}
        </update>
    
        <insert id="save"
                useGeneratedKeys="true"
                keyProperty="id"
                parameterType="skill">
            INSERT INTO skill(name, level) VALUES (#{name}, #{level})
        </insert>
    
        <delete id="remove" parameterType="int">
            DELETE FROM skill WHERE id = #{id}
        </delete>
    </mapper>
    

    SkillDao接口实现如下

    package com.sj.dao;
    import com.sj.bean.Skill;
    import java.util.List;
    public interface SkillDao {
        boolean save(Skill skill);
        boolean update(Skill skill);
        boolean remove(Integer id);
        Skill get(Integer id);
        List<Skill> list();
    }
    

    Test代码实现如下(只写了一个实现)

    public void get() {
        try (SqlSession session = Mybatises.openSession(true)){
            // 代理对象
            SkillDao dao = session.getMapper(SkillDao.class);
            System.out.println(dao.get(1));
        }
    }
    
    1.3、getMapper+注解实现dao

    1、首先要在mybaits-cofig.xml中配置dao的位置
    方法一:<mapper class="dao的全类名" />
    方法二:<package name="dao所在的包" />
    2、常用注解

    • @Select@Insert@Update@Delete@SelectedKey
    • @SelectedKey:等价于前面提到的<selectKey></selectKey>
    @SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty="id", before = false, resultType = Integer.class)
    
    • @Param:设置参数名,

    java文件如下

    public void list2() {
        try (SqlSession session = Mybatises.openSession(true)) {
            SkillDao dao = session.getMapper(SkillDao.class);
            System.out.println(dao.listByStartAndSize(1, 2));
        }
    }
    

    SkillDao接口文件

    // 通过注解告知参数名称 start 和size
        @Select("SELECT * FROM skill LIMIT #{start}, #{size}")
        List<Skill> listByStartAndSize(@Param("start") int start, @Param("size") int size);
    

    不加@Param注解会报如下错误
    ### Cause: org.apache.ibatis.binding.BindingException: Parameter 'start' not found. Available parameters are [arg1, arg0, param1, param2]

    • @Options:设置其他属性值,
    @Options(useGeneratedKeys = true, keyProperty = "id")
    
    • @CacheNameSpace:对应<cache>开启二级缓存
    @CacheNamespace(flushInterval = 600000, size = 512, eviction = LruCache.class)
    
    • @Results@ResultMap:对应<resultMap>
    • @Result:对应<id><result>
    • @One对应<association>
    • @Many对应<collection>
      PersonDao接口实现
    public interface PersonDao {
        @Select("SELECT * FROM person WHERE id = #{id}")
        @Results(id = "get", value = {
                @Result(property = "id", column = "id", id = true),
                @Result(property = "name", column = "name"),
                // @One 相当于association
                @Result(
                        property = "idCard",
                        column = "id",
                        one = @One(fetchType = FetchType.LAZY, select = "com.sj.dao.IdCardDao.getByPerson")
                ),
                // @Many相当于collection标签
                @Result(property = "bankCards",
                        column = "id",
                        many = @Many(fetchType = FetchType.LAZY,select = "com.sj.dao.BankCardDao.listByPerson")),
                @Result(property = "jobs",
                        column = "id",
                        many = @Many(fetchType = FetchType.LAZY,select = "com.sj.dao.JobDao.listByPerson"))
        })
        Person get(Integer id);
        
        @Select("SELECT * FROM Person")
        // 引用id为get的Results
        @ResultMap("get")
        List<Person>list();
    }
    

    BankCardDao接口实现

    public interface BankCardDao {
        @Select("SELECT * FROM bank_card WHERE person_id = #{presonId}")
        List<BankCard> listByPerson(Integer personId);
    }
    

    IdCardDao接口实现

    public interface IdCardDao {
        @Select("SELECT * FROM id_card WHERE person_id = #{personId}")
        IdCard getByPerson(Integer personId);
    }
    

    JobDao接口实现

    public interface JobDao {
        @Select("SELECT j.* FROM job j JOIN person_job pj ON j.id = pj.job_id AND pj.person_id = #{presonId}")
        List<Job> listByPerson(Integer personId);
    }
    

    mybatis-config.xml配置如下

    <configuration>
        <mappers>
            <package name="com.sj.dao"/>
        </mappers>
    </configuration>
    

    PersonTest代码如下

    public void get() {
        try (SqlSession session = Mybatises.openSession(true)){
                // 代理对象
            PersonDao dao = session.getMapper(PersonDao.class);
            System.out.println(dao.get(1));
        }
    }
    

    • @ConstructorArgs:对应<constructor>
    • @Arg:对应<idArg><arg>
    <resultMap id="rmGet" type="Skill">
        <constructor>
            <arg name="name" javaType="String" column="name"></arg>
            <arg javaType="int" column="level"></arg>
        </constructor>
    </resultMap>
    
    public Skill(@Param("name") String name, Integer level) {
        this.name = name;
        this.level = level;
    }
    
    • 可以使用<script>嵌入其他的XML标签中的内容
    @Insert("<script>" +
            "INSERT INTO skill(name, level) VALUES" +
            "        <foreach collection='skills' item='skill' separator=','>" +
            "            (#{skill.name}, ${skill.level})" +
            "        </foreach>" +
            "</script>"
    )
    boolean batchSave(@Param("skills") List<Skill> skills);
    
    • @ConstructorProperties:指定构造函数名称
    // 指定构造函数名称
    @ConstructorProperties({"age", "name"})
    public Dog(int age, String name) {
        this.age = age;
        this.name = name;
    }
    
    <bean id="dog" class="com.sj.domain.Dog">
        <constructor-arg value="shiji" name="name"/>
        <constructor-arg value="10" name="age" />
    </bean>
    

    mybaits-cofig.xml中配置如下

    <configuration>
        <mappers>
            <mapper class="com.sj.dao.SkillDao"/>
        </mappers>
    </configuration>
    

    SkillDao接口实现如下

    @CacheNamespace(flushInterval = 600000, size = 512, eviction = LruCache.class)
    public interface SkillDao {
        @Insert("INSERT INTO skill(name, level) VALUES (#{name}, #{level})")
        @Options(useGeneratedKeys = true, keyProperty = "id")
        @SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty="id", before = false, resultType = Integer.class)
        boolean save(Skill skill);
    
        @Update("UPDATE skill SET name = #{name}, level = #{level} WHERE id = #{id}")
        boolean update(Skill skill);
    
        @Delete("DELETE FROM skill WHERE id = #{id}")
        boolean remove(Integer id);
    
        @Select("SELECT * FROM skill WHERE id = #{id}")
        Skill get(Integer id);
    
        @Select("SELECT * FROM skill")
        List<Skill> list();
    
        // 通过注解告知参数名称 start 和size
        @Select("SELECT * FROM skill LIMIT #{start}, #{size}")
        List<Skill> listByStartAndSize(@Param("start") int start, @Param("size") int size);
    }
    

    Test代码实现如下(只写了一个实现)

    public void get() {
        try (SqlSession session = Mybatises.openSession(true)){
            // 代理对象
            SkillDao dao = session.getMapper(SkillDao.class);
            System.out.println(dao.get(1));
        }
    }
    

    相关文章

      网友评论

          本文标题:[java]40、MyBatis-dao

          本文链接:https://www.haomeiwen.com/subject/vtagyrtx.html