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
2.2 eclipse window---->Perferences
3 导入Mybatis的主配置文件
在项目中创建一个 resource源文件夹,将configuration.xml拷贝
ctrl + shift + / 注释
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
解决:
- 确定一下 Java代码中 Employee.insert 和 Mapper映射文件中的 Employee.insert 是否相同
- 主配置文件中是否 加载 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语句,而是区分元素的属性
- insert元素
insert into employee(employee_id,first_name,phone_number)
values (default,#{first_name},#{phone_number})
- 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;
}
Mybatis关联关系查询
查找出一个对象时,也能查询出和这个对象关联的对象,对象和对象存在一对一和一对多关联
多表连接查询有几种连接方式?
等值连接/不等值连接
内连接
外连接:左外连接 右外连接
Mybatis接口绑定技术
用一个接口和一个Mapper映射文件绑定,接口中的方法和Mapper映射文件的SQL语句绑定,那么只要调用接口的方法就能执行绑定的SQL语句了
绑定规则:
- 在Mapper映射文件的namespace中填写接口的全类名,接口和这个Mapper映射文件就绑定了
- 接口中的方法名和Mapper中SQL语句的id一致,方法的参数类型和SQL语句的参数类型一致,那么这个方法就和这个SQL语句绑定了
public interface EmployeeDao {
public List select(Map map);
}
//获得了一个EmployeeDao接口 实现类 的对象, 实质是一个代理对象
EmployeeDao employeeDao = sqlSession.getMapper(EmployeeDao.class);
//调用employeeDao的方法
List list = employeeDao.select(map);
Mybatis的逆向工程
generatorConfig.xml
修改以下信息
运行
生成
Mybatis插件功能之PageHelper分页插件
Mybatis实现分页的方式:
1. 使用Mybatis提供的一个RowBounds类实现分页, 是对结果集的分页,而不是对表数据的分页,不推荐使用。
2. 使用SQL语句完成分页,缺点:每个查询语句都要写分页语句;不同数据库分页方式不同,编写SQL语句时比较麻烦。
3. 使用PageHelper插件实现分页,优点:写法简单而且是对表数据的分页,不需要区分数据库
PageHelper是github的分页插件
使用方式:
- 添加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());
缓存 多对多 注解开发