王小码

导航

Mybaits(15)注解开发

一、概述

  mybatis最初配置信息是基于 XML ,映射语句(SQL)也是定义在 XML 中的。而到了 MyBatis 3提供了新的基于注解的配置。

二、常见注解  

  1. @Insert:实现新增
  2. @Update:实现更新
  3. @Delete:实现删除
  4. @Select:实现查询
  5. @Result:实现结果集封装
  6. @Results:可以与@Result 一起使用,封装多个结果集
  7. @ResultMap:实现引用@Results 定义的封装
  8. @One:实现一对一结果集封装
  9. @Many:实现一对多结果集封装
  10. @SelectProvider: 实现动态 SQL 映射
  11. @CacheNamespace:实现注解二级缓存的使用

三、注解实现CRUD

1.编写实体类

package com.xhbjava.domain;

import java.io.Serializable;
import java.util.List;

import com.xhbjava.enumeration.SexEnum;
/**
 * 用户类
 * @author Mr.wang
 *@date    2020年2月28日
 */
public class User implements Serializable{
    private int id;
    private String userName;
    private String realName;
    private SexEnum sex;
    private String moble;
    //此处故意设置和数据库字段不一致
    private String userEmail;
    private String note;
    //对角色进行一对多关联
    private List<Role> roleList;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getRealName() {
        return realName;
    }
    public void setRealName(String realName) {
        this.realName = realName;
    }
    public SexEnum getSex() {
        return sex;
    }
    public void setSex(SexEnum sex) {
        this.sex = sex;
    }
    public String getMoble() {
        return moble;
    }
    public void setMoble(String moble) {
        this.moble = moble;
    }
    public String getuserEmail() {
        return userEmail;
    }
    public void setuserEmail(String userEmail) {
        this.userEmail = userEmail;
    }
    public String getNote() {
        return note;
    }
    public void setNote(String note) {
        this.note = note;
    }
    public List<Role> getRoleList() {
        return roleList;
    }
    public void setRoleList(List<Role> roleList) {
        this.roleList = roleList;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", userName=" + userName + ", realName=" + realName + ", sex=" + sex + ", moble="
                + moble + ", userEmail=" + userEmail + ", note=" + note + ", roleList=" + roleList + "]";
    }
    

}

2.持久层开发持久层接口

package com.xhbjava.dao;

import java.util.List;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.ResultMap;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectKey;
import org.apache.ibatis.annotations.Update;

import com.xhbjava.domain.User;

/**
 * 用户接口
 * 
 * @author Mr.wang
 * @date 2020年2月28日
 */
public interface IUserDao {
    /**
     * 查询所有用户
     * 
     * @return
     */
    @Select("select * from t_user")
    @Results(id="userMap",
    value= {@Result(id=true,column="id",property="id"),
            @Result(column="user_name",property="userName"),
            @Result(column="real_name",property="realName"),
            @Result(column="sex",property="sex"),
            @Result(column="moble",property="moble"),
            @Result(column="email",property="userEmail"),
            @Result(column="note",property="note")
            
    })
    List<User> findAll();

    /**
     * 根据id获取用户
     * 
     * @param id
     * @return
     */
    @Select("select * from t_user where id =#{id}")
    public User getUser(Long id);
    /**
     * 根据用户id查询用户
     * @param userId
     * @return
     */
    @Select("select * from t_user where id = #{id} ")
    @ResultMap("userMap")
    User findById(Integer userId);

    /**
     * 保存用户
     * 
     * @param user
     * @return
     */
    @Insert("insert into t_user(user_name,real_name,sex,moble,email,note) values(#{userName},#{realName},#{sex},#{moble},#{userEmail},#{note})")
    @SelectKey(keyColumn="id",keyProperty="id",resultType=Integer.class,before = 
    false, statement = { "select last_insert_id()" })
    public int saveUser(User user);
    
    /**
     * 更新用户
     * @param user
     * @return
     */
    @Update("update t_user set user_name=#{userName},real_name=#{realName},sex=#{sex},moble=#{moble},email=#{userEmail},note=#{note}")
     public int updateUser(User user);
    /**
     * 删除用户
     * @param id
     * @return
     */
    @Delete("delete from t_user where id = #{id}")
    public int deleteUser(int id);
}

 

3.编写 SqlMapConfig 配置文件

  

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- 主配置文件 -->
<configuration>

    <properties resource="jdbcConfig.properties" />
    <settings>
        <setting name="lazyLoadingEnabled" value="true" />
        <setting name="aggressiveLazyLoading" value="false" />
        <!-- 开启二级缓存 -->
        <setting name="cacheEnabled" value="true"/>
    </settings>
    <!-- 配置环境 -->
    <environments default="mysql">
        <!-- 配置mysql环境 -->
        <environment id="mysql">
            <!-- 配置事务类型 -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置数据源 -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}" />
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.username}" />
                <property name="password" value="${jdbc.password}" />
            </dataSource>
        </environment>
    </environments>
    <!-- 配置映射文件 -->
    <mappers>
        <package name="com.xhbjava.dao" />
    </mappers>
</configuration>

4.编写测试类进行测试

@Test
    public void saveUser() {
        // 5.创建Dao的代理对象
        session = factory.openSession(true);
        userDao = session.getMapper(IUserDao.class);
        User u = new User();
        u.setUserName("lisi");
        u.setRealName("李四");
        u.setSex(null);
        u.setMoble("12121212");
        u.setuserEmail("1212@qq.com");
        u.setNote("备注");
        int id = userDao.saveUser(u);
        System.out.println("==="+id);
    }

 

 

 

注意:
(1)SqlMapConfig.xml该怎么写还怎么写,注解开发,只是用来替代mapper.xml映射文件的.
(2)不要写mapper.xml映射文件
(3)不同的sql语句,要对应不同的@Servlet,@Insert,@Update,@Delete注解

四、使用注解实现复杂关系映射开发

  之前我们实现复杂关系开发时,我们在映射文件中通过<resultMap>标签来实现,在使用注解开发时我们需要借助@Results 注解,@Result 注解,@One 注解和@Many 注解。 

1.复杂关系映射的注解说明

(1)@Results注释代替标签<resultMap>,该注解中可以使用@Result注解,也可以使用@Result 集合@Results({@Result(),@Result()})或@Results(@Result()) 

(2)@Resutl 注解代替了<id>和<result>标签,@Result中的属性介绍:id是否是主键字段,column数据库列名,property需要装配的属性名,one 需要使用@One注解(@Result(one=@One)())),many 需要使用的@Many 注解(@Result(many=@many)())) 

@One 注解(一对一)
代替了<assocation>标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。
(3)@One 注解属性介绍:
  select 指定用来多表查询的 sqlmapper
  fetchType 会覆盖全局的配置参数 lazyLoadingEnabled。。
  使用格式:
  @Result(column=" ",property="",one=@One(select=""))

(4)@Many 注解(多对一)

  代替了<Collection>标签,是是多表查询的关键,在注解中用来指定子查询返回对象集合。
  注意:聚集元素用来处理“一对多”的关系。需要指定映射的 Java 实体类的属性,属性的 javaType(一般为 ArrayList)但是注解中可以不定义;
  使用格式:
  @Result(property="",column="",many=@Many(select=""))

2.使用注解实现一对一复杂关系映射及延迟加载

  我们之前通过加载职员信息的时候加载工牌实现一对一。

(1)添加Employee和WorkCard实体类

(2)Employee持久层接口使用注解配置 

package com.xhbjava.dao;

import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;

import com.xhbjava.domain.Employee;

/**
 * 雇员接口
 * 
 * @author Mr.wang
 * @date 2020年2月27日
 */
public interface IEmployeeDao {

    @Select("select * from t_employee where id=#{id}")
    @Results(id = "workcardMap", value = { @Result(id = true, 
            column = "id", property = "id"),
            @Result(column = "real_name", property = "real_name"),
            @Result(column = "sex", property = "sex",typeHandler=SexTypeHandler.class),
            @Result(column = "birthday", property = "birthday"),
            @Result(column = "mobile", property = "mobile"),
            @Result(column = "email", property = "email"), 
            @Result(column = "position", property = "position"), 
            @Result(column = "note", property = "note"), 
            @Result(column = "id", property = "workcard", 
            one = @One(select = "com.xhbjava.dao.IWorkCardDao.getWorkCard", fetchType = FetchType.LAZY)) })
    public Employee getEmployee(Long id);

}

(3)IWorkCardDao持久层接口使用注解配置 

package com.xhbjava.dao;
/**
 * 工牌接口
 * @author Mr.wang
 *@date    2020年2月27日
 */

import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import com.xhbjava.domain.WorkCard;

public interface IWorkCardDao {
    @Select("SELECT id, emp_id as empId, real_name as realName, department, mobile,\r\n" + 
            "        position, note FROM t_work_card" + 
            "        where emp_id = #{empId}")
    @Results(id="workCardMap",
    value= {
    @Result(id=true,column="id",property="id"),
    @Result(column="emp_id",property="empId"),
    @Result(column="real_name",property="realName"),
    @Result(column="department",property="department"),
    @Result(column="mobile",property="mobile"),
    @Result(column="position",property="position"),
    @Result(column="note",property="note")
    })
    public WorkCard getWorkCard(Long empId);
}

(4)编写测试类进行测试

@Test
    public void getEmployeeTaskByEmpId() {
        // 5.创建Dao的代理对象
        session = factory.openSession(true);
        employeeDao = session.getMapper(IEmployeeDao.class);
        Employee employee = employeeDao.getEmployee(1l);
        // System.out.println("===="+employee.getBirthday());
        logger.info(employee.getWorkcard().getDepartment());
    }

 

 

 

3.使用注解实现一对多复杂关系映射

  通过之前的例子员工和员工任务是一对多,我们进行注解配置。

(1)Employee持久层接口使用注解配置 

package com.xhbjava.dao;

import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;

import com.xhbjava.domain.Employee;
import com.xhbjava.typeHandler.SexTypeHandler;

/**
 * 雇员接口
 * 
 * @author Mr.wang
 * @date 2020年2月27日
 */
public interface IEmployeeDao {

    @Select("select * from t_employee where id=#{id}")
    @Results(id = "workcardMap", value = { @Result(id = true, 
            column = "id", property = "id"),
            @Result(column = "real_name", property = "realName"),
            @Result(column = "sex", property = "sex",typeHandler=SexTypeHandler.class),
            @Result(column = "birthday", property = "birthday"),
            @Result(column = "mobile", property = "mobile"),
            @Result(column = "email", property = "email"), 
            @Result(column = "position", property = "position"), 
            @Result(column = "note", property = "note"),
            @Result(column = "id", property = "workcard", 
            one = @One(select = "com.xhbjava.dao.IWorkCardDao.getWorkCard", fetchType = FetchType.LAZY)),
            @Result(column = "id", property = "employeeTaskList", 
            many=@Many(select = "com.xhbjava.dao.IEmployeeTaskDao.getEmployeeTaskByEmpId", fetchType = FetchType.LAZY)
                    )
                })
    public Employee getEmployee(Long id);

}

(2)IEmployeeTaskDao持久层接口使用注解配置 

package com.xhbjava.dao;

import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import com.xhbjava.domain.EmployeeTask;

/**
 * 员工任务
 * 
 * @author Mr.wang
 * @date 2020年2月27日
 */
public interface IEmployeeTaskDao {
    @Select("select id, emp_id, task_name, task_id, note from t_employee_task\r\n" + 
            "        where emp_id = #{empId}")
    @Results(id="getEmployeeTaskByEmpId",
    value= {
    @Result(id=true,column="id",property="id"),
    @Result(column="emp_id",property="empId"),
    @Result(column="task_name",property="taskName"),
    @Result(column="task_id",property="taskId"),
    @Result(column="note",property="note"),
    })
    public EmployeeTask getEmployeeTaskByEmpId(Long empid);

}

(3)编写测试类测试

@Test
    public void getEmployeeTaskByEmpId() {
        // 5.创建Dao的代理对象
        session = factory.openSession(true);
        employeeDao = session.getMapper(IEmployeeDao.class);
        Employee employee = employeeDao.getEmployee(1l);
        // System.out.println("===="+employee.getBirthday());
        logger.info(employee.getEmployeeTaskList().get(0).getTaskName());
    }

 

 

 五、基于注解的二级缓存

1.在 SqlMapConfig 中开启二级缓存支持

 

 

 2.在持久层接口中使用注解配置二级缓存

//mybatis 基于注解方式实现配置二级缓存
@CacheNamespace(blocking=true)
public interface IEmployeeDao {
    public Employee getEmployee(Long id);

}

 

 

 

workcard

posted on 2020-03-06 14:53  王小码  阅读(188)  评论(0编辑  收藏  举报