[java]40、MyBatis-dao

2022-05-08  本文已影响0人  史记_d5da

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、常用注解

@SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty="id", before = false, resultType = Integer.class)

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(useGeneratedKeys = true, keyProperty = "id")
@CacheNamespace(flushInterval = 600000, size = 512, eviction = LruCache.class)
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));
    }
}

<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;
}
@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({"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));
    }
}
上一篇 下一篇

猜你喜欢

热点阅读