MyBatis框架搭建 - DAY3、DAY4、DAY5

1.创建Maven工程,导入Mybatis依赖以及mysql数据库驱动的依赖

https://mvnrepository.com/

 
    
      junit
      junit
      4.12
      test
    
    
        org.mybatis
        mybatis
        3.4.6
    
    
        mysql
        mysql-connector-java
        5.1.38
       
  

2.eclipse中配置两个xml配置文件的元素校验 (只配置一次,在开发的时候使用)


http://mybatis.org/dtd/mybatis-3-config.dtd和 mybatis-3-config.dtd 在eclipse中形成配置映射

http://mybatis.org/dtd/mybatis-3-mapper.dtd 和 mybatis-3-mapper.dtd 形成映射

2.1

image.png

2.2 eclipse window---->Perferences

image.png

image.png

3 导入Mybatis的主配置文件

在项目中创建一个 resource源文件夹,将configuration.xml拷贝


image.png




    
    
    
    
    
       
           
           
              
              
              
              
           
       
    
    
    
       
    

ctrl + shift + / 注释


image.png

employee 表

/*
Navicat MySQL Data Transfer

Source Server         : local
Source Server Version : 50728
Source Host           : 127.0.0.1:3306
Source Database       : test1913

Target Server Type    : MYSQL
Target Server Version : 50728
File Encoding         : 65001

Date: 2020-06-10 14:07:29
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for employee
-- ----------------------------
DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee` (
  `employee_id` int(11) NOT NULL AUTO_INCREMENT,
  `first_name` varchar(20) NOT NULL,
  `last_name` varchar(25) DEFAULT NULL,
  `email` varchar(25) DEFAULT NULL,
  `phone_number` varchar(20) NOT NULL,
  `hire_date` date DEFAULT NULL,
  `job_id` varchar(10) DEFAULT NULL,
  `salary` float(8,2) DEFAULT NULL,
  `commission_pct` float(4,2) DEFAULT NULL,
  `manager_id` int(11) DEFAULT NULL,
  `department_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`employee_id`)
) ENGINE=InnoDB AUTO_INCREMENT=302 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of employee
-- ----------------------------
INSERT INTO `employee` VALUES ('100', 'tom2', 'a', '', '15945742131', '2011-05-18', '财务主管', '9000.00', null, '110', '5001');
INSERT INTO `employee` VALUES ('101', 'jim', 'a', '', '15945742432', '2011-05-18', '技术总监', '9000.00', null, '110', '5002');
INSERT INTO `employee` VALUES ('102', 'zion', 'a', '', '15945742230', '2011-05-18', '市场总监', '10500.00', '3.20', '110', '5003');
INSERT INTO `employee` VALUES ('103', 'charles', 'a', '', '15945742231', '2010-05-14', '财务总监', '27000.00', '3.10', '100', '5001');
INSERT INTO `employee` VALUES ('104', 'john', '', '', '15945742232', '2001-09-18', '出纳', '4000.00', '1.50', '100', '5001');
INSERT INTO `employee` VALUES ('105', 'rose', '', '', '13946158745', '2008-09-20', '项目经理', '6000.00', '1.40', '101', '5002');
INSERT INTO `employee` VALUES ('106', 'white', '', '', '13946158744', '2010-10-10', '程序员', '4000.00', '1.50', '101', '5002');
INSERT INTO `employee` VALUES ('107', 'cherry', '', '', '13946151874', '2009-03-28', '程序员', '5500.00', '2.70', '101', '5002');
INSERT INTO `employee` VALUES ('108', 'hott', '', '', '13955696521', '2008-08-08', '程序员', '6000.00', '0.70', '101', '5002');
INSERT INTO `employee` VALUES ('109', 'hawk', '', '', '13955691521', '2007-05-09', '市场助理', '5800.00', '1.20', '102', '5003');
INSERT INTO `employee` VALUES ('110', 'ww', '', '', '13758525114', '2000-05-12', '总经理', '10000.00', '3.10', null, null);
INSERT INTO `employee` VALUES ('111', 'jack', '', '', '13758525524', '2000-11-11', '市场助理', '3600.00', '2.10', '102', '5003');

departments 表

/*
Navicat MySQL Data Transfer

Source Server         : local
Source Server Version : 50728
Source Host           : 127.0.0.1:3306
Source Database       : test1913

Target Server Type    : MYSQL
Target Server Version : 50728
File Encoding         : 65001

Date: 2020-06-10 14:07:19
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for departments
-- ----------------------------
DROP TABLE IF EXISTS `departments`;
CREATE TABLE `departments` (
  `department_id` int(11) NOT NULL AUTO_INCREMENT,
  `department_name` varchar(30) NOT NULL,
  `manager_id` int(11) DEFAULT NULL,
  `location_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`department_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5011 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of departments
-- ----------------------------
INSERT INTO `departments` VALUES ('5001', '财务部', '100', '1001');
INSERT INTO `departments` VALUES ('5002', '软件部', '101', '1003');
INSERT INTO `departments` VALUES ('5003', '市场部', '102', '1002');
INSERT INTO `departments` VALUES ('5004', '人力资源部', null, '1004');
INSERT INTO `departments` VALUES ('5010', '行政部2', null, null);

4.创建Employee表的实体类,创建EmployeeMapper.xml映射文件

要求:com.oracle.entity.Employee实体类中的属性名和表中的列名相同

package com.oracle.entity;

import java.util.Date;

public class Employee {
    private int employee_id;
    private String first_name;
    private String phone_number;
    private Date hire_date;
    private String job_id;
    private double salary;
    private int department_id;
    public int getEmployee_id() {
        return employee_id;
    }
    public void setEmployee_id(int employee_id) {
        this.employee_id = employee_id;
    }
    public String getFirst_name() {
        return first_name;
    }
    public void setFirst_name(String first_name) {
        this.first_name = first_name;
    }
    public String getPhone_number() {
        return phone_number;
    }
    public void setPhone_number(String phone_number) {
        this.phone_number = phone_number;
    }
    public Date getHire_date() {
        return hire_date;
    }
    public void setHire_date(Date hire_date) {
        this.hire_date = hire_date;
    }
    public String getJob_id() {
        return job_id;
    }
    public void setJob_id(String job_id) {
        this.job_id = job_id;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    public int getDepartment_id() {
        return department_id;
    }
    public void setDepartment_id(int department_id) {
        this.department_id = department_id;
    }
    
}




    
    
        insert into employee(employee_id,first_name,phone_number)
        values (default,#{first_name},#{phone_number})
    
    

5 使用Mybatis的API 执行指定的SQL语句

package com.zps.mybatis01;

import java.io.IOException;
import java.io.Reader;

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 com.zps.entity.Employee;

public class Main {
     public static void main(String[] args) {
         try {
            //将主配置文件configuration.xml读取到Reader对象中
            Reader reader = Resources.getResourceAsReader("configuration.xml");
            //创建SQLSessionFactory对象,SqlSessionFactoryBuilder的build方法加载主配置文件内容
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
            //通过SQLSessionFactory创建SqlSession对象(封装了Connection)也是Mybatis框架的核心API
            SqlSession sqlSession = factory.openSession();
            //调用EmployeeMapper.xml中id是Employee.insert的SQL语句,并传入一个要插入的对象
            //例如 要插入的数据为 tom,13312345678,那么要创建一个Employee对象,赋其属性
            Employee employee = new Employee();
            employee.setFirst_name("tom");
            employee.setPhone_number("13312345678");
            //调用SqlSession的insert方法执行指定的SQL语句并传入employee对象
            sqlSession.insert("Employee.insert",employee);
            //sqlSession需要手动提交
            sqlSession.commit();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
     }
}

可能会出现的错误,解决方案

### Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for Employee.insert
    at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:200)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:185)
    at com.oracle.mybatis01.Main.main(Main.java:28)
Caused by: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for Employee.insert
    at org.apache.ibatis.session.Configuration$StrictMap.get(Configuration.java:888)
    at org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:721)
    at org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:714)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:197)
    ... 2 more

解决:

  1. 确定一下 Java代码中 Employee.insert 和 Mapper映射文件中的 Employee.insert 是否相同
  2. 主配置文件中是否 加载 Mapper映射文件
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'first_nam' in 'field list'
    at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:200)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:185)
    at com.oracle.mybatis01.Main.main(Main.java:28)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'first_nam' in 'field list'
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
    at com.mysql.jdbc.Util.getInstance(Util.java:387)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:939)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3878)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
    at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1192)
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:46)
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:74)
    at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:50)
    at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
    at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198)
    ... 2 more

解决:

​ 明显的SQL语句错误,检查Mapper中的SQL语句

### Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'firstName' in 'class com.oracle.entity.Employee'
    at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:200)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:185)
    at com.oracle.mybatis01.Main.main(Main.java:28)
Caused by: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'firstName' in 'class com.oracle.entity.Employee'
    at org.apache.ibatis.reflection.Reflector.getGetInvoker(Reflector.java:419)
    at org.apache.ibatis.reflection.MetaClass.getGetInvoker(MetaClass.java:164)
    at org.apache.ibatis.reflection.wrapper.BeanWrapper.getBeanProperty(BeanWrapper.java:162)
    at org.apache.ibatis.reflection.wrapper.BeanWrapper.get(BeanWrapper.java:49)
    at org.apache.ibatis.reflection.MetaObject.getValue(MetaObject.java:122)
    at org.apache.ibatis.scripting.defaults.DefaultParameterHandler.setParameters(DefaultParameterHandler.java:79)
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.parameterize(PreparedStatementHandler.java:93)
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.parameterize(RoutingStatementHandler.java:64)
    at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:86)
    at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:49)
    at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
    at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198)
    ... 2 more

解决:

​ 在映射文件中找#{} 表达式,查找写的属性是否正确

主配置文件配置元素

配置别名:配置类的全类名的别名


        

Mapper映射文件中的元素

insert、update、delete、select元素实质并不是区分SQL语句,而是区分元素的属性

  1. insert元素
  
    
        insert into employee(employee_id,first_name,phone_number)
        values (default,#{first_name},#{phone_number})
    
  1. update元素
    
        update employee set first_name = #{first_name},phone_number=#{phone_number},job_id = #{job_id},
        salary = #{salary} where employee_id = #{employee_id}
    

        update employee 
        
            
                first_name = #{first_name},
            
            
                phone_number = #{phone_number},
            
            
                job_id = #{job_id},
            
            
                salary = #{salary},
            
        
        where employee_id = #{employee_id}
    

使用动态SQL :

3.select元素


  
//按id查询
          Employee employee = sqlSession.selectOne("Employee.selectById", 100);
          System.out.println(employee.getFirst_name()+","+employee.getPhone_number());

    
  Map map = new HashMap();
          //按姓名查询
          map.put("first_name", "%a%");
          //map.put("phone_number", "13758525524");
          List list = sqlSession.selectList("Employee.select", map);
          for(Employee e:list) {
              System.out.println(e.getFirst_name());
          }

4.delete元素


  
      delete from employee where employee_id = #{id}
  
  
  
      delete from employee where employee_id in 
      
          #{item}
      
  
//数组
//              int[] ids = new int[] {112,113}; // int[] array
//集合
sqlSession.delete("Employee.delete", 302);
            List list = new ArrayList();    
            Collections.addAll(list, 114,115);
            sqlSession.delete("Employee.deleteBatch",list);
            sqlSession.commit();

5.ResultMap元素:结果映射 ,当使用select元素中的resultType时,将结果集一行的数据注入到一个对象中,按照结果集列名和对象属性名相同比对方式来向对象的属性中注入值,但是当对象的属性名和结果集的列名不一致时,或出现了关联关系查询时,不能使用resultType

ResultMap是 自定义的结果映射,当查询时可以使用resultType属性也可以使用resultMap属性,在resultMap属性中指定自定义结果映射的id

public int getEmployee_id() {
        return employee_id;
    }
    public void setEmployee_id(int employee_id) {
        this.employee_id = employee_id;
    }
    public String getFirst_name() {
        return first_name;
    }
    public void setFirst_name(String first_name) {
        this.first_name = first_name;
    }
    public String getPhone_number() {
        return phone_number;
    }
    public void setPhone_number(String phone_number) {
        this.phone_number = phone_number;
    }
    public Date getHire_date() {
        return hire_date;
    }
    public void setHire_date(Date hire_date) {
        this.hire_date = hire_date;
    }
    public String getJob_id() {
        return job_id;
    }
    public void setJob_id(String job_id) {
        this.job_id = job_id;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    public int getDepartment_id() {
        return department_id;
    }
    public void setDepartment_id(int department_id) {
        this.department_id = department_id;
    }

        
        
        
        
        
        
    
      
        select * from employee e left outer join departments d on e.department_id = d.department_id
                 
            
                and first_name like #{first_name}
            
            
                and phone_number = #{phone_number}
            
        
           
public interface EmployeeDao {
    public List select(Map map);
}
                //获得了一个EmployeeDao接口 实现类 的对象, 实质是一个代理对象
            EmployeeDao employeeDao = sqlSession.getMapper(EmployeeDao.class);
            //调用employeeDao的方法
            List list = employeeDao.select(map);

Mybatis的逆向工程

image.png

generatorConfig.xml





    
        
            
            
        
        
        
        
        

        
        
            
        

        
        
            
            
            
            
        
        
        
            
            
        
        
        
            
            
        
        
        
修改以下信息


 


运行
image.png

生成
image.png

Mybatis插件功能之PageHelper分页插件

Mybatis实现分页的方式:

1. 使用Mybatis提供的一个RowBounds类实现分页, 是对结果集的分页,而不是对表数据的分页,不推荐使用。
   2. 使用SQL语句完成分页,缺点:每个查询语句都要写分页语句;不同数据库分页方式不同,编写SQL语句时比较麻烦。
   3. 使用PageHelper插件实现分页,优点:写法简单而且是对表数据的分页,不需要区分数据库

PageHelper是github的分页插件

使用方式:

  1. 添加PageHelper依赖,在Mybatis主配置文件中添加PageHelper的插件
    
            com.github.pagehelper
            pagehelper
            5.1.4
        
 
    
        
            
            
        
    

2.调用PageHelper的API实现分页

PageHelper.startPage(2, 5);
            //5001部门工资大于5000的员工
            EmployeeExample example = new EmployeeExample();
            List list = employeeMapper.selectByExample(example);
            for(Employee e:list) {
                System.out.println(e.getFirstName());
            }
            //pageInfo中封装了查询的结果list  ,还封装了分页的所有信息,包括页数、每页的记录数、总记录数、总页数
            PageInfo pageInfo = new PageInfo(list);
            System.out.println("页数:"+pageInfo.getPageNum()+",每页记录数:"+pageInfo.getPageSize()+
                    ",总记录数:"+pageInfo.getTotal()+",总页数:"+pageInfo.getPages());

缓存 多对多 注解开发

你可能感兴趣的:(MyBatis框架搭建 - DAY3、DAY4、DAY5)