MyBatisの純粋なアノテーションメソッドは元のマッパーファイルを削除し、エンティティクラスの構成ファイルを書き込む必要はなく、クエリステートメントをインターフェイスに直接書き込みます。SqlMapperConfig.xmlでは、インターフェイスがあるパッケージを指定するだけで済みます。あります。次に、ケース部門と従業員を使用して、純粋なアノテーション開発を実装します。
(1)Mavenプロジェクトを作成し、jarパッケージをインポートします。
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.25</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
(2)データベースファイルの準備。
t_deptファイル:
CREATE TABLE `t_dept` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`dept_name` varchar(20) DEFAULT NULL,
`dept_desc` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
);
insert into t_dept(dept_name, dept_age) values("开发部","软件开发");
insert into t_dept(dept_name, dept_age) values("测试部","软件测试");
insert into t_dept(dept_name, dept_age) values("财务部","发放钱财");
insert into t_dept(dept_name, dept_age) values("人事部","招聘员工");
t_empファイル:
CREATE TABLE `t_emp` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`emp_name` varchar(20) DEFAULT NULL,
`emp_age` int(11) DEFAULT NULL,
`dept_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `dept_id` (`dept_id`),
CONSTRAINT `t_emp_ibfk_1` FOREIGN KEY (`dept_id`) REFERENCES `t_dept` (`id`)
);
INSERT INTO `t_emp` VALUES (1,'张倩',22,2),(2,'杨帆',24,1),(3,'章飞',21,3),(4,'李冰',51,4),(5,'王猛',36,3),(6,'康生',26,1),(7,'刘婷',20,3),(8,'刘羽',22,2);
(3)daoパッケージの下にエンティティクラスemployeeクラスとdepartmentクラスを作成します。
部門カテゴリ:
public class Department {
private Integer id;
private String deptName;
private String deptDesc;
private List<Emp> empList;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public String getDeptDesc() {
return deptDesc;
}
public void setDeptDesc(String deptDesc) {
this.deptDesc = deptDesc;
}
public List<Emp> getEmpList() {
return empList;
}
public void setEmpList(List<Emp> empList) {
this.empList = empList;
}
@Override
public String toString() {
return "Department{" +
"id=" + id +
", deptName='" + deptName + '\'' +
", deptDesc='" + deptDesc + '\'' +
", empList=" + empList +
'}';
}
}
スタッフカテゴリー:
public class Emp {
private Integer id;
private String empName;
private Integer empAge;
private Integer deptId;
public Emp() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Integer getEmpAge() {
return empAge;
}
public void setEmpAge(Integer empAge) {
this.empAge = empAge;
}
public Integer getDeptId() {
return deptId;
}
public void setDeptId(Integer deptId) {
this.deptId = deptId;
}
@Override
public String toString() {
return "Staff{" +
"id=" + id +
", empName='" + empName + '\'' +
", empAge=" + empAge +
", deptId=" + deptId +
'}';
}
}
(4)daoパッケージの下にIDepartmentDaoとIEmpDaoを作成します。
IDepartmentDao:
public interface IDepartmentDao {
@Select(value = "select * from t_dept")
@Results(value = {
@Result(id=true, column = "id", property = "id"),
@Result(column = "dept_name", property = "deptName"),
@Result(column = "dept_desc", property = "deptDesc"),
@Result(column = "id", property = "empList", javaType = List.class,many = @Many(select = "com.dao.IEmpDao.findByDeptId"))
})
List<Department> findAll();
@Select(value = "select * from t_dept where id = #{id}")
@Results(value = {
@Result(id=true, column = "id", property = "id"),
@Result(column = "dept_name", property = "deptName"),
@Result(column = "dept_desc", property = "deptDesc")
})
List<Department> findById(int id);
}
IEmpDao:
public interface IEmpDao {
@Select("select * from t_emp")
@Results(id = "empMap",value={
@Result(id=true, column = "id", property = "id"),
@Result(column = "emp_name", property = "empName"),
@Result(column = "emp_age", property = "empAge"),
@Result(property = "department", column = "dept_id", one = @One(select = "com.dao.IDepartmentDao.findById", fetchType = FetchType.EAGER))
})
List<Emp> findDepartment();
@Select("select * from t_emp where id = #{id}")
@Results(value={
@Result(id=true, column = "id", property = "id"),
@Result(column = "emp_name", property = "empName"),
@Result(column = "emp_age", property = "empAge"),
})
List<Emp> findByDeptId(int id);
}
(5)リソースディレクトリにlog4j.propertiesとSqlMapperConfig.xmlをインポートします。
log4j.properties:
### 设置###
log4j.rootLogger = debug,stdout
### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
pender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
SqlMapperConfig.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>
<!-- 配置环境 -->
<environments default="mysql">
<!-- 配置MySQL的环境 -->
<environment id="mysql">
<!-- 配置事务的类型 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源(连接池) -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///universaldb"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--接口的注册-->
<!--之前是配置实体类的映射文件,现在没有了,直接配置接口-->
<mappers>
<package name="com.dao"/>
</mappers>
</configuration>
(6)テストクラスを作成する
package com;
import com.dao.IDepartmentDao;
import com.dao.IEmpDao;
import com.entity.Department;
import com.entity.Emp;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* 功能描述:
*
* @Author: aaa
* @Date: 2021/2/18 11:33
*/
public class TestAnno {
InputStream in = null;
SqlSessionFactoryBuilder builder = null;
SqlSessionFactory factory = null;
SqlSession sqlSession = null;
@Before
public void init() throws IOException {
//1、读取配置文件
in = Resources.getResourceAsStream("SqlMapperConfig.xml");
//2、创建SqlSessionFactory工厂
builder = new SqlSessionFactoryBuilder();
factory = builder.build(in);
//3、使用工厂生产SqlSession对象
sqlSession = factory.openSession();
}
@After
public void destory() throws IOException {
sqlSession.commit();
sqlSession.close();
in.close();
}
@Test
public void testDeptAll(){
IDepartmentDao departmentDao = sqlSession.getMapper(IDepartmentDao.class);
List<Department> departmentList = departmentDao.findAll();
System.out.println(departmentList);
}
@Test
public void testeMPAll(){
IEmpDao staffAnnoDao = sqlSession.getMapper(IEmpDao.class);
List<Emp> empList = staffAnnoDao.findDepartment();
System.out.println(empList);
}
}
MyBatisマルチパラメータクエリのアノテーション開発方法は次のとおりです。
@Select("select * from t_people where name=#{name} and address=#{address}")
List<People> findByMorePara(@Param("name") String name, @Param("address") String address);
上記はMyBatisアノテーション開発の場合です。
総括する:
1. @ Resultsの各属性の意味
(1)idは、現在の結果セット宣言の一意の識別子です。
(2)値は、結果セットのマッピング関係です。
(3)@Resultは、フィールドのマッピング関係を表します。
- columnは、データベースフィールドの名前を指定します。
- プロパティは、エンティティクラス属性の名前を指定します。
- dbcTypeデータベースフィールドタイプ。@ Resultのid値は主キーを示すためにtrueであり、デフォルトはfalseです。
(4)@ResultMapを使用して、値を省略できるマッピング結果セットを参照します。この@Resultsコードを複数のメソッドで使用する必要がある場合、コードの再利用性を向上させるために、この@ResultsアノテーションのIDを設定してから、@ ResultMapアノテーションを使用してこのコードを再利用できます。
(5)ケース:
@Select(value = "select * from t_dept")
@Results(value = {
@Result(id=true, column = "id", property = "id"),
@Result(column = "dept_name", property = "deptName"),
@Result(column = "dept_desc", property = "deptDesc")
})
List<Department> findAll();
2.1つおよび複数の使用法
(1)1つの使用法
フィールド値をパラメーターとして使用して関連コンテンツをクエリする別のメソッドを実行する必要があり、2つが1対1の関係にある場合、@ Oneアノテーションを使用してこれを容易にすることができます。たとえば、学生情報とそれらが属するクラス情報をクエリする必要がある場合、クエリされたclass_idをパラメータとして使用して、ClassesMapperのselectByIdメソッドを実行し、学生が属するクラス情報を取得する必要があります。
場合:
@Select("select * from t_emp")
@Results(id = "empMap",value={
@Result(id=true, column = "id", property = "id"),
@Result(column = "emp_name", property = "empName"),
@Result(column = "emp_age", property = "empAge"),
@Result(property = "department", column = "dept_id", one = @One(select = "com.dao.IDepartmentDao.findById", fetchType = FetchType.EAGER))
})
List<Emp> findDepartment();
(2)多くの使用法
@Oneと同様ですが、@ Oneを使用したクエリの結果が複数の行である場合、TooManyResultExceptionがスローされます。この場合、@ Manyアノテーションを使用して1対多のクエリを実行する必要があります。たとえば、各試験の学生情報とスコア情報を照会する必要がある場合です。
場合:
@Select(value = "select * from t_dept")
@Results(value = {
@Result(id=true, column = "id", property = "id"),
@Result(column = "dept_name", property = "deptName"),
@Result(column = "dept_desc", property = "deptDesc"),
@Result(column = "id", property = "empList", javaType = List.class,many = @Many(select = "com.dao.IEmpDao.findByDeptId"))
})
List<Department> findAll();
エラーの要約:
问题一:結果マップコレクションには、com.dao.IEmpDao.empMapの値がすでに含まれています。
理由: IEmpDaoにID「empMap」のresultMap値があります
質問2:MyBatisは、1対多の結果を1つだけ表示します。
理由: 1対多操作の2つのテーブルで、主キー名が同じである場合は、異なる主キー名に設定する必要があります。つまり、エンティティクラスの属性名は同じにすることができ、データベースの列名は異なる必要があります。例:employeeテーブルの主キーはidであり、departmentテーブルの主キーもidであるため、上記の問題が発生します。従業員テーブルの主キーがemp_idに変更され、部門テーブルの主キーがdept_idに変更された場合、この問題はトリガーされません。