CREATE TABLE `tabple_emp` (
`emp_id` int NOT NULL AUTO_INCREMENT,
`emp_name` VARCHAR ( 500 ) NULL,
`emp_salary` DOUBLE ( 15, 5 ) NULL,
`emp_age` int NULL,
PRIMARY KEY ( `emp_id` )
);
INSERT INTO `tabple_emp` ( `emp_name`, `emp_salary`, `emp_age` )
VALUES
( 'tom', '1254.37', '27' );
INSERT INTO `tabple_emp` ( `emp_name`, `emp_salary`, `emp_age` )
VALUES
( 'jerry', '6635.42', '38' );
INSERT INTO `tabple_emp` ( `emp_name`, `emp_salary`, `emp_age` )
VALUES
( 'bob', '5560.11', '40' );
INSERT INTO `tabple_emp` ( `emp_name`, `emp_salary`, `emp_age` )
VALUES
( 'kate', '2209.11', '22' );
INSERT INTO `tabple_emp` ( `emp_name`, `emp_salary`, `emp_age` )
VALUES
( 'justin', '4203.15', '30' );
3、创建java实体类
考虑到基本数据类型在 Java 类中都有默认值,会导致 MyBatis 在执行相关操作时很难判断当前字段是否为 null,所以在 MyBatis 环境下使用 Java 实体类时尽量不要使用基本数据类型,都使用对应的包装类型。
@Table(name="tabple_emp")
public class Employee {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer empId;//emp_id
private String empName;//emp_name
@Column(name="emp_salary")
private Double empSalary;//emp_salary
private Integer empAge;//emp_age
public Employee() {
}
public Employee(Integer empId, String empName, Double empSalary, Integer empAge) {
super();
this.empId = empId;
this.empName = empName;
this.empSalary = empSalary;
this.empAge = empAge;
}
@Override
public String toString() {
return "Employee [empId=" + empId + ", empName=" + empName + ", empSalary=" + empSalary + ", empAge=" + empAge
+ "]";
}
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Double getEmpSalary() {
return empSalary;
}
public void setEmpSalary(Double empSalary) {
this.empSalary = empSalary;
}
public Integer getEmpAge() {
return empAge;
}
public void setEmpAge(Integer empAge) {
this.empAge = empAge;
}
}
@Table 注解
作用:建立实体类和数据库表之间的对应关系。
默认规则:实体类类名首字母小写作为表名。Employee 类→employee 表。
用法:在@Table 注解的 name 属性中指定目标数据库表的表名
@Column 注解
作用:建立实体类字段和数据库表字段之间的对应关系。
默认规则:
实体类字段:驼峰式命名
数据库表字段:使用“_”区分各个单词
用法:在@Column 注解的 name 属性中指定目标字段的字段名
@Id注解
通用 Mapper 在执行 xxxByPrimaryKey(key)方法时,有两种情况。
情况 1:没有使用@Id 注解明确指定主键字段
SELECT emp_id,emp_name,emp_salary_apple,emp_age FROM tabple_emp WHERE emp_id = ? AND emp_name=? AND emp_salary_apple=? AND emp_age=?
之所以会生成上面这样的 WHERE 子句是因为通用 Mapper 将实体类中的所有字段都拿来放在一起作为联合主键。
情况 2:使用@Id 主键明确标记和数据库表中主键字段对应的实体类字段。
@GeneratedValue 注解
作用:让通用 Mapper 在执行 insert 操作之后将数据库自动生成的主键值回写到实体类对象中。
@Transient注解
用于标记不与数据库表字段对应的实体类字段。
@Transient
private String otherThings;//非数据库表中字段
4、搭建 MyBatis+Spring 开发环境
创建jdbc.porperties文件
jdbc.user=root
jdbc.password=root
jdbc.url=jdbc:mysql://localhost:3306/mapper?useUnicode=true&characterEncoding=utf8
jdbc.driver=com.mysql.jdbc.Driver
创建spring配置文件spring-context.xml
测试数据库连接:
public class MapperTest {
private ApplicationContext iocContainer = new ClassPathXmlApplicationContext("spring-context.xml");
@Test
public void testDataSource() throws SQLException {
DataSource dataSource = iocContainer.getBean(DataSource.class);
Connection connection = dataSource.getConnection();
System.out.println(connection);
}
}
tk.mybatis
mapper
4.0.0-beta3
修改 Spring 配置文件
6、编写EmployeeMapper
/**
* 具体操作数据库的Mapper接口,需要继承通用Mapper提供的核心接口:Mapper
* 泛型类型就是实体类的类型
*/
public interface EmployeeMapper extends Mapper {
}
7、编写EmployeeService
@Service
public class EmployeeService {
@Autowired
private EmployeeMapper employeeMapper;
public Employee getOne(Employee employeeQueryCondition) {
return employeeMapper.selectOne(employeeQueryCondition);
}
public Employee getEmployeeById(Integer empId) {
return employeeMapper.selectByPrimaryKey(empId);
}
public boolean isExists(Integer empId) {
return employeeMapper.existsWithPrimaryKey(empId);
}
public void saveEmployee(Employee employee) {
employeeMapper.insert(employee);
}
public void saveEmployeeSelective(Employee employee) {
employeeMapper.insertSelective(employee);
}
public void updateEmployeeSelective(Employee employee) {
employeeMapper.updateByPrimaryKeySelective(employee);
}
public void removeEmployee(Employee employee) {
employeeMapper.delete(employee);
}
public void removeEmployeeById(Integer empId) {
employeeMapper.deleteByPrimaryKey(empId);
}
public List getEmpListByExample(Example example) {
return employeeMapper.selectByExample(example);
}
public List getEmpListByRowBounds(RowBounds rowBounds) {
return employeeMapper.selectByRowBounds(null, rowBounds);
}
}
测试Mapper:
public class EmployeeMapperTest {
private ApplicationContext iocContainer = new ClassPathXmlApplicationContext("spring-context.xml");
private EmployeeService employeeService = iocContainer.getBean(EmployeeService.class);
/**
* 通用 Mapper 替我们自动生成的 SQL 语句情况
* Preparing: SELECT emp_id,emp_name,emp_salary,emp_age FROM tabple_emp WHERE emp_name = ? AND emp_salary = ?
* Parameters: bob(String), 5560.11(Double)
* Total: 1
* 实体类封装查询条件生成 WHERE 子句的规则
* 使用非空的值生成 WHERE 子句
* 在条件表达式中使用“=”进行比较
* 要求必须返回一个实体类结果,如果有多个,则会抛出异常
*
*/
@Test
public void testSelectOne() {
//1.创建封装查询条件的实体类对象
Employee employeeQueryCondition = new Employee(null, "bob", 5560.11, null);
//2.执行查询
Employee employeeQueryResult = employeeService.getOne(employeeQueryCondition);
//3.打印
System.out.println(employeeQueryResult);
}
/**
* xxxByPrimaryKey 方法:
* 需要使用@Id 主键明确标记和数据库表主键字段对应的实体类字段,
* 否则通用 Mapper 会将所有实体类字段作为联合主键。
*/
@Test
public void testSelectByPrimaryKey() {
//1.提供id值
Integer empId = 3;
//2.执行根据主键进行的查询
Employee employee = employeeService.getEmployeeById(empId);
//3.打印结果
System.out.println(employee);
}
@Test
public void testExistsWithPrimaryKey() {
//1.提供主键值
Integer empId = 33;
//2.执行查询
boolean exists = employeeService.isExists(empId);
//3.打印结果
System.out.println(exists);
}
@Test
public void testInsert() {
//1.创建实体类对象封装要保存到数据库的数据
Employee employee = new Employee(null, "emp03", 3000.00, 23);
//2.执行插入操作
employeeService.saveEmployee(employee);
//3.获取employee对象的主键字段值
Integer empId = employee.getEmpId();
System.out.println("empId="+empId);
}
/**
* xxxSelective 方法:
* 非主键字段如果为 null 值,则不加入到 SQL 语句中。
*/
@Test
public void testInsertSelective() {
//1.创建实体类对象封装要保存到数据库的数据
Employee employee = new Employee(null, "emp04", null, 23);
//2.执行插入操作
employeeService.saveEmployeeSelective(employee);
}
@Test
public void testUpdateByPrimaryKeySelective() {
//1.创建用于测试的实体类
Employee employee = new Employee(7, "empNewName", null, null);
//2.执行更新
employeeService.updateEmployeeSelective(employee);
}
@Test
public void testDelete() {
//1.声明实体类变量作为查询条件
Employee employee = null;
//2.执行删除
employeeService.removeEmployee(employee);
}
@Test
public void testDeleteByPrimaryKey() {
//1.提供主键值
Integer empId = 13;
//2.执行删除
employeeService.removeEmployeeById(empId);
}
/**
* QBC查询:
* Query By Criteria
* Criteria是Criterion的复数形式。意思是:规则、标准、准则。在SQL语句中相当于查询条件。
* QBC查询是将查询条件通过Java对象进行模块化封装。
*/
@Test
public void testSelectByExample() {
//目标:WHERE (emp_salary>? AND emp_age) OR (emp_salary AND emp_age>?)
//1.创建Example对象
Example example = new Example(Employee.class);
//i.设置排序信息
example.orderBy("empSalary").asc().orderBy("empAge").desc();
//ii.设置“去重”
example.setDistinct(true);
//iii.设置select字段
example.selectProperties("empName","empSalary");
//2.通过Example对象创建Criteria对象
Criteria criteria01 = example.createCriteria();
Criteria criteria02 = example.createCriteria();
//3.在两个Criteria对象中分别设置查询条件
//property参数:实体类的属性名
//value参数:实体类的属性值
criteria01.andGreaterThan("empSalary", 3000)
.andLessThan("empAge", 25);
criteria02.andLessThan("empSalary", 5000)
.andGreaterThan("empAge", 30);
//4.使用OR关键词组装两个Criteria对象
example.or(criteria02);
//5.执行查询
List empList = employeeService.getEmpListByExample(example);
for (Employee employee : empList) {
System.out.println(employee);
}
}
@Test
public void testSelectByRowBounds() {
int pageNo = 3;
int pageSize = 5;
int index = (pageNo - 1) * pageSize;
RowBounds rowBounds = new RowBounds(index, pageSize);
List empList = employeeService.getEmpListByRowBounds(rowBounds);
for (Employee employee : empList) {
System.out.println(employee);
}
}
@Test
public void testSelectOneByExample() {
}
@Test
public void testSelectCountByExample() {
}
@Test
public void testDeleteByExample() {
}
@Test
public void testUpdateByExample() {
}
@Test
public void testUpdateByExampleSelective() {
}
@Test
public void testSelectByExampleAndRowBounds() {
}
@Test
public void testSelect() {
}
@Test
public void testSelectAll() {
}
@Test
public void testSelectCount() {
}
@Test
public void testUpdateByPrimaryKey() {
}
}
QBC查询生成的SQL:
Preparing: SELECT distinct emp_name , emp_salary FROM tabple_emp WHERE ( emp_salary > ? and emp_age < ? ) or ( emp_salary < ? and emp_age > ? ) order by emp_salary ASC,emp_age DESC
Parameters: 3000(Integer), 25(Integer), 5000(Integer), 30(Integer)
Total: 0