概述
在注解开发中,我们常用到以下几种注解
@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result一起使用, 封装多个结果集
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
注解开发实现简单的增删改查
MyBatis在配置文件开发中,我们需要为每个实体类编写映射的配置文件,在配置文件中进行配置,才可以对其相关数据库进行操作。在注解开发中,我们不需要编写映射配置文件。
这里用到以下几个注解:
@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
环境搭建
jar包坐标:
<build>
<plugins>
<!-- 指定jdk -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<skip>true</skip>
<source>9</source>
<target>9</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
然后:
user数据库:
然后user实体类:
public class User {
private int id;
private String username;
private String password;
private Date birthday;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", birthday=" + birthday +
'}';
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
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 getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
实现
然后:
直接在编写接口实现代理开发的时候使用注解即可:
使用方法就是在接口的虚拟方法上加上注解,然后注解的参数设置为对应的sql语句即可
然后在核心配置文件的地方需要做一个小改动:
用package标签,然后name属性选择接口所在的包。注意看注释
核心配置文件的全部代码:
<?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="jdbc.properties"/>
<!-- 为类型设置别名-->
<typeAliases>
<typeAlias type="com.it_LYH.domain.User" alias="user"/>
</typeAliases>
<!-- 注册类型转换器-->
<typeHandlers>
<typeHandler handler="com.it_LYH.handler.DateTypeHandler"/>
</typeHandlers>
<!-- 1. 配置数据源环境-->
<environments default="development">
<!-- 此标签中可以配置多种的数据源环境,他的default属性是设置默认使用数据源环境-->
<environment id="development">
<transactionManager type="JDBC"/> <!-- 设置事务管理器 这里设置为JDBC,表示使用原生的JDBC -->
<dataSource type="POOLED"> <!-- 配置数据源 这里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属性选择接口所在的包-->
<package name="com.it_LYH.Dao"/>
</mappers>
<!-- 然后配置映射关系的xml文件可以全部删除-->
</configuration>
测试代码:
public class MapperTest {
@Test
public void test() throws IOException {
InputStream resource = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resource);
SqlSession session = build.openSession(true);
UserMapper mapper = session.getMapper(UserMapper.class);
// 查找全部
List<User> all = mapper.findAll();
for (User user : all) {
System.out.println(user);
}
//查找一条
System.out.println(mapper.findOne(2));
//删除id为12
mapper.delete(12);
// 修改
User user=new User();
user.setBirthday(new Date());
user.setPassword("456");
user.setUsername("老二");
user.setId(2);
mapper.update(user);
System.out.println(mapper.findOne(2));
// 存储
User user01=new User();
user01.setBirthday(new Date());
user01.setPassword("456789");
user01.setUsername("老大");
mapper.save(user01);
}
public void findAll(){
List<User> all = mapper.findAll();
for (User user : all) {
System.out.println(user);
}
}
@Test
public void findOne(){
System.out.println(mapper.findOne(2));
}
@Test
public void delete(){
mapper.delete(3);
}
@Test
public void update(){
User user=new User();
user.setBirthday(new Date());
user.setPassword("456");
user.setUsername("老二");
user.setId(2);
mapper.update(user);
System.out.println(mapper.findOne(2));
}
@Test
public void save(){
User user=new User();
user.setBirthday(new Date());
user.setPassword("456789");
user.setUsername("老大");
mapper.save(user);
}
}
结果:
一对一复杂查询
这里涉及到这三个注解的使用:
@Result:实现结果集封装
@Results:可以与@Result一起使用, 封装多个结果集
@One:实现一对一结果集封装
环境搭建
还是之前的那个User和Order实体类,然后有主外键,一个Order只能一个User拥有
然后:注解也是用在接口的虚拟方法上的。
上面的语句是直接查询出所有的结果,这里我们可以间接来查询出所有的结果。
即,当查询记录的时候,先查询出orders表的数据,然后根据其外键的字段(uid),来对user01表进行根据id的查询,这样写
这个是:"com.it_LYH.Dao.UserMapper.findOne"的那个方法
一般开发中,这种的我们更常用
实现
一对多的复杂查询
@Many:实现一对多结果集封装
首先,还是那两个实体类,不过这次,我们从User的角度出发,一个用户User可以有多个订单Order,但是一个订单只能有一个用户。orders表的外键uid是user01表的主键即id
User实体及表:
Order实体及表:
最后的那个属性此处我们不用在意
下面是表:
然后:
这里,我们的需求是:在查询用户的同时把它所拥有的订单信息也给查询出来:
看User的代理开发的接口:
看"com.it_LYH.Dao.OrderMapper.findById"方法:这里其实就是先查询出User01表中的数据,再根据每条记录的id(在orders表中的uid字段),在orders表中进行查询,把查询出的结果一并封装到User01对应的记录中
然后测试:
多对多表复杂查询
这里还是用到@Many注解。操作和一对多查询类似
这里,我们两个实体:一个User用户实体。一个Role角色实体。
一个User可以有多个角色,一个Role可以供过个用户拥有。
然后User实体和表:里面的orderList忽略,不用管
Role实体和表:
然后其实我们还有一个表用来存储User表和Role表之间的关系,如下:
首先,三个表的关系:uid外键设置的是user01表的主键,rid外键设置的是role表的主键
然后:我们的需求:
在查询User所有用户信息的同时查询出此用户在role中所对应的角色。
策略:先查询user01表,然后根据user01表的主键信息,再通过r_u关系表查询到role表中对应的数据
如下:
User的代理接口:
"com.it_LYH.Dao.RoleMapper.findByRid"的方法:
测试:
结束