mybatis接口开发&关联关系的简单使用2

工程目录结构查看:

面向接口开发的过程:

 写一个接口,方法照着xml配置文件中的方法写,public+返回值对应resultType+方法名称对应id+参数对应parameterType,然后session.getMapper(OrderMapper.class),其中mpper底层会创建OrderMapper的实现类,通过jdk动态代理方式实现,断点调试可以看到$ProxyN这个动态代理实现类对象,通过接口全局限定名cn.tedu.order.pojo.OrderMapper的路径(即包名.类/接口名称),找到相对应的命名空间,就找到映射文件OrderMapepr.xml,解析映射文件,找到所有SQL语句。因为调用的是接口的find方法,就找到映射文件中的find标签,找到标签就找到sql语句,利用Executor执行sql语句,返回记录集ResultSet,获取这个结果集,遍历这个结果集,获取每条记录,从记录中获取每个字段,例如id,获取到id对应值,通过xml中配置的返回值,就拿到pojo对象,调用setld,底层调用反射中回调类的setld(id),pojo的属性有值了,遍历所有的字段,pojo这一个对象就都有值了,遍历所有的结果集,创建多个pojo对象,最终设置完所有的属性值,最终再放入到list集合中

尽管是面向接口开发,但是mapper.xml中的方法配置仍然需要手动编写,config.xml和mapper.xml两个文件都不能少,否则报org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.swliu.person.pojo.PersonMapper.find ......

 1.数据库文件mybatisdb2.sql

(1)cmd执行(本身GBK):

mysql -uroot -prootswliu

SET NAMES GBK;

(2)mysql客户端工具Navicat等(本身UTF8):
 
SET NAMES UTF8;-- 可以省略

CREATE DATABASE IF NOT EXISTS `mybatisdb2` DEFAULT CHARACTER SET utf8;

USE `mybatisdb2`;

DROP TABLE IF EXISTS `person`;

CREATE TABLE `person` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(20) DEFAULT NULL,
  `school` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;

insert  into `person`(`id`,`user_name`,`school`) values (1,'tony','北大'),(2,'hellen','清华');

select * from `person`;

Delete删除所有的数据,但是不更新一些配置,比如自增id的值不会被清;
Truncate删除所有的数据,把特有的配置也还原,比如自增id也从0开始。

2. 测试类TestInterface.java

package person;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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 org.junit.Before;
import org.junit.Test;

import com.swliu.person.pojo.Person;
import com.swliu.person.pojo.PersonMapper;

//面向接口式开发
public class TestInterface {
	//初始化工厂对象
	private SqlSessionFactory factory;
	
	//初始化
	@Before
	public void init() throws IOException{
		InputStream is = Resources.getResourceAsStream("sqlMapConfig.xml");
		factory = new SqlSessionFactoryBuilder().build(is);
	}
	
	@Test	//调用接口的方式,没有实现类
	public void find(){
		SqlSession session = factory.openSession();
		//调用getMapper方法,参数是接口
		//调用接口方式,$ProxyN底层使用jdk动态代理技术,Mybatis底层创建了实现类
		PersonMapper mapper = session.getMapper(PersonMapper.class);
		
		Person p = new Person();	//参数
		
		List<Person> personList = mapper.find(p);
		for(Person x: personList){
			System.out.println(x);
		}
	}
	
}

测试类TestPerson.java 

package person;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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 org.junit.Before;
import org.junit.Test;

import com.swliu.person.pojo.Person;

//原始xml配置方式的开发
public class TestPerson {
	private SqlSessionFactory factory;
	
	@Before //在每个方法执行前执行
	public void init() throws IOException{
		InputStream is = Resources.getResourceAsStream("sqlMapConfig.xml");
		factory = new SqlSessionFactoryBuilder().build(is);
	}
	
	@Test
	public void find(){
		SqlSession session = factory.openSession();
		String ns = "com.swliu.person.pojo.PersonMapper.find";
		
		//参数,mybatis如果创建pojo,属性未设置它的值null(使用包装类型的好处)
		Person p = new Person();
		//p.setUserName("tony");
		p.setSchool("北大");
		
		List<Person> personList = session.selectList(ns, p);
		for(Person x :personList){
			System.out.println(x);
		}
	}
	
	@Test
	public void update(){
		SqlSession session = factory.openSession();
		String ns = "com.swliu.person.pojo.PersonMapper.update";
		
		//参数,mybatis如果创建pojo,属性未设置它的值null
		Person p = new Person();
		p.setId(1);
		p.setUserName("");
		//p.setUserName("ruse");
		//p.setSchool("");
		//p.setSchool("哈佛");
		
		session.update(ns,p);
		session.commit();
	}	
	
	@Test
	public void delete(){
		SqlSession session = factory.openSession();
		String ns = "com.swliu.person.pojo.PersonMapper.delete";
		
		//参数map
		Map<String,Object> p = new HashMap<String,Object>();
		p.put("ids", new Integer[]{13,14});	//key一个,value数组
		
		session.delete(ns,p);
		session.commit();
	}	
	
	@Test
	public void deleteArray(){
		SqlSession session = factory.openSession();
		String ns = "com.swliu.person.pojo.PersonMapper.deleteArray";
		
		//参数array
		session.delete(ns, new Integer[]{15,16});
		session.commit();
	}
	
	@Test
	public void deleteList(){
		SqlSession session = factory.openSession();
		String ns = "com.swliu.person.pojo.PersonMapper.deleteList";
		
		//参数list
		List<Integer> list = new ArrayList<Integer>();
		Collections.addAll(list, 17,18);

		session.delete(ns, list);
		session.commit();
	}	
}




 3.配置事务、数据源、映射文件、全局配置文件 sqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<!-- 
	核心配置文件中标签是有顺序性的:
	元素类型为 "configuration" 的内容必须匹配
		properties 
		settings
		typeAliases
		typeHandlers
		objectFactory
		objectWrapperFactory
		plugins
		environments
		databaseIdProvider
		mappers
	 -->
	 
	<!-- 加载属性文件 -->
	<properties resource="jdbc.properties"/>

	<!-- 全局配置,mapUnderscoreToCamelCase 下划线和驼峰规则自动映射 -->
	<settings>
		<setting name="mapUnderscoreToCamelCase" value="true"/>
	</settings>
		
	<!-- 简化类,起别名 -->
	<typeAliases>
		<typeAlias type="com.swliu.person.pojo.Person" alias="Person"/>
	</typeAliases>
	
	<!-- 配置环境、事务、数据源、映射文件 -->
	<environments default="test">
		<environment id="test">
			<!-- 支持两种类型:JDBC/MANAGE -->
			<transactionManager type="JDBC"/>
			<!-- 数据源:POOLED/UNPOOLED/JNDI -->
			<dataSource type="POOLED">
				<property name="driver" value="${driver}"/>
				<property name="url" value="${url}"/>
				<property name="username" value="${username}"/>
				<property name="password" value="${password}"/>
			</dataSource>
		</environment>
	</environments>
	
	<!-- 告诉mybatis映射文件存在 -->
	<mappers>
		<!-- 
		Mybatis早期提供方法selectList/selectOne这种方式不是面向对象思考方式,
		推出接口式开发(接口式开发无需xml配置访问)
		开发步骤:
		(1)创建一个接口(Map接口有实现类HashMap),无需写实现类
		(2)sqlSession对象来调用这个接口
		注意路径:
		(1)保证接口文件放在和映射文件同一目录(约定)
		(2)命名空间指向映射文件的目录
		(3)在全局配置文件中告诉mybatis接口存在,不能同时存在接口和xml方式
		jdk动态代理实现,动态根据接口来创建实现类
		接口实际上最终调用的还是xml中的方法
		org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(statement, parameter)
		在实际开发Mybatis程序时,大多数情况使用的都是接口方式,少数必须使用原始xml配置方式关联对象ResultMap!!!
		 -->
		<!-- 全局限定名=包名.类/接口名称 -->
		<mapper class="com.swliu.person.pojo.PersonMapper"/> 
		
		<!-- Mybatis早期提供方法selectList/selectOne的方式:-->
		<mapper resource="com/swliu/person/pojo/PersonMapper.xml"/>
		
	</mappers>		  

</configuration>

mappers严格按照顺序执行:先class,后resource 

 jdbc.properties数据源配置文件

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatisdb2?characterEncoding=utf8
username=root
password=rootswliu

4.配置映射文件的命名空间(java包): 包的路径.映射文件的名称 PersonMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
	PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
	
<mapper namespace="com.swliu.person.pojo.PersonMapper">
	<!-- 第三种改进:使用核心配置文件全局配置,mapUnderscoreToCamelCase下划线和驼峰规则自动映射,无需字段另起别名和resultMap映射 -->
	<select id="find" parameterType="Person" resultType="Person">
		SELECT id,user_name,school FROM person
		where 1=1
		<if test="userName != null">and user_name = #{userName}</if> 
		<if test="school != null"> and school = #{school}</if>
	</select>

	<!-- 第二种改进:带参查询 -->
	<select id="find3" parameterType="Person" resultMap="personResultMap">
		SELECT id,user_name,school FROM person
		where 1=1
		<if test="userName != null">and user_name = #{userName}</if> 
		<if test="school != null"> and school = #{school}</if>
	</select>
	
	<!-- 构建复杂映射关系,id唯一,type返回值放入哪个pojo -->
	<resultMap type="Person" id="personResultMap">
		<!-- 主键,property pojo的属性, column数据库表的字段 -->
		<id property="id" column="id"/>
		<!-- 普通字段,起到了映射规则:数据库结果集字段user_name,
		内部会自动调用person.setUserName方法 
		-->
		<result property="userName" column="user_name"/>
		<result property="school" column="school"/>
	</resultMap>
	
	<!-- 第一种:使用where标签,会自动去掉最前面的and/or,字段使用别名以便找到对应的实体类属性 -->
	<!-- 
	<select id="find2" parameterType="Person" resultType="Person">
		SELECT id,user_name userName,school FROM person
		<where>
			<if test="userName != null">user_name = #{userName}</if> 
			<if test="school != null"> and school = #{school}</if>	
		</where>
	</select>
	 -->
	
	<!-- 修改:set标签会自动去掉最后面的逗号"," -->
	<update id="update" parameterType="Person">
		UPDATE person 
		<set> 
			<if test="userName != null and userName !='' ">user_name=#{userName},</if>
			<if test="school != null and userName !='' ">school=#{school},</if>
		</set>  
		 WHERE id=#{id}
	</update>
	
	<!-- 批量删除改进  map:k(ids) v(3,4,5) (更灵活更常用)-->
	<delete id="delete" parameterType="map">
		DELETE FROM person WHERE id
		<foreach collection="ids" item="id" separator=","  open="in (" close=")" >
			#{id}
		</foreach>
	</delete>
	
	<!-- 批量删除  map:k(ids) v(3,4,5) (格式不好看)
	<delete id="delete" parameterType="map">
		DELETE FROM person WHERE id in (
			<foreach collection="ids" item="id" separator="," >
				#{id}
			</foreach>
		)
	</delete>
	-->
	
	<!-- 批量删除数组元素的类型(不灵活不常用)-->
	<delete id="deleteArray" parameterType="int">
		DELETE FROM person WHERE id
		<foreach collection="array" item="id" separator="," open="in (" close=")">
			#{id}
		</foreach>
	</delete>
	
	<!-- 批量删除list元素的类型(不灵活不常用)-->
	<delete id="deleteList" parameterType="int">
		DELETE FROM person WHERE id
		<foreach collection="list" item="id" separator="," open="in (" close=")">
			#{id}
		</foreach>
	</delete>

</mapper>



5.javaBean类Person.java

package com.swliu.person.pojo;

public class Person {
	private Integer id;
	private String userName;
	private String school;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getSchool() {
		return school;
	}
	public void setSchool(String school) {
		this.school = school;
	}
	@Override
	public String toString() {
		return "Person [id=" + id + ", userName=" + userName + ", school=" + school + "]";
	}
	
}

6.log4j.properties日志打印 

log4j.rootLogger=DEBUG, Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

7.pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.swliu</groupId>
	<artifactId>mybatis</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<properties>  
	    <argLine>-Dfile.encoding=UTF-8</argLine>  
	</properties>
	
	<dependencies>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.40</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.2.8</version>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
		</dependency>
	</dependencies>
	
	<!-- 
	<build>
	    <plugins>  
	        <plugin>  
	            <groupId>org.apache.maven.plugins</groupId>  
	            <artifactId>maven-surefire-plugin</artifactId>  
	            <version>2.16</version>  
	            <configuration>  
	                <forkMode>once</forkMode>  
	                <argLine>-Dfile.encoding=UTF-8</argLine>  
	            </configuration>  
	        </plugin>  
	    </plugins>
	</build>  
     -->
     
</project>


8.接口 PersonMapper.java

package com.swliu.person.pojo;

import java.util.List;

//必须是一个接口
public interface PersonMapper {
	//写一个查询方法
	//<select id="find" parameterType="Person" resultType="Person">
	public List<Person> find(Person p);
}

打印信息: 略

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值