11.1 项目目录
11.2 UserMapper接口
11.2.1 查询用户(@Select)
注解 | 属性 | 说明 |
---|---|---|
@Select | value:查询SQL语句 | 查询的注解 |
@Results | value:是一个Result数组 | 定义映射关系 |
@Result | column | 定义表中列 |
property | 定义实体类中属性 | |
id | true 这是主键列,默认是false |
- 增加通过id查询用户的方法
- 方法上使用注解@Select(“SQL语句”)
- 在SQL语句使用#{id}占位符
/**
* 通过id查询1个用户
*/
@Select("select * from user where id = #{id}")
User findUserById(int id);
11.2.2 使用@Results和@Result属性
/**
* 通过id查询1个用户
*/
@Select("select * from user where id = #{id}")
@Results({
@Result(column = "id", property = "id", id = true), // 映射主键
@Result(column = "user_name", property = "username") // 映射普通列
})
User findUserById(int id);
11.2.3修改用户
- 写修改方法
- 在方法上使用注解@Update(“SQL语句”)
- 占位符使用#{属性名}
/**
* 根据用户id修改用户
*/
@Update("update user set username=#{username}, address=#{address} where id=#{id}")
int updateUser(User user);
11.2.4删除用户
- 编写删除方法
- 使用注解@Delete(“SQL”)
- 使用#{id},删除指定的用户
如果有外键约束,主表中记录不能删除。
/**
* 删除记录
*/
@Delete("delete from user where id=#{id}")
int deleteUser(Integer id);
11.2.5新增用户
- 在UserMapper接口中,增加新增用户方法
- 使用注解@Insert(“SQL语句”)
/**
* 插入一条记录
*/
@Insert("insert into user values (null, #{username},#{birthday},#{sex},#{address})")
int addUser(User user);
11.2.6 获取新增主键值
得到自增长生成的主键值
属性 | 说明 |
---|---|
statement | 获取主键的SQL语句 |
keyProperty | 实体类中主键的属性名 |
keyColumn | 表中主键列的名字 |
resultType | 主键数据类型 |
before | false 之后 true之前 |
/**
* 插入一条记录
*/
@Insert("insert into user values (null, #{username},#{birthday},#{sex},#{address})")
/**
statement:获取主键的SQL语句
keyProperty: 实体类中主键的属性名
keyColumn:表中主键列的名字
resultType:主键数据类型
before: false 之后 true之前
*/
@SelectKey(statement = "select last_insert_id()", keyProperty = "id",
keyColumn = "id", resultType = Integer.class, before = false)
int addUser(User user);
11.2.7 测试代码
package cn.guardwhy.test;
import cn.guardwhy.dao.UserMapper;
import cn.guardwhy.domain.User;
import cn.guardwhy.utils.SessionFactoryUtils;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.sql.Date;
public class TestUserMapper {
private static SqlSessionFactory factory;
private SqlSession session;
private UserMapper userMapper;
// 创建会话对象,自动提交事务
@Before
public void begin(){
session = SessionFactoryUtils.getSession();
userMapper = session.getMapper(UserMapper.class);
}
/***
* 查询操作
*/
@Test
public void testFindUserById(){
User user = userMapper.findUserById(1);
System.out.println(user);
}
/**
* 更新操作
*/
@Test
public void testUpdateUser(){
User user = new User();
user.setUsername("田甜");
user.setAddress("广州");
user.setId(4);
int row = userMapper.updateUser(user);
System.out.println("更新了" + row + "行");
}
/**
* 添加操作
*/
@Test
public void testAddUser(){
User user = new User(null, "王永强", Date.valueOf("1990-2-10"), "男", "秦阳");
int row = userMapper.addUser(user);
System.out.println("添加了" + row + "条记录");
System.out.println("生成的主键:" + user.getId());
}
// 关闭会话
@After
public void end(){
// 手动提交
session.commit();
session.close();
}
}
11.3 一对一关联查询
11.3.1 常用属性
注解 | 作用 |
---|---|
@Select | 查询操作 |
@Results | 配置一对一在关联映射 |
@Result | column:主表的主键 property:另一方属性名 one:配置关联关系 |
@One | select:查询另一张表的方法 fetchType: LAZY 延迟加载 EAGER 及时加载。 |
11.3.2 sqlMapConfig.xml
<?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="db.properties">
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="root"/>
</properties>
<!--定义实体类别名-->
<typeAliases>
<package name="cn.guardwhy.domain"/>
</typeAliases>
<environments default="default">
<!-- 环境变量 -->
<environment id="default">
<!--事务管理器 -->
<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="cn.guardwhy.dao"/>
</mappers>
</configuration>
11.3.3 UserMapper接口
package cn.guardwhy.dao;
import cn.guardwhy.domain.OrderForm;
import cn.guardwhy.domain.User;
import cn.guardwhy.domain.UserInfo;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
/**
* 持久化接口:UserMapper
*/
public interface UserMapper {
/**
* 通过id查找用户
*/
@Select("select * from user where id = #{id}")
@Results({
// column:主表的主键 property:另一方的属性名, one:配置一对一的关联关系
@Result(column = "id", property = "userInfo",
// select:读取另一个对象查询方法 fetchType:LAZY延迟加载,EAGER及时加载。
one = @One(select = "findUserInfoById", fetchType = FetchType.LAZY))
})
User findUserById(@Param("id") int id);
/**
* 通过id查询用户拓展信息
*/
@Select("select * from user_info where id = #{id}")
UserInfo findUserInfoById(int id);
}
11.3.4 测试代码
/**
一对一关联查询
1. 只查询用户名和性别
2. 同时查询用户扩展信息
*/
@Test
public void testFindUserById(){
User user = userMapper.findUserById(1);
System.out.println("用户名:" + user.getUsername());
UserInfo userInfo = user.getUserInfo();
System.out.println(userInfo);
}
11.3.5 执行结果
11.4 一对多关联查询
11.4.1 常用属性
@Result注解属性 | 说明 |
---|---|
column | 主表的主键 |
property | 另一方的属性名 |
many | 一对多的关联映射 |
@Many注解属性 | 说明 |
---|---|
select | 查询另一方的方法 |
fetchType | 指定是否是延迟加载 |
11.4.2 UserMapper接口
1、通过user_id查询当前用户订单的方法
使用@Select注解。
2、修改findUserById()方法,增加1对多延迟加载配置
在findUserById()方法修改注解。
在@Results注解中添加@Result注解。
注意:
column: 为user表中的主键id
property: 对应用户表中的订单集合属性orders
3、many为 @Many注解
select:为上面的查询方法名
fetchType:为延迟加载
代码实现
package cn.guardwhy.dao;
import cn.guardwhy.domain.OrderForm;
import cn.guardwhy.domain.User;
import cn.guardwhy.domain.UserInfo;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
/**
* 持久化接口:UserMapper
*/
public interface UserMapper {
/**
* 通过id查找用户
*/
@Select("select * from user where id = #{id}")
@Results({
// column:主表的主键 property:另一方的属性名, one:配置一对一的关联关系
@Result(column = "id", property = "userInfo",
// select:读取另一个对象查询方法 fetchType:LAZY延迟加载,EAGER及时加载。
one = @One(select = "findUserInfoById", fetchType = FetchType.LAZY)),
// 配置1对多的关系,column:主表的主键, property:方法的属性名, many:配置一对多的关联关系
@Result(column = "id", property = "orders", many = @Many(select = "findOrderByUserId"
, fetchType = FetchType.LAZY))
})
User findUserById(@Param("id") int id);
/**
* 通过userId查询这个用户所有的订单信息
*/
@Select("select * from order_form where user_id = #{userId}")
@Results({
@Result(column = "user_id", property = "userId"),
@Result(column = "create_time", property = "createTime")
})
List<OrderForm> findOrderByUserId(int userId);
}
11.4.3 测试代码
/**
一对多关联查询
1. 只查用户信息
2. 查询订单信息
*/
@Test
public void testFindUserById(){
User user = userMapper.findUserById(1);
System.out.println("用户名:" + user.getUsername());
/*UserInfo userInfo = user.getUserInfo();
System.out.println(userInfo);*/
// 1对多
List<OrderForm> orders = user.getOrders();
orders.forEach(System.out::println);
}
11.4.4 执行结果