目录
一、引言
MyBatis 注解开发是指在 MyBatis 中使用注解来代替 XML 配置文件的方式,通过使用注解开发方式,这样我们就可以减少编写Mapper.xml映射文件了。
@Insert:执行新增操作
@Update:执行更新操作
@Delete:执行删除操作
@Select:执行查询操作,返回查询结果。
@Result:执行结果集封装
@Results:可以与@Result 一起使用,封装多个结果集。
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
二、常规XML完成CRUD
2.1. 用户实体类
package com.example.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {
private int id;
private String username;
private String password;
private Date birthday;
}
2.2. UserMapper
package com.example.mapper;
import com.example.domain.User;
import java.util.List;
public interface UserMapper {
void save(User user);
void update(User user);
void delete(int id);
User findById(int id);
List<User> findAll();
}
2.3. sqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 加载外部properties -->
<properties resource="jdbc.properties"></properties>
<settings>
<!-- 其他配置 -->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<typeAlias type="com.example.domain.User" alias="user"></typeAlias>
</typeAliases>
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- 指定方言 MySQl -->
<property name="dialect" value="mysql"/>
</plugin>
</plugins>
<!-- 数据源环境 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<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>
<mapper resource="com/example/mapper/UserMapper.xml"/>
</mappers>
</configuration>
2.4. properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=Wangzhexiao
2.5. UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper">
<insert id="save" parameterType="user">
insert into user values(#{id},#{username},#{password},#{birthday})
</insert>
<update id="update" parameterType="user">
update user set username = #{username}, password = #{password} where id = #{id}
</update>
<delete id="delete" parameterType="int">
delete from user where id = #{id}
</delete>
<select id="findById" parameterType="int" resultType="user">
select * from user where id = #{id}
</select>
<select id="findAll" resultType="user">
select * from user
</select>
</mapper>
2.6. 测试类
package com.example;
import com.example.domain.User;
import com.example.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
public class UserTest {
private UserMapper userMapper;
@Before
public void before() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
userMapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void insert() {
User user = new User();
user.setUsername("余则成");
user.setPassword("yuzecheng");
user.setBirthday(new Date());
userMapper.save(user);
}
@Test
public void delete() {
userMapper.delete(11);
}
@Test
public void update() {
User user = new User();
user.setId(1);
user.setUsername("毛泽东");
user.setPassword("maozedong");
user.setBirthday(new Date());
userMapper.update(user);
}
@Test
public void findById() {
userMapper.findById(1);
}
@Test
public void findAll() {
userMapper.findAll();
}
}
三、注解完成CRUD
上述XML方式CRUD其他相关代码不变,我们仅删除UserMapper.xml,将其中的SQL通过注解的方式,添加到UserMapper接口中的各个对应的方法上,以及将sqlMapConfig.xml中对UserMapper.xml的配置改为UserMapper接口:
3.1. UserMapper
package com.example.mapper;
import com.example.domain.User;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
public interface UserMapper {
@Insert("insert into user values(#{id},#{username},#{password},#{birthday})")
void save(User user);
@Update("update user set username = #{username}, password = #{password} where id = #{id}")
void update(User user);
@Delete("delete from user where id = #{id}")
void delete(int id);
@Select("select * from user where id = #{id}")
User findById(int id);
@Select("select * from user")
List<User> findAll();
}
3.2. sqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 加载外部properties -->
<properties resource="jdbc.properties"></properties>
<settings>
<!-- 其他配置 -->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<typeAlias type="com.example.domain.User" alias="user"></typeAlias>
</typeAliases>
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- 指定方言 MySQl -->
<property name="dialect" value="mysql"/>
</plugin>
</plugins>
<!-- 数据源环境 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<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.example.mapper"/>
</mappers>
</configuration>
查看最终控制台输出结果,效果和XML方式一样。
四、注解实现复杂映射开发
实现复杂关系映射之前我们可以在映射文件中通过配置<resultMap>来实现,使用注解开发后,我们可以使用@Results注解,@Result注解,@One注解,@Many注解组合完成复杂关系的配置。
4.1. 一对一查询模式(1)
4.1.1. OrderMapper
package com.example.mapper;
import com.example.domain.Order;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface OrderMapper {
@Select("select *, o.id oid from `order` o, user u where o.uid = u.id")
@Results({
@Result(column = "oid", property = "id"),
@Result(column = "ordertime", property = "orderTime"),
@Result(column = "total", property = "total"),
@Result(column = "uid", property = "user.id"),
@Result(column = "username", property = "user.username"),
@Result(column = "password", property = "user.password"),
})
List<Order> findAll();
}
4.1.2. sqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 加载外部properties -->
<properties resource="jdbc.properties"></properties>
<settings>
<!-- 其他配置 -->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<typeAlias type="com.example.domain.User" alias="user"></typeAlias>
</typeAliases>
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- 指定方言 MySQl -->
<property name="dialect" value="mysql"/>
</plugin>
</plugins>
<!-- 数据源环境 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<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.example.mapper"/>
</mappers>
</configuration>
4.1.3. properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=Wangzhexiao
4.1.4. 订单实体类
package com.example.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Order {
private int id;
private Date orderTime;
private double total;
private User user;
}
4.1.5. 用户实体类
package com.example.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {
private int id;
private String username;
private String password;
private Date birthday;
}
4.1.6. 测试类
package com.example;
import com.example.domain.Order;
import com.example.mapper.OrderMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class UserTest {
private OrderMapper orderMapper;
@Before
public void before() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
orderMapper = sqlSession.getMapper(OrderMapper.class);
}
@Test
public void findAll() {
List<Order> orders = orderMapper.findAll();
for (Order order : orders) {
System.out.println(order);
}
}
}
4.2. 一对一查询模式(2)
我们在一对一查询模式(1)的OrderMapper接口方法上做适当调整:
package com.example.mapper;
import com.example.domain.Order;
import com.example.domain.User;
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 java.util.List;
public interface OrderMapper {
@Select("select * from `order`")
@Results({
@Result(column = "oid", property = "id"),
@Result(column = "ordertime", property = "orderTime"),
@Result(column = "total", property = "total"),
@Result(
property = "user", // 要封装的属性名称
column = "uid", // 根据这个字段去查询user表的数据
javaType = User.class, // 要封装的实体类型
// select属性代表查询这个接口的方法获得数据
one = @One(select = "com.example.mapper.UserMapper.findById")
)
})
List<Order> findAll();
}
4.3. 一对多查询模型
4.3.1. sqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 加载外部properties -->
<properties resource="jdbc.properties"></properties>
<settings>
<!-- 其他配置 -->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<typeAlias type="com.example.domain.User" alias="user"></typeAlias>
</typeAliases>
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- 指定方言 MySQl -->
<property name="dialect" value="mysql"/>
</plugin>
</plugins>
<!-- 数据源环境 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<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.example.mapper"/>
</mappers>
</configuration>
4.3.2. properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=Wangzhexiao
4.3.3. UserMapper
package com.example.mapper;
import com.example.domain.User;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface UserMapper {
@Select("select * from user")
@Results({
@Result(column = "id", property = "id"),
@Result(column = "username", property = "username"),
@Result(column = "password", property = "password"),
@Result(
property = "orderList", // 要封装的属性名称
column = "id", // 根据这个字段去查询订单表的数据
javaType = List.class, // 要封装的实体类型
// select属性代表查询这个接口的方法获得数据
many = @Many(select = "com.example.mapper.OrderMapper.findByUid")
)
})
List<User> findUserAndOrderAll();
}
4.3.4. OrderMapper
package com.example.mapper;
import com.example.domain.Order;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface OrderMapper {
@Select("select * from `order` where uid = #{uid}")
List<Order> findByUid(int uid);
}
4.3.5. Order实体类
package com.example.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Order {
private int id;
private Date orderTime;
private double total;
private User user;
}
4.3.6. User实体类
package com.example.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Order {
private int id;
private Date orderTime;
private double total;
private User user;
}
4.4. 多对多查询模型
4.4.1. sqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 加载外部properties -->
<properties resource="jdbc.properties"></properties>
<settings>
<!-- 其他配置 -->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<typeAlias type="com.example.domain.User" alias="user"></typeAlias>
</typeAliases>
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- 指定方言 MySQl -->
<property name="dialect" value="mysql"/>
</plugin>
</plugins>
<!-- 数据源环境 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<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.example.mapper"/>
</mappers>
</configuration>
4.4.2. properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=Wangzhexiao
4.4.3. UserMapper
package com.example.mapper;
import com.example.domain.User;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface UserMapper {
@Select("select * from user")
@Results({
@Result(column = "id", property = "id"),
@Result(column = "username", property = "username"),
@Result(column = "password", property = "password"),
@Result(
property = "roleList", // 要封装的属性名称
column = "id", // 根据这个字段去查询角色表的数据
javaType = List.class, // 要封装的实体类型
// select属性代表查询这个接口的方法获得数据
many = @Many(select = "com.example.mapper.RoleMapper.findByUid")
)
})
List<User> findUserAndRoleAll();
}
4.4.4. RoleMapper
package com.example.mapper;
import com.example.domain.Role;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface RoleMapper {
@Select("select * from user_role ur, role r where ur.role_id = r.id and ur.user_id = #{uid}")
List<Role> findByUid(int uid);
}
4.4.5. Role实体类
package com.example.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Role {
private int id;
private String roleName;
private String roleDesc;
}
4.4.6. User实体类
package com.example.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.Date;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {
private int id;
private String username;
private String password;
private Date birthday;
// 描述当前用户具有多个角色
private List<Role> roleList;
}