使用jdbc连接数据源与mybatis使用(1)

package com.enjoylearning.mybatis;
//STEP 1. 导入sql相关的包
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import com.enjoylearning.mybatis.entity.TUser;

public class JdbcDemo {
	static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
	static final String DB_URL = "jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true";

	// Database credentials
	static final String USER = "root";
	static final String PASS = "root";

	@Test
	public void QueryStatementDemo() {
		Connection conn = null;
		Statement stmt = null;
		List<TUser> users = new ArrayList<>();
		try {
			// STEP 2: 注册mysql的驱动
			Class.forName("com.mysql.jdbc.Driver");

			// STEP 3: 获得一个连接
			System.out.println("Connecting to database...");
			conn = DriverManager.getConnection(DB_URL, USER, PASS);

			// STEP 4: 创建一个查询
			System.out.println("Creating statement...");
			stmt = conn.createStatement();
			String userName = "lison";
			String sql="SELECT * FROM t_user where user_name='"+userName+"'";
			ResultSet rs = stmt.executeQuery(sql);
			System.out.println(stmt.toString());
			

			// STEP 5: 从resultSet中获取数据并转化成bean
			while (rs.next()) {
				System.out.println("------------------------------");
				// Retrieve by column name
				TUser user = new TUser();
//				user.setId(rs.getInt("id"));
//				user.setUserName(rs.getString("user_name"));
				user.setRealName(rs.getString("real_name"));
				user.setSex(rs.getByte("sex"));
				user.setMobile(rs.getString("mobile"));
				user.setEmail(rs.getString("email"));
				user.setNote(rs.getString("note"));

				System.out.println(user.toString());
				
				users.add(user);
			}
			// STEP 6: 关闭连接
			rs.close();
			stmt.close();
			conn.close();
		} catch (SQLException se) {
			// Handle errors for JDBC
			se.printStackTrace();
		} catch (Exception e) {
			// Handle errors for Class.forName
			e.printStackTrace();
		} finally {
			// finally block used to close resources
			try {
				if (stmt != null)
					stmt.close();
			} catch (SQLException se2) {
			}// nothing we can do
			try {
				if (conn != null)
					conn.close();
			} catch (SQLException se) {
				se.printStackTrace();
			}
		}
		System.out.println("-------------------------");
		System.out.println("there are "+users.size()+" users in the list!");
	}
	
	
	@Test
	public void QueryPreparedStatementDemo() {
		Connection conn = null;
		PreparedStatement stmt = null;
		List<TUser> users = new ArrayList<>();
		try {
			// STEP 2: 注册mysql的驱动
			Class.forName("com.mysql.jdbc.Driver");

			// STEP 3: 获得一个连接
			System.out.println("Connecting to database...");
			conn = DriverManager.getConnection(DB_URL, USER, PASS);

			// STEP 4: 创建一个查询
			System.out.println("Creating statement...");
			String sql;
			sql = "SELECT * FROM t_user where user_name= ? ";
			stmt = conn.prepareStatement(sql);
			stmt.setString(1, "lison");
			System.out.println(stmt.toString());//打印sql
			ResultSet rs = stmt.executeQuery();
			

			// STEP 5: 从resultSet中获取数据并转化成bean
			while (rs.next()) {
				System.out.println("------------------------------");
				// Retrieve by column name
				TUser user = new TUser();
//				user.setId(rs.getInt("id"));
//				user.setUserName(rs.getString("user_name"));
				user.setRealName(rs.getString("real_name"));
				user.setSex(rs.getByte("sex"));
				user.setMobile(rs.getString("mobile"));
				user.setEmail(rs.getString("email"));
				user.setNote(rs.getString("note"));

				System.out.println(user.toString());
				
				users.add(user);
			}
			// STEP 6: 关闭连接
			rs.close();
			stmt.close();
			conn.close();
		} catch (SQLException se) {
			// Handle errors for JDBC
			se.printStackTrace();
		} catch (Exception e) {
			// Handle errors for Class.forName
			e.printStackTrace();
		} finally {
			// finally block used to close resources
			try {
				if (stmt != null)
					stmt.close();
			} catch (SQLException se2) {
			}// nothing we can do
			try {
				if (conn != null)
					conn.close();
			} catch (SQLException se) {
				se.printStackTrace();
			}
		}
		System.out.println("-------------------------");
		System.out.println("there are "+users.size()+" users in the list!");
	}

	@Test
	public void updateDemo(){
		Connection conn = null;
		PreparedStatement stmt = null;
		try {
			// STEP 2: 注册mysql的驱动
			Class.forName("com.mysql.jdbc.Driver");

			// STEP 3: 获得一个连接
			System.out.println("Connecting to database...");
			conn = DriverManager.getConnection(DB_URL, USER, PASS);
			
			// STEP 4: 启动手动提交
			conn.setAutoCommit(false);
			

			// STEP 5: 创建一个更新
			System.out.println("Creating statement...");
			String sql = "update t_user  set mobile= ? where user_name= ? ";
			stmt = conn.prepareStatement(sql);
			stmt.setString(1, "186995587411");
			stmt.setString(2, "lison");
			System.out.println(stmt.toString());//打印sql
			int ret = stmt.executeUpdate();
			System.out.println("此次修改影响数据库的行数为:"+ret);

			// STEP 6: 手动提交数据
			conn.commit();
			
			// STEP 7: 关闭连接
			stmt.close();
			conn.close();
		} catch (SQLException se) {
			// Handle errors for JDBC
			try {
				conn.rollback();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			se.printStackTrace();
		} catch (Exception e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			e.printStackTrace();
		} finally {
			// finally block used to close resources
			try {
				if (stmt != null)
					stmt.close();
			} catch (SQLException se2) {
			}// nothing we can do
			try {
				if (conn != null)
					conn.close();
			} catch (SQLException se) {
				se.printStackTrace();
			}
		}
	}
}

1.PreparedStatement与Statement区别:

1)PreparedStatement执行查询后,第一次查询会预编译,数据库会对该语句的执行进行缓存,包括执行计划,包括结果等,以后查询速度很快。(mybatis默认)
Statement每次查询,都一样。
2)PreparedStatement防止sql注入。

在这里插入图片描述

2.ORM是什么?

对象关系映射(ORM),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换;

在这里插入图片描述
也就是说,java代码中的对象与数据库中的数据一一对应。
在这里插入图片描述

3.hibernate与mybatis的区别:

在这里插入图片描述
hibernate仅支持全表映射(不能只查询某几个字段)

4示例操作:

package com.enjoylearning.mybatis.entity;


public class TUser {
    private Integer id;

    private String userName;

    private String realName;

    private Byte sex;

    private String mobile;

    private String email;

    private String note;

    private Integer positionId;
    

    


	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 getRealName() {
        return realName;
    }

    public void setRealName(String realName) {
        this.realName = realName;
    }

    public Byte getSex() {
        return sex;
    }

    public void setSex(Byte sex) {
        this.sex = sex;
    }

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }

    public Integer getPositionId() {
        return positionId;
    }

    public void setPositionId(Integer positionId) {
        this.positionId = positionId;
    }
    

	@Override
	public String toString() {
		return "TUser [id=" + id + ", userName=" + userName + ", realName="
				+ realName + ", sex=" + sex + ", mobile=" + mobile + ", email="
				+ email + ", note=" + note + ", positionId=" + positionId + "]";
	}

	
	
    
}
package com.enjoylearning.mybatis.mapper;

import com.enjoylearning.mybatis.entity.TUser;

public interface TUserMapper {
	
    TUser selectByPrimaryKey(Integer id);
    
}
<?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.enjoylearning.mybatis.mapper.TUserMapper">

	<select id="selectByPrimaryKey" resultType="com.enjoylearning.mybatis.entity.TUser"	parameterType="java.lang.Integer">
		select
			id, 
			user_name , 
			real_name , 
			sex, 
			mobile, 
			email, 
			note,
			position_id positionId
		from t_user
		where id = #{id,jdbcType=INTEGER}
	</select>

</mapper>
<?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>
	<properties resource="db.properties" />
	<settings>
		<setting name="mapUnderscoreToCamelCase" value="true" />
	</settings>

	<!--配置environment环境 -->
	<environments default="development">
		<!-- 环境配置1,每个SqlSessionFactory对应一个环境 -->
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="UNPOOLED">
				<property name="driver" value="${jdbc_driver}" />
				<property name="url" value="${jdbc_url}" />
				<property name="username" value="${jdbc_username}" />
				<property name="password" value="${jdbc_password}" />
			</dataSource>
		</environment>
	</environments>

	<!-- 映射文件,mapper的配置文件 -->
<!-- 	<mappers>
		直接映射到相应的mapper文件
		<mapper resource="sqlmapper/TUserMapper.xml" />
	</mappers> -->

	<mappers>
		<mapper class="com.enjoylearning.mybatis.mapper.TUserMapper" />
	</mappers>


</configuration>  
jdbc_driver=com.mysql.jdbc.Driver
jdbc_url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
jdbc_username=root
jdbc_password=lixun033
project_src =src/main/java
project_mapper_xml =src/main/resources/sqlmapper
#class_path=C:/Users/admin/.m2/repository/mysql/mysql-connector-java/5.1.18/mysql-connector-java-5.1.18.jar
class_path=D:/devTools/LocalRepository/mysql/mysql-connector-java/5.1.18/mysql-connector-java-5.1.18.jar
package com.enjoylearning.mybatis;

import java.io.IOException;
import java.io.InputStream;

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.enjoylearning.mybatis.entity.TUser;
import com.enjoylearning.mybatis.mapper.TUserMapper;

public class MybatisQuickStart {

	private SqlSessionFactory sqlSessionFactory;

	@Before
	public void init() throws IOException {
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		// 1.读取mybatis配置文件创SqlSessionFactory
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		inputStream.close();
	}

	@Test
	// 快速入门
	public void quickStart() throws IOException {
		// 2.获取sqlSession
		SqlSession sqlSession = sqlSessionFactory.openSession();
		// 3.获取对应mapper
		TUserMapper mapper = sqlSession.getMapper(TUserMapper.class);
		// 4.执行查询语句并返回结果
		TUser user = mapper.selectByPrimaryKey(1);
		System.out.println(user.toString());

	}
	
}

5.一次访问数据库的过程

在这里插入图片描述
SqlSessionFactoryBuilder:读取配置信
息创建SqlSessionFactory,建造者模式,
方法级别生命周期;

 SqlSessionFactory:创建Sqlsession,工
厂单例模式,存在于程序的整个生命周
期;

 SqlSession:代表一次数据库连接,可
以直接发送SQL执行,也可以通过调用
Mapper访问数据库;线程不安全,要保
证线程独享(方法级);

 SQL Mapper:由一个Java接口和XML文
件组成,包含了要执行的SQL语句和结果
集映射规则。方法级别生命周期;

6.mybatis核心配置文件:

<?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>
	<properties resource="db.properties" />
	<settings>
		<setting name="mapUnderscoreToCamelCase" value="true" />
	</settings>

	<!--配置environment环境 -->
	<environments default="development">
		<!-- 环境配置1,每个SqlSessionFactory对应一个环境 -->
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="UNPOOLED">
				<property name="driver" value="${jdbc_driver}" />
				<property name="url" value="${jdbc_url}" />
				<property name="username" value="${jdbc_username}" />
				<property name="password" value="${jdbc_password}" />
			</dataSource>
		</environment>
	</environments>

	<!-- 映射文件,mapper的配置文件 -->
<!-- 	<mappers>
		直接映射到相应的mapper文件
		<mapper resource="sqlmapper/TUserMapper.xml" />
	</mappers> -->

	<mappers>
		<mapper class="com.enjoylearning.mybatis.mapper.TUserMapper" />
	</mappers>


</configuration>  

在这里插入图片描述

7.Mybatis配置 environments

1) environment 元素是配置一个数据源的开始,属性id是它的唯一标识
2) transactionManager 元素配置数据库事务,其中type属性有三种配置方式

  1. jdbc,采用jdbc的方式管理事务;
  2. managed,采用容器的方式管理事务,在JNDI数据源中使用;
  3. 自定义,自定义数据库事务管理办法;
    3) dataSource 元素配置数据源连接信息,type属性是连接数据库的方式配置,有四种配置方式
  4. UNPOOLED 非连接池方式连接
  5. POOLED 使用连接池连接
  6. JNDI 使用JNDI数据源
  7. 自定义数据源
<!--配置environment环境 -->
	<environments default="development">
		<!-- 环境配置1,每个SqlSessionFactory对应一个环境 -->
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="UNPOOLED">
				<property name="driver" value="${jdbc_driver}" />
				<property name="url" value="${jdbc_url}" />
				<property name="username" value="${jdbc_username}" />
				<property name="password" value="${jdbc_password}" />
			</dataSource>
		</environment>
	</environments>

databaseIdProvider配置:
MyBatis可以根据不同的数据库厂商执行不同的语句,用于一个系统
内多厂商数据源支持。也就是说,可以选择mysql,oracle,SqlServer。

8.Mybatis配置mappers

配置引入映射器的方法。可以使用相对于类路径的资源引用、或完全
限定资源定位符(包括file:///的URL),或类名和包名等等

<!-- 映射文件,mapper的配置文件 -->
<!-- 	<mappers>
		直接映射到相应的mapper文件
		<mapper resource="sqlmapper/TUserMapper.xml" />
	</mappers> -->

	<mappers>
		<mapper class="com.enjoylearning.mybatis.mapper.TUserMapper" />
	</mappers>

在这里插入图片描述
使用 第二种:类注册方式引用 与 第三种:使用包名引入引射器名,需要将接口类与对应的包含sql语句的xml文件放在同一个包下。
不推荐使用该方式。

第四种,强烈不推荐,使用全路径(某个盘里某个文件夹下)。

9.Mybatis配置 setting

设置,用于指定MyBatis的一些全局配置属性,这些属性非常重要,
它们会改变MyBatis的运行时行为;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
所有mybatis核心配置模板:

<?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>

	<!-- 参数设置 -->
	<settings>
		<!-- 这个配置使全局的映射器启用或禁用缓存 -->
		<setting name="cacheEnabled" value="true" />
		<!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载 -->
		<setting name="lazyLoadingEnabled" value="true" />
		<!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载 -->
		<setting name="aggressiveLazyLoading" value="true" />
		<!-- 允许或不允许多种结果集从一个单独的语句中返回(需要适合的驱动) -->
		<setting name="multipleResultSetsEnabled" value="true" />
		<!-- 使用列标签代替列名。不同的驱动在这方便表现不同。参考驱动文档或充分测试两种方法来决定所使用的驱动 -->
		<setting name="useColumnLabel" value="true" />
		<!-- 允许JDBC支持生成的键。需要适合的驱动。如果设置为true则这个设置强制生成的键被使用,尽管一些驱动拒绝兼容但仍然有效(比如Derby) -->
		<setting name="useGeneratedKeys" value="true" />
		<!-- 指定MyBatis如何自动映射列到字段/属性。PARTIAL只会自动映射简单,没有嵌套的结果。FULL会自动映射任意复杂的结果(嵌套的或其他情况) -->
		<setting name="autoMappingBehavior" value="PARTIAL" />
		<!--当检测出未知列(或未知属性)时,如何处理,默认情况下没有任何提示,这在测试的时候很不方便,不容易找到错误。 NONE : 不做任何处理 
			(默认值) WARNING : 警告日志形式的详细信息 FAILING : 映射失败,抛出异常和详细信息 -->
		<setting name="autoMappingUnknownColumnBehavior" value="WARNING" />
		<!-- 配置默认的执行器。SIMPLE执行器没有什么特别之处。REUSE执行器重用预处理语句。BATCH执行器重用语句和批量更新 -->
		<setting name="defaultExecutorType" value="SIMPLE" />
		<!-- 设置超时时间,它决定驱动等待一个数据库响应的时间 -->
		<setting name="defaultStatementTimeout" value="25000" />
		<!--设置查询返回值数量,可以被查询数值覆盖 -->
		<setting name="defaultFetchSize" value="100" />
		<!-- 允许在嵌套语句中使用分页 -->
		<setting name="safeRowBoundsEnabled" value="false" />
		<!--是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 
			的类似映射。 -->
		<setting name="mapUnderscoreToCamelCase" value="false" />
		<!--MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。 
			默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 
			的不同调用将不会共享数据。 -->
		<setting name="localCacheScope" value="SESSION" />
		<!-- 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。 某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 
			NULL、VARCHAR OTHER。 -->
		<setting name="jdbcTypeForNull" value="OTHER" />
		<!-- 指定哪个对象的方法触发一次延迟加载。 -->
		<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString" />
	</settings>

	<!-- 别名定义 -->
	<typeAliases>
		<typeAlias alias="pageAccessURL" type="com.lgm.mybatis.model.PageAccessURL" />
	</typeAliases>

	<!--自定义类型处理器 -->
	<typeHandlers>
		<!-- <typeHandler handler="com.xhm.util.BooleanTypeHandlder" /> -->
		<!--扫描整个包下的自定义类型处理器 -->
		<package name="com.xhm.util" />
	</typeHandlers>

	<!--plugins插件之 分页拦截器 -->
	<plugins>
		<plugin interceptor="com.xhm.util.PageInterceptor"></plugin>
	</plugins>

	<!--配置environment环境 -->
	<environments default="development">
		<!-- 环境配置1,每个SqlSessionFactory对应一个环境 -->
		<environment id="development1">
			<!-- 事务配置 type= JDBC、MANAGED 1.JDBC:这个配置直接简单使用了JDBC的提交和回滚设置。它依赖于从数据源得到的连接来管理事务范围。 
				2.MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接。而它会让容器来管理事务的整个生命周期(比如Spring或JEE应用服务器的上下文)。 
				默认情况下它会关闭连接。然而一些容器并不希望这样,因此如果你需要从连接中停止它,将closeConnection属性设置为false -->
			<transactionManager type="JDBC" />
			<!-- <transactionManager type="MANAGED"> <property name="closeConnection" 
				value="false"/> </transactionManager> -->
			<!-- 数据源类型:type = UNPOOLED、POOLED、JNDI 1.UNPOOLED:这个数据源的实现是每次被请求时简单打开和关闭连接。它有一点慢,这是对简单应用程序的一个很好的选择,因为它不需要及时的可用连接。 
				不同的数据库对这个的表现也是不一样的,所以对某些数据库来说配置数据源并不重要,这个配置也是闲置的 2.POOLED:这是JDBC连接对象的数据源连接池的实现,用来避免创建新的连接实例时必要的初始连接和认证时间。 
				这是一种当前Web应用程序用来快速响应请求很流行的方法。 3.JNDI:这个数据源的实现是为了使用如Spring或应用服务器这类的容器,容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用 -->
			<dataSource type="UNPOOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/xhm" />
				<property name="username" value="root" />
				<property name="password" value="root" />
				<!-- 默认连接事务隔离级别 <property name="defaultTransactionIsolationLevel" value="" 
					/> -->
			</dataSource>
		</environment>

		<!-- 环境配置2 -->
		<environment id="development2">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/xhm" />
				<property name="username" value="root" />
				<property name="password" value="root" />
				<!-- 在任意时间存在的活动(也就是正在使用)连接的数量 -->
				<property name="poolMaximumActiveConnections" value="10" />
				<!-- 任意时间存在的空闲连接数 -->
				<property name="poolMaximumIdleConnections" value="5" />
				<!-- 在被强制返回之前,池中连接被检查的时间 -->
				<property name="poolMaximumCheckoutTime" value="20000" />
				<!-- 这是给连接池一个打印日志状态机会的低层次设置,还有重新尝试获得连接,这些情况下往往需要很长时间(为了避免连接池没有配置时静默失败) -->
				<property name="poolTimeToWait" value="20000" />
				<!-- 发送到数据的侦测查询,用来验证连接是否正常工作,并且准备接受请求。 -->
				<property name="poolPingQuery" value="NO PING QUERY SET" />
				<!-- 这是开启或禁用侦测查询。如果开启,你必须用一个合法的SQL语句(最好是很快速的)设置poolPingQuery属性 -->
				<property name="poolPingEnabled" value="false" />
				<!-- 这是用来配置poolPingQuery多次时间被用一次。这可以被设置匹配标准的数据库连接超时时间,来避免不必要的侦测 -->
				<property name="poolPingConnectionsNotUsedFor" value="0" />
			</dataSource>
		</environment>

		<!-- 环境配置3 -->
		<environment id="development3">
			<transactionManager type="JDBC" />
			<dataSource type="JNDI">
				<property name="data_source" value="java:comp/env/jndi/mybatis" />
				<property name="env.encoding" value="UTF8" />
				<!-- <property name="initial_context" value=""/> <property name="env.encoding" 
					value="UTF8"/> -->
			</dataSource>
		</environment>
	</environments>

	<!-- 映射文件,mapper的配置文件 -->
	<mappers>
		<!--直接映射到相应的mapper文件 -->
		<mapper resource="com/xhm/mapper/UserMapper.xml" />
		<!--扫描包路径下所有xxMapper.xml文件 -->
		<package name="com.xhm.mapper" />
	</mappers>

</configuration>  

cacheEnabled:开启与关闭的是二级缓存,对一级缓存无效。
localCacheScope:对于一级缓存的配置,SESSION表示使用一级缓存, STATEMENT不使用。

logImpl:指定 MyBatis 所用日志的具体实现,未指定时将自动查找。默认使用JDK_LOGGING。

10.基于xml配置的映射器

基于接口,所编写的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.enjoylearning.mybatis.mapper.TUserMapper">
	<select id="selectByPrimaryKey" resultType="com.enjoylearning.mybatis.entity.TUser"	parameterType="java.lang.Integer">
		select
			id, 
			user_name , 
			real_name , 
			sex, 
			mobile, 
			email, 
			note,
			position_id positionId
		from t_user
		where id = #{id,jdbcType=INTEGER}
	</select>
</mapper>

在这里插入图片描述
 cache – 给定命名空间的缓存配置。
 cache-ref – 其他命名空间缓存配置的引用。
 resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
 sql – 可被其他语句引用的可重用语句块。
 insert – 映射插入语句
 update – 映射更新语句
 delete – 映射删除语句
 select – 映射查询语句

sql:提高sql复用率。如

<sql id="Base_Column_List">
		id, user_name, real_name, sex, mobile, email, note,
		position_id
	</sql>

1)select元素
在这里插入图片描述
resultMap与resultType只能使用一个。

如:

<?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.enjoylearning.mybatis.mapper.TUserMapper">
	<resultMap id="BaseResultMap" type="TUser">
		
		<!-- <constructor>
			<idArg column="id" javaType="int"/>
			<arg column="user_name" javaType="String"/>
		</constructor>  -->
		<id column="id" property="id" jdbcType="INTEGER" />
		<result column="user_name" property="userName" jdbcType="VARCHAR" />
		<result column="real_name" property="realName" jdbcType="VARCHAR" />
		<result column="sex" property="sex" jdbcType="TINYINT" />
		<result column="mobile" property="mobile" jdbcType="VARCHAR" />
		<result column="email" property="email" jdbcType="VARCHAR" />
		<result column="note" property="note" jdbcType="VARCHAR" />
		<result column="position_id" property="positionId" jdbcType="INTEGER" />
	</resultMap>





	<resultMap id="userAndJobs1" extends="BaseResultMap" type="TUser">
		<collection property="jobs"
			ofType="com.enjoylearning.mybatis.entity.TJobHistory">
			<result column="comp_name" property="compName" jdbcType="VARCHAR" />
			<result column="years" property="years" jdbcType="INTEGER" />
			<result column="title" property="title" jdbcType="VARCHAR" />
		</collection>
	</resultMap>









	<resultMap id="userAndJobs2" extends="BaseResultMap" type="TUser">
		<collection property="jobs" fetchType="lazy" column="id"
			select="com.enjoylearning.mybatis.mapper.TJobHistoryMapper.selectByUserId" />
	</resultMap>








	<select id="selectUserJobs1" resultMap="userAndJobs1">
		select
		a.id,
		a.user_name,
		a.real_name,
		a.sex,
		a.mobile,
		b.comp_name,
		b.years,
		b.title
		from t_user a,
		t_job_history b
		where a.id = b.user_id

	</select>

	<select id="selectUserJobs2" resultMap="userAndJobs2">
		select
		a.id,
		a.user_name,
		a.real_name,
		a.sex,
		a.mobile
		from t_user a
	</select>




	<select id="selectByEmailAndSex1" resultMap="BaseResultMap"
		parameterType="map">
		select
		<include refid="Base_Column_List" />
		from t_user a
		where a.email like CONCAT('%', #{email}, '%') and
		a.sex = #{sex}
	</select>

	<select id="selectByEmailAndSex2" resultMap="BaseResultMap">
		select
		<include refid="Base_Column_List" />
		from t_user a
		where a.email like CONCAT('%', #{email}, '%') and
		a.sex = #{sex}
	</select>


	<select id="selectByEmailAndSex3" resultMap="BaseResultMap"
		parameterType="com.enjoylearning.mybatis.entity.EmailSexBean">
		select
		<include refid="Base_Column_List" />
		from t_user a
		where a.email like CONCAT('%', #{email}, '%') and
		a.sex = #{sex}
	</select>


	<select id="selectBySymbol" resultMap="BaseResultMap">
		select 
		#{inCol} 
		from ${tableName} a
		where a.sex = #{sex}
		order by ${orderStr} 
	</select>
	
	
	
	<select id="selectIfOper" resultMap="BaseResultMap">
		select
		<include refid="Base_Column_List" />
		from t_user a
		where 
		<if test="email != null and email != ''">
		  	a.email like CONCAT('%', #{email}, '%') and
		</if>
		<if test="sex != null ">
			a.sex = #{sex}
		</if>
	</select>
	
	<select id="selectIfandWhereOper" resultMap="BaseResultMap">
		select
		<include refid="Base_Column_List" />
		from t_user a
		<where>
			<if test="email != null and email != ''">
			  	and a.email like CONCAT('%', #{email}, '%') 
			</if>
			<if test="sex != null ">
				and a.sex = #{sex}
			</if>
		</where>
	</select>
	
	<update id="updateIfOper" parameterType="TUser">
		update t_user
		  set 
			<if test="userName != null">
				user_name = #{userName,jdbcType=VARCHAR},
			</if>
			<if test="realName != null">
				real_name = #{realName,jdbcType=VARCHAR},
			</if>
			<if test="sex != null">
				sex = #{sex,jdbcType=TINYINT},
			</if>
			<if test="mobile != null">
				mobile = #{mobile,jdbcType=VARCHAR},
			</if>
			<if test="email != null">
				email = #{email,jdbcType=VARCHAR},
			</if>
			<if test="note != null">
				note = #{note,jdbcType=VARCHAR},
			</if>
			<if test="positionId != null">
				position_id = #{positionId,jdbcType=INTEGER}
			</if>
		where id = #{id,jdbcType=INTEGER}
	</update>
	
	<update id="updateIfAndSetOper" parameterType="TUser">
		update t_user
		  <set> 
			<if test="userName != null">
				user_name = #{userName,jdbcType=VARCHAR},
			</if>
			<if test="realName != null">
				real_name = #{realName,jdbcType=VARCHAR},
			</if>
			<if test="sex != null">
				sex = #{sex,jdbcType=TINYINT},
			</if>
			<if test="mobile != null">
				mobile = #{mobile,jdbcType=VARCHAR},
			</if>
			<if test="email != null">
				email = #{email,jdbcType=VARCHAR},
			</if>
			<if test="note != null">
				note = #{note,jdbcType=VARCHAR},
			</if>
			<if test="positionId != null">
				position_id = #{positionId,jdbcType=INTEGER},
			</if>
		</set>
		where id = #{id,jdbcType=INTEGER}
	</update>
	
	
	<insert id="insertIfOper" parameterType="TUser">
		insert into t_user (
			<if test="id != null">
				id,
			</if>
			<if test="userName != null">
				user_name,
			</if>
			<if test="realName != null">
				real_name,
			</if>
			<if test="sex != null">
				sex,
			</if>
			<if test="mobile != null">
				mobile,
			</if>
			<if test="email != null">
				email,
			</if>
			<if test="note != null">
				note,
			</if>
			<if test="positionId != null">
				position_id
			</if>
		)
		values(
			<if test="id != null">
				#{id,jdbcType=INTEGER},
			</if>
			<if test="userName != null">
				#{userName,jdbcType=VARCHAR},
			</if>
			<if test="realName != null">
				#{realName,jdbcType=VARCHAR},
			</if>
			<if test="sex != null">
				#{sex,jdbcType=TINYINT},
			</if>
			<if test="mobile != null">
				#{mobile,jdbcType=VARCHAR},
			</if>
			<if test="email != null">
				#{email,jdbcType=VARCHAR},
			</if>
			<if test="note != null">
				#{note,jdbcType=VARCHAR},
			</if>
			<if test="positionId != null">
				#{positionId,jdbcType=INTEGER}
			</if>
		)
	</insert>


	<select id="selectForeach4In" resultMap="BaseResultMap">
		select
		<include refid="Base_Column_List" />
		from t_user a
		where a.user_name in 
		<foreach collection="array" open="(" close=")" item="userName" index="i" separator=",">
			#{userName}
		</foreach>	
	</select>
	
	
	<insert id="insertForeach4Batch">
		insert into t_user (user_name, real_name,
		sex, mobile,email,note, position_id) 
		values
		<foreach collection="list" separator="," item="user">
			(
			#{user.userName,jdbcType=VARCHAR},
			#{user.realName,jdbcType=VARCHAR},
			#{user.sex,jdbcType=TINYINT}, 
			#{user.mobile,jdbcType=VARCHAR},
			#{user.email,jdbcType=VARCHAR},
			#{user.note,jdbcType=VARCHAR},
			#{user.positionId,jdbcType=INTEGER}
			)
		</foreach>
	
	
	</insert>





	<sql id="Base_Column_List">
		id, user_name, real_name, sex, mobile, email, note,
		position_id
	</sql>

	<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer">
		select
		<include refid="Base_Column_List" />
		from t_user
		where id = #{id,jdbcType=INTEGER}
	</select>

	<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
		delete from t_user
		where id = #{id,jdbcType=INTEGER}
	</delete>
	
	<insert id="insert1" parameterType="TUser" useGeneratedKeys="true"		keyProperty="id">
		insert into t_user (id, user_name, real_name,
		sex, mobile,
		email,
		note, position_id)
		values (#{id,jdbcType=INTEGER},
		#{userName,jdbcType=VARCHAR},
		#{realName,jdbcType=VARCHAR},
		#{sex,jdbcType=TINYINT}, #{mobile,jdbcType=VARCHAR},
		#{email,jdbcType=VARCHAR},
		#{note,jdbcType=VARCHAR},
		#{positionId,jdbcType=INTEGER})
	</insert>
	
	<insert id="insert2" parameterType="TUser">
	
		<selectKey  keyProperty="id" order="AFTER" resultType="int">
			select LAST_INSERT_ID()
		</selectKey>
		insert into t_user (id, user_name, real_name,
		sex, mobile,
		email,
		note, position_id)
		values (#{id,jdbcType=INTEGER},
		#{userName,jdbcType=VARCHAR},
		#{realName,jdbcType=VARCHAR},
		#{sex,jdbcType=TINYINT}, #{mobile,jdbcType=VARCHAR},
		#{email,jdbcType=VARCHAR},
		#{note,jdbcType=VARCHAR},
		#{positionId,jdbcType=INTEGER})
	</insert>
	
	
	
	
	<insert id="insertSelective" parameterType="TUser">
		insert into t_user
		<trim prefix="(" suffix=")" suffixOverrides=",">
			<if test="id != null">
				id,
			</if>
			<if test="userName != null">
				user_name,
			</if>
			<if test="realName != null">
				real_name,
			</if>
			<if test="sex != null">
				sex,
			</if>
			<if test="mobile != null">
				mobile,
			</if>
			<if test="email != null">
				email,
			</if>
			<if test="note != null">
				note,
			</if>
			<if test="positionId != null">
				position_id,
			</if>
		</trim>
		<trim prefix="values (" suffix=")" suffixOverrides=",">
			<if test="id != null">
				#{id,jdbcType=INTEGER},
			</if>
			<if test="userName != null">
				#{userName,jdbcType=VARCHAR},
			</if>
			<if test="realName != null">
				#{realName,jdbcType=VARCHAR},
			</if>
			<if test="sex != null">
				#{sex,jdbcType=TINYINT},
			</if>
			<if test="mobile != null">
				#{mobile,jdbcType=VARCHAR},
			</if>
			<if test="email != null">
				#{email,jdbcType=VARCHAR},
			</if>
			<if test="note != null">
				#{note,jdbcType=VARCHAR},
			</if>
			<if test="positionId != null">
				#{positionId,jdbcType=INTEGER},
			</if>
		</trim>
	</insert>
	<update id="updateByPrimaryKeySelective" parameterType="TUser">
		update t_user
		<set>
			<if test="userName != null">
				user_name = #{userName,jdbcType=VARCHAR},
			</if>
			<if test="realName != null">
				real_name = #{realName,jdbcType=VARCHAR},
			</if>
			<if test="sex != null">
				sex = #{sex,jdbcType=TINYINT},
			</if>
			<if test="mobile != null">
				mobile = #{mobile,jdbcType=VARCHAR},
			</if>
			<if test="email != null">
				email = #{email,jdbcType=VARCHAR},
			</if>
			<if test="note != null">
				note = #{note,jdbcType=VARCHAR},
			</if>
			<if test="positionId != null">
				position_id = #{positionId,jdbcType=INTEGER},
			</if>
		</set>
		where id = #{id,jdbcType=INTEGER}
	</update>
	<update id="updateByPrimaryKey" parameterType="TUser">
		update t_user
		set
		user_name = #{userName,jdbcType=VARCHAR},
		real_name =
		#{realName,jdbcType=VARCHAR},
		sex = #{sex,jdbcType=TINYINT},
		mobile =
		#{mobile,jdbcType=VARCHAR},
		email = #{email,jdbcType=VARCHAR},
		note =
		#{note,jdbcType=VARCHAR},
		position_id = #{positionId,jdbcType=INTEGER}
		where id = #{id,jdbcType=INTEGER}
	</update>
</mapper>

在这里插入图片描述
当接口中,方法入参有多个时:
1)使用map传参:

List<TUser> selectByEmailAndSex1(Map<String, Object> param);
<select id="selectByEmailAndSex1" resultMap="BaseResultMap"
		parameterType="map">
		select
		<include refid="Base_Column_List" />
		from t_user a
		where a.email like CONCAT('%', #{email}, '%') and
		a.sex = #{sex}
	</select>

方法二:使用@Param注解传入

List<TUser> selectByEmailAndSex2(@Param("email")String email,@Param("sex")Byte sex);
<select id="selectByEmailAndSex2" resultMap="BaseResultMap">
		select
		<include refid="Base_Column_List" />
		from t_user a
		where a.email like CONCAT('%', #{email}, '%') and
		a.sex = #{sex}
	</select>

方法三:将参数封装一个bean(当单个参数超过5个时)

List<TUser> selectByEmailAndSex3(EmailSexBean esb);
<select id="selectByEmailAndSex3" resultMap="BaseResultMap"
		parameterType="com.enjoylearning.mybatis.entity.EmailSexBean">
		select
		<include refid="Base_Column_List" />
		from t_user a
		where a.email like CONCAT('%', #{email}, '%') and
		a.sex = #{sex}
	</select>
// 多参数查询
	@Test
	public void testManyParamQuery() {
		// 2.获取sqlSession
		SqlSession sqlSession = sqlSessionFactory.openSession();
		// 3.获取对应mapper
		TUserMapper mapper = sqlSession.getMapper(TUserMapper.class);

		String email = "qq.com";
		Byte sex = 1;

		// 第一种方式使用map
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("email", email);
		params.put("sex", sex);
		List<TUser> list1 = mapper.selectByEmailAndSex1(params);
		System.out.println(list1.size());

		// 第二种方式直接使用参数
		List<TUser> list2 = mapper.selectByEmailAndSex2(email, sex);
		System.out.println(list2.size());

		// 第三种方式用对象
		EmailSexBean esb = new EmailSexBean();
		esb.setEmail(email);
		esb.setSex(sex);
		List<TUser> list3 = mapper.selectByEmailAndSex3(esb);
		System.out.println(list3.size());
	}

杜绝使用map原因:
主要是因为,代码不易维护,其他人读该代码时,需要仔细查看map中有哪些属性?可读性差。

11.自动映射与手动映射:

优先推荐使用手动映射,因为可以将java代码与表结构解耦,如果将来修改表时,只需要一些配置文件就可以了。

12.resultMap元素 子元素

在这里插入图片描述
id作用:1.唯一标识一条数据;2.查询时,数据根据id合并。

<resultMap id="BaseResultMap" type="TUser">
		
		<!-- <constructor>
			<idArg column="id" javaType="int"/>
			<arg column="user_name" javaType="String"/>
		</constructor>  -->
		<id column="id" property="id" jdbcType="INTEGER" />
		<result column="user_name" property="userName" jdbcType="VARCHAR" />
		<result column="real_name" property="realName" jdbcType="VARCHAR" />
		<result column="sex" property="sex" jdbcType="TINYINT" />
		<result column="mobile" property="mobile" jdbcType="VARCHAR" />
		<result column="email" property="email" jdbcType="VARCHAR" />
		<result column="note" property="note" jdbcType="VARCHAR" />
		<result column="position_id" property="positionId" jdbcType="INTEGER" />
	</resultMap>

1)id & result
在这里插入图片描述
 id 和 result 都将一个列的值映射到一个简单数据类型(字符串,整型,双精度浮点数,日期等)的属性或字段

 两者之间的唯一不同是, id 表示的结果将是对象的标识属性,这会在比较对象实例时用到。 这样可以提高整体的性能,尤其是缓存和嵌套结果映射(也就是联合映射)的时候

在这里插入图片描述
如果是自定义的类型转换(java对象属性与数据源中字段转换),如枚举,需要自定义转换规则:
typeHandler

2)constructor用法:

<resultMap id="BaseResultMap" type="TUser">
		
		<!-- <constructor>
			<idArg column="id" javaType="int"/>
			<arg column="user_name" javaType="String"/>
		</constructor>  -->
		<id column="id" property="id" jdbcType="INTEGER" />
		<result column="user_name" property="userName" jdbcType="VARCHAR" />
		<result column="real_name" property="realName" jdbcType="VARCHAR" />
		<result column="sex" property="sex" jdbcType="TINYINT" />
		<result column="mobile" property="mobile" jdbcType="VARCHAR" />
		<result column="email" property="email" jdbcType="VARCHAR" />
		<result column="note" property="note" jdbcType="VARCHAR" />
		<result column="position_id" property="positionId" jdbcType="INTEGER" />
	</resultMap>

如上配置中,使用constructor标签时:

package com.enjoylearning.mybatis.entity;

import java.util.List;

import org.apache.ibatis.annotations.Param;

public class TUser {
    private Integer id;

    private String userName;

    private String realName;

    private Byte sex;

    private String mobile;

    private String email;

    private String note;

    private Integer positionId;
    
    private List<TJobHistory> jobs ;

/*    
	public TUser(Integer id, String userName) {
		super();
		this.id = id;
		this.userName = userName;
	}
	*/

.......	

类中存在构造方法时。
constructor使用场景:如:.没有无参构造方法。(如果没有get,set方法时,也可以反射赋值成功,springmvc传参时,调用的是set方法,不要混淆)。

为什么互联网项目不使用多表联合查询,尽量使用单表查询?
因为,如果数据量过大,分库分表后,多表查询可能会报错。

13.insert, update 和 delete

在这里插入图片描述

int insert1(TUser record);
<insert id="insert1" parameterType="TUser" useGeneratedKeys="true"		keyProperty="id">
		insert into t_user (id, user_name, real_name,
		sex, mobile,
		email,
		note, position_id)
		values (#{id,jdbcType=INTEGER},
		#{userName,jdbcType=VARCHAR},
		#{realName,jdbcType=VARCHAR},
		#{sex,jdbcType=TINYINT}, #{mobile,jdbcType=VARCHAR},
		#{email,jdbcType=VARCHAR},
		#{note,jdbcType=VARCHAR},
		#{positionId,jdbcType=INTEGER})
	</insert>

useGeneratedKeys:主键生成策略
keyProperty:指定id。

测试:

@Test
	// 测试插入数据自动生成id
	public void testInsertGenerateId1() throws IOException {
		// 2.获取sqlSession
		SqlSession sqlSession = sqlSessionFactory.openSession();
		// 3.获取对应mapper
		TUserMapper mapper = sqlSession.getMapper(TUserMapper.class);
		// 4.执行查询语句并返回结果
		TUser user1 = new TUser();
		user1.setUserName("test1");
		user1.setRealName("realname1");
		user1.setEmail("myemail1");
		mapper.insert1(user1);
		sqlSession.commit();
		System.out.println(user1.getId());
	}
<insert id="insert1" parameterType="TUser" useGeneratedKeys="true"		keyProperty="id">
		insert into t_user (id, user_name, real_name,
		sex, mobile,
		email,
		note, position_id)
		values (#{id,jdbcType=INTEGER},
		#{userName,jdbcType=VARCHAR},
		#{realName,jdbcType=VARCHAR},
		#{sex,jdbcType=TINYINT}, #{mobile,jdbcType=VARCHAR},
		#{email,jdbcType=VARCHAR},
		#{note,jdbcType=VARCHAR},
		#{positionId,jdbcType=INTEGER})
	</insert>

如果去除useGeneratedKeys,keyProperty属性,则该测试代码返回值为null,如果配置,则可以拿到。

如果配置useGeneratedKeys,keyProperty属性后,如果传入的待持久化的对象中,存在自定义id值,则会持久化自定义值,如果传入的id为null,则数据库会根据主键生成规则,自动生成id值。

这两个属性,只能使用在mysql与SqlServer中,oracle不支持自增。

14.selectKey元素

selectKey:

int insert2(TUser record);
<insert id="insert2" parameterType="TUser">
	
		<selectKey  keyProperty="id" order="AFTER" resultType="int">
			select LAST_INSERT_ID()
		</selectKey>
		insert into t_user (id, user_name, real_name,
		sex, mobile,
		email,
		note, position_id)
		values (#{id,jdbcType=INTEGER},
		#{userName,jdbcType=VARCHAR},
		#{realName,jdbcType=VARCHAR},
		#{sex,jdbcType=TINYINT}, #{mobile,jdbcType=VARCHAR},
		#{email,jdbcType=VARCHAR},
		#{note,jdbcType=VARCHAR},
		#{positionId,jdbcType=INTEGER})
	</insert>

其中,select LAST_INSERT_ID()表示得到数据库中最新的字段,插入

猜你喜欢

转载自blog.csdn.net/qq_43277087/article/details/105667230