难度4,知识点比较琐碎,不过比hibernate简单。学完MyBatis Spring再来学这里。
第一部分:理论
1,创建测试数据
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');
实体类
public class Employee {
private Integer empId;
private String empName;
private Double empSalary;
private Integer empAge;
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;
}
}
Java 实体类
考虑到基本数据类型在 Java 类中都有默认值,会导致 MyBatis 在执行相关操作
时很难判断当前字段是否为 null,所以在 MyBatis 环境下使用 Java 实体类时尽量不
要使用基本数据类型,都使用对应的包装类型。
2,搭建 MyBatis+Spring 开发环境
集成 Mapper
加入 Maven 依赖信息
Ø
修改 Spring 配置文件
第一个操作
/**
* 具 体 操 作 数 据 库 的 Mapper 接 口 , 需 要 继 承 通 用 Mapper 提 供 的 核 心 接 口 :
Mapper
* 泛型类型就是实体类的类型
* @author Lenovo
*
*/
public interface EmployeeMapper extends Mapper
}
3,常用注解
3.1@Table 注解
作用:建立实体类和数据库表之间的对应关系。
默认规则:实体类类名首字母小写作为表名。Employee 类→employee 表。
用法:在@Table 注解的 name 属性中指定目标数据库表的表名
3.2@Column 注解
作用:建立实体类字段和数据库表字段之间的对应关系。
默认规则:
实体类字段:驼峰式命名
数据库表字段:使用“_”区分各个单词
用法:在@Column 注解的 name 属性中指定目标字段的字段名
3.3@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 主键明确标记和数据库表中主键字段对应的实体类字段。
3.4@GeneratedValue 注解
作用:让通用 Mapper 在执行 insert 操作之后将数据库自动生成的主键值回写到实
体类对象中。
自增主键用法:
序列主键用法:
应用场景:购物车结账
Ø 增加商品销量...
Ø 减少商品库存...
Ø 生成订单数据→封装到 Order 对象中→保存 Order 对象→数据库自动生成主键
值→回写到实体类对象 Order 中
Ø 生成一系列订单详情数据→List
Order 对象的主键值作为外键→批量保存 List
……
3.5@Transient 主键
用于标记不与数据库表字段对应的实体类字段。
@Transient
private String otherThings; //非数据库表中字段
4 常用方法
4.1selectOne 方法
Ø 通用 Mapper 替我们自动生成的 SQL 语句情况
实体类封装查询条件生成 WHERE 子句的规则
n 使用非空的值生成 WHERE 子句
n 在条件表达式中使用“=”进行比较
Ø 要求必须返回一个实体类结果,如果有多个,则会抛出异常
4.2xxxByPrimaryKey 方法
需要使用@Id 主键明确标记和数据库表主键字段对应的实体类字段,否则通用
Mapper 会将所有实体类字段作为联合主键。
4.3xxxSelective 方法
非主键字段如果为 null 值,则不加入到 SQL 语句中。
5 QBC 查询
5.1概念
Query By Criteria
Criteria 是 Criterion 的复数形式。意思是:规则、标准、准则。在 SQL 语句中相当
于查询条件。
QBC 查询是将查询条件通过 Java 对象进行模块化封装。
5.2示例代码
//目标: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);
}
下面的就直接截图了
7.3配置 MapperScannerConfigurer 注册 MyMapper
mappers=com.atguigu.mapper.mine_mappers.MyMapper
8 通用 Mapper 接口扩展
8.1说明
这里的扩展是指增加通用 Mapper 没有提供的功能。
8.2举例
通用 Mapper 官方文档中使用一个批量 insert 作为扩展功能的例子:
tk.mybatis.mapper.additional.insert.InsertListMapper
tk.mybatis.mapper.additional.insert.InsertListProvider
我们来仿照写一个批量 update。假设我们想生成下面这样的 SQL 语句:
UPDATE tabple_emp SET emp_name=?,emp_age=?,emp_salary=? where emp_id=? ;
UPDATE tabple_emp SET emp_name=?,emp_age=?,emp_salary=? where emp_id=? ;
UPDATE tabple_emp SET emp_name=?,emp_age=?,emp_salary=? where emp_id=? ;
……
为了生成上面那样的 SQL 语句,我们需要使用到 MyBatis 的 foreach 标签。
UPDATE tabple_emp
SET emp_name=#{record.empName},
emp_age=#{record.empAge},
emp_salary=#{record.empSalary}
where emp_id=#{record.empId}
第二部分:案例
常用方法:
目录
Employee.java
package com.atguigu.mapper.entities;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@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_apple")
private Double empSalary;//emp_salary_apple
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;
}
}
EmployeeMapper.java
package com.atguigu.mapper.mappers;
import com.atguigu.mapper.entities.Employee;
import tk.mybatis.mapper.common.Mapper;
/**
* 具体操作数据库的Mapper接口,需要继承通用Mapper提供的核心接口:Mapper
* 泛型类型就是实体类的类型
* @author Lenovo
*
*/
public interface EmployeeMapper extends Mapper {
}
EmployeeService.java
package com.atguigu.mapper.services;
import java.util.List;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.atguigu.mapper.entities.Employee;
import com.atguigu.mapper.mappers.EmployeeMapper;
import tk.mybatis.mapper.entity.Example;
//通用mapper方法 这个里面的方法视频里面老师都走过一遍,要求掌握,很重要!!!!
@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);
}
}
jdbc.properties
jdbc.user=root
jdbc.password=root
jdbc.url=jdbc:mysql://localhost:3306/common_mapper?useUnicode=true&characterEncoding=utf8
jdbc.driver=com.mysql.jdbc.Driver
log4j.properties
log4j.rootLogger=DEBUG,myConsole
log4j.appender.myConsole=org.apache.log4j.ConsoleAppender
log4j.appender.myConsole.ImmediateFlush=true
log4j.appender.myConsole.Target=System.out
log4j.appender.myConsole.layout=org.apache.log4j.PatternLayout
log4j.appender.myConsole.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
log4j.logger.com.mchange.v2=ERROR
mybatis-config.xml
spring-context.xml
EmployeeMapperTest.java
package com.atguigu.mapper.test;
import java.util.List;
import org.apache.ibatis.session.RowBounds;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.atguigu.mapper.entities.Employee;
import com.atguigu.mapper.services.EmployeeService;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;
public class EmployeeMapperTest {
private ApplicationContext iocContainer = new ClassPathXmlApplicationContext("spring-context.xml");
private EmployeeService employeeService = iocContainer.getBean(EmployeeService.class);
//==================常用方法========================================
@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);
}
@Test
public void testSelect() {
}
@Test
public void testSelectAll() {
}
@Test
public void testSelectCount() {
}
@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);
}
@Test
public void testInsertSelective() {
//1.创建实体类对象封装要保存到数据库的数据
Employee employee = new Employee(null, "emp04", null, 23);
//2.执行插入操作
employeeService.saveEmployeeSelective(employee);
}
@Test
public void testUpdateByPrimaryKey() {
}
@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);
}
//==================5 QBC 查询 ========================================
//5.1概念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 testSelectOneByExample() {
}
@Test
public void testSelectCountByExample() {
}
@Test
public void testDeleteByExample() {
}
@Test
public void testUpdateByExample() {
}
@Test
public void testUpdateByExampleSelective() {
}
@Test
public void testSelectByExampleAndRowBounds() {
}
@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);
}
}
}
MapperTest.java
package com.atguigu.mapper.test;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
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);
}
}
MBG 通用工程 逆向工程
MBGTest.java
package com.atguigu.shop.test;
import java.io.InputStream;
import java.util.Iterator;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import com.atguigu.shop.entities.Employee;
import com.atguigu.shop.mappers.EmployeeMapper;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
public class MBGTest {
public static void main(String[] args) {
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
InputStream inputStream = MBGTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = builder.build(inputStream);
SqlSession session = factory.openSession();
//***********************
//按照Java方式整合通用Mapper的特殊设置
//i.创建MapperHelper对象
MapperHelper mapperHelper = new MapperHelper();
//ii.通过MapperHelper对象对MyBatis原生的Configuration对象进行处理
Configuration configuration = session.getConfiguration();
mapperHelper.processConfiguration(configuration);
//***********************
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
Iterator iterator = mapper.selectAll().iterator();
while (iterator.hasNext()) {
Employee employee = (Employee) iterator.next();
System.out.println(employee);
}
}
}
config.properties
# Database connection information
jdbc.driverClass = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/common_mapper
jdbc.user = root
jdbc.password = root
#c3p0
jdbc.maxPoolSize=50
jdbc.minPoolSize=10
jdbc.maxStatements=100
jdbc.testConnection=true
# mapper
mapper.plugin = tk.mybatis.mapper.generator.MapperPlugin
mapper.Mapper = tk.mybatis.mapper.common.Mapper
mybatis-config.xml
//测试自定义mapper接口
MyBatchUpdateTest.java
package com.atguigu.mapper.test;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.atguigu.mapper.entities.Employee;
import com.atguigu.mapper.services.EmployeeService;
public class MyBatchUpdateTest {
//用于功能扩展的接口和实现类
public static void main(String[] args) {
ClassPathXmlApplicationContext iocContainer = new ClassPathXmlApplicationContext("spring-context.xml");
EmployeeService employeeService = iocContainer.getBean(EmployeeService.class);
List empList = new ArrayList<>();
empList.add(new Employee(25, "newName01", 111.11, 10));
empList.add(new Employee(26, "newName02", 222.22, 20));
empList.add(new Employee(27, "newName03", 333.33, 30));
employeeService.batchUpdateEmp(empList);
iocContainer.close();
}
}
EmployeeService.java
package com.atguigu.mapper.services;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.atguigu.mapper.entities.Employee;
import com.atguigu.mapper.mappers.EmployeeMapper;
@Service
public class EmployeeService {
@Autowired
private EmployeeMapper employeeMapper;
public List getAll() {
return employeeMapper.selectAll();
}
public void batchUpdateEmp(List empList) {
employeeMapper.batchUpdate(empList);
}
}
MyBatchUpdateMapper.java
package com.atguigu.mapper.mine_mappers;
import java.util.List;
import org.apache.ibatis.annotations.UpdateProvider;
public interface MyBatchUpdateMapper {
@UpdateProvider(type=MyBatchUpdateProvider.class, method="dynamicSQL")
void batchUpdate(List list);
}
MyBatchUpdateProvider.java
package com.atguigu.mapper.mine_mappers;
import java.util.Set;
import org.apache.ibatis.mapping.MappedStatement;
import tk.mybatis.mapper.entity.EntityColumn;
import tk.mybatis.mapper.mapperhelper.EntityHelper;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import tk.mybatis.mapper.mapperhelper.MapperTemplate;
import tk.mybatis.mapper.mapperhelper.SqlHelper;
public class MyBatchUpdateProvider extends MapperTemplate {
public MyBatchUpdateProvider(Class> mapperClass, MapperHelper mapperHelper) {
super(mapperClass, mapperHelper);
}
/*
UPDATE tabple_emp
emp_name=#{record.empName},
emp_age=#{record.empAge},
emp_salary=#{record.empSalary},
where emp_id=#{record.empId}
*/
//在类里面需要提供一个和接口同名的方法 batchUpdate
public String batchUpdate(MappedStatement statement) {
//1.创建StringBuilder用于拼接SQL语句的各个组成部分
StringBuilder builder = new StringBuilder();
//2.拼接foreach标签
builder.append("");
//3.获取实体类对应的Class对象
Class> entityClass = super.getEntityClass(statement);
//4.获取实体类在数据库中对应的表名
String tableName = super.tableName(entityClass);
//5.生成update子句
String updateClause = SqlHelper.updateTable(entityClass, tableName);
builder.append(updateClause);
builder.append("");
//6.获取所有字段信息
Set columns = EntityHelper.getColumns(entityClass);
String idColumn = null;
String idHolder = null;
for (EntityColumn entityColumn : columns) {
boolean isPrimaryKey = entityColumn.isId();
//7.判断当前字段是否为主键
if(isPrimaryKey) {
//8.缓存主键的字段名和字段值
idColumn = entityColumn.getColumn();
//※返回格式如:#{record.age,jdbcType=NUMERIC,typeHandler=MyTypeHandler}
idHolder = entityColumn.getColumnHolder("record");
}else {
//9.使用非主键字段拼接SET子句
String column = entityColumn.getColumn();
String columnHolder = entityColumn.getColumnHolder("record");
builder.append(column).append("=").append(columnHolder).append(",");
}
}
builder.append(" ");
//10.使用前面缓存的主键名、主键值拼接where子句
builder.append("where ").append(idColumn).append("=").append(idHolder);
builder.append(" ");
//11.将拼接好的字符串返回
return builder.toString();
}
}
BaseTypeHandler用法
setNonNullParameter
getNullableResult
getNullableResult
getNullableResultgetNullableResult
TypeHandlerTest.java
package com.atguigu.mapper.test;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.atguigu.mapper.entities.Address;
import com.atguigu.mapper.entities.SeasonEnum;
import com.atguigu.mapper.entities.User;
import com.atguigu.mapper.services.UserService;
public class TypeHandlerTest {
private UserService userService;
{
userService = new ClassPathXmlApplicationContext("spring-context.xml").getBean(UserService.class);
}
@Test
public void testQueryUser() {
Integer userId = 8;
User user = userService.getUserById(userId);
System.out.println(user);
}
@Test
public void testSaveUser() {
User user = new User(null, "tom08", new Address("AAA", "BBB", "CCC"), SeasonEnum.AUTUMN);
userService.saveUser(user);
}
}
UserService.java
package com.atguigu.mapper.services;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.atguigu.mapper.entities.User;
import com.atguigu.mapper.mappers.UserMapper;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public void saveUser(User user) {
userMapper.insert(user);
}
public User getUserById(Integer userId) {
return userMapper.selectByPrimaryKey(userId);
}
}
UserMapper.java
package com.atguigu.mapper.mappers;
import com.atguigu.mapper.entities.User;
import tk.mybatis.mapper.common.Mapper;
public interface UserMapper extends Mapper {
}
AddressTypeHandler.java
package com.atguigu.mapper.handlers;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import com.atguigu.mapper.entities.Address;
public class AddressTypeHandler extends BaseTypeHandler {
//setNonNullParameter
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Address address, JdbcType jdbcType)
throws SQLException {
//1.对address对象进行验证
if(address == null) {
return ;
}
//2.从address对象中取出具体数据
String province = address.getProvince();
String city = address.getCity();
String street = address.getStreet();
//3.拼装成一个字符串
//规则:各个值之间使用“,”分开
StringBuilder builder = new StringBuilder();
builder
.append(province)
.append(",")
.append(city)
.append(",")
.append(street);
String parameterValue = builder.toString();
//4.设置参数
ps.setString(i, parameterValue);
}
//getNullableResult
@Override
public Address getNullableResult(ResultSet rs, String columnName) throws SQLException {
//1.根据字段名从rs对象中获取字段值
String columnValue = rs.getString(columnName);
//2.验证columnValue是否有效
if(columnValue == null || columnValue.length() == 0 || !columnValue.contains(",")) {
return null;
}
//3.根据“,”对columnValue进行拆分
String[] split = columnValue.split(",");
//4.从拆分结果数组中获取Address需要的具体数据
String province = split[0];
String city = split[1];
String street = split[2];
//5.根据具体对象组装一个Address对象
Address address = new Address(province, city, street);
return address;
}
//getNullableResult
@Override
public Address getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
//1.根据字段名从rs对象中获取字段值
String columnValue = rs.getString(columnIndex);
//2.验证columnValue是否有效
if(columnValue == null || columnValue.length() == 0 || !columnValue.contains(",")) {
return null;
}
//3.根据“,”对columnValue进行拆分
String[] split = columnValue.split(",");
//4.从拆分结果数组中获取Address需要的具体数据
String province = split[0];
String city = split[1];
String street = split[2];
//5.根据具体对象组装一个Address对象
Address address = new Address(province, city, street);
return address;
}
//getNullableResult
@Override
public Address getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
//1.根据字段名从rs对象中获取字段值
String columnValue = cs.getString(columnIndex);
//2.验证columnValue是否有效
if(columnValue == null || columnValue.length() == 0 || !columnValue.contains(",")) {
return null;
}
//3.根据“,”对columnValue进行拆分
String[] split = columnValue.split(",");
//4.从拆分结果数组中获取Address需要的具体数据
String province = split[0];
String city = split[1];
String street = split[2];
//5.根据具体对象组装一个Address对象
Address address = new Address(province, city, street);
return address;
}
}
User.java
package com.atguigu.mapper.entities;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
/**
CREATE TABLE `table_user` (
`user_id` INT NOT NULL AUTO_INCREMENT,
`user_name` VARCHAR (100) NULL,
`address` VARCHAR (100) NULL,
`season` VARCHAR (100) NULL,
PRIMARY KEY (`user_id`)
);
* @author Lenovo
*
*/
@Table(name="table_user")
public class User {
@Id
private Integer userId;
private String userName;
//@ColumnType(typeHandler=AddressTypeHandler.class)
@Column
private Address address;
//在枚举类型这里无法使用@ColumnType注解注册MyBatis内置的枚举类型处理器
//@ColumnType(typeHandler=EnumTypeHandler.class)
@Column
private SeasonEnum season;
public User() {
}
public User(Integer userId, String userName, Address address, SeasonEnum season) {
super();
this.userId = userId;
this.userName = userName;
this.address = address;
this.season = season;
}
@Override
public String toString() {
return "User [userId=" + userId + ", userName=" + userName + ", address=" + address + ", season=" + season
+ "]";
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public SeasonEnum getSeason() {
return season;
}
public void setSeason(SeasonEnum season) {
this.season = season;
}
}
SeasonEnum.java
package com.atguigu.mapper.entities;
public enum SeasonEnum {
SPRING("spring @_@"),SUMMER("summer @_@"),AUTUMN("autumn @_@"),WINTER("winter @_@");
private String seasonName;
private SeasonEnum(String seasonName) {
this.seasonName = seasonName;
}
public String getSeasonName() {
return this.seasonName;
}
public String toString() {
return this.seasonName;
}
}
Address.java
package com.atguigu.mapper.entities;
public class Address {
private String province;
private String city;
private String street;
public Address() {
// TODO Auto-generated constructor stub
}
public Address(String province, String city, String street) {
super();
this.province = province;
this.city = city;
this.street = street;
}
@Override
public String toString() {
return "Address [province=" + province + ", city=" + city + ", street=" + street + "]";
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
}