赞
踩
MyBatis的纯注解方式去掉了原来的mapper文件,不用写实体类的配置文件,直接在接口里面写查询语句,在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包下创建实体类员工类和部门类。
部门类:
- 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)在resources目录下引入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)value值为结果集映射关系。
(3)@Result代表一个字段的映射关系。
(4)使用@ResultMap来引用映射结果集,其中value可省略。当这段@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、one和Many的用法
(1)One的用法
当我们需要通过查询到的一个字段值作为参数,去执行另外一个方法来查询关联的内容,而且两者是一对一关系时,可以使用@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)Many的用法
与@One类似,只不过如果使用@One查询到的结果是多行,会抛出TooManyResultException异常,这种时候应该使用的是@Many注解,实现一对多的查询。比如在需要查询学生信息和每次考试的成绩信息时.
案例:
- @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();
错误总结:
问题一:Result Maps collection already contains value for com.dao.IEmpDao.empMap。
原因:在IEmpDao中存在id为"empMap"的resultMap值
问题二:MyBatis一对多只显示一个结果的问题。
原因:在一对多操作中的两张表,它们的主键名称相同引发的问题,只要设置为不同的主键名称就可以了。即:实体类的属性名可以相同,数据库的列名要不同。例如:员工表的主键为id,部门表的主键也为id,就会引发上面的问题。如果员工表的主键改为emp_id,部门表的主键改为dept_id,则不会触发此问题。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。