Mapper系列一:基本使用

1、創建數據庫mapper
在這裏插入圖片描述
2、創建表和數據

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

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
	
	<!-- 配置數據源 -->
	<context:property-placeholder location="classpath:jdbc.properties"/>

	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="user" value="${jdbc.user}"/>
		<property name="password" value="${jdbc.password}"/>
		<property name="jdbcUrl" value="${jdbc.url}"/>
		<property name="driverClass" value="${jdbc.driver}"/>
	</bean>

	<!-- 整合MyBatis -->
	<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="configLocation" value="classpath:mybatis-config.xml"/>
		<property name="dataSource" ref="dataSource"/>
	</bean>
	
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.atguigu.mapper.mappers"/>
	</bean>

	<!-- 配置Service自動掃描的包 -->
	<context:component-scan base-package="com.atguigu.mapper.services"/>

	<!-- 配置聲明式事務 -->
	<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/>
	</bean>

	<aop:config>
		<aop:advisor advice-ref="txAdvice" pointcut="execution(* *..*Service.*(..))"/>
	</aop:config>

	<tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager">
		<tx:attributes>
			<tx:method name="get*" read-only="true"/>
			<tx:method name="save*" rollback-for="java.lang.Exception" propagation="REQUIRES_NEW"/>
			<tx:method name="remove*" rollback-for="java.lang.Exception" propagation="REQUIRES_NEW"/>
			<tx:method name="update*" rollback-for="java.lang.Exception" propagation="REQUIRES_NEW"/>
		</tx:attributes>
	</tx:advice>
</beans>

測試數據庫連接:

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);
	}
	
}

在這裏插入圖片描述
5、集成 Mapper
 加入 Maven 依賴信息

	<dependency>
		<groupId>tk.mybatis</groupId>
		<artifactId>mapper</artifactId>
		<version>4.0.0-beta3</version>
	</dependency>

  修改 Spring 配置文件

	<!-- 整合通用Mapper所需要做的配置修改: -->
	<!-- 原始全類名:org.mybatis.spring.mapper.MapperScannerConfigurer -->
	<!-- 通用Mapper使用:tk.mybatis.spring.mapper.MapperScannerConfigurer -->
	<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.atguigu.mapper.mappers"/>
	</bean>

6、編寫EmployeeMapper

/**
 * 具體操作數據庫的Mapper接口,需要繼承通用Mapper提供的核心接口:Mapper<Employee>
 * 泛型類型就是實體類的類型
 */
public interface EmployeeMapper extends Mapper<Employee> {
	
}

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<Employee> getEmpListByExample(Example example) {
		return employeeMapper.selectByExample(example);
	}

	public List<Employee> 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<Employee> 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<Employee> 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  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章