MyBatis 笔记


软件开发常用结构

三层架构
界面层: 和用户打交道的, 接收用户的请求参数, 显示处理结果的。(jsp ,html ,servlet)
业务逻辑层: 接收了界面层传递的数据,计算逻辑,调用数据库,获取数据
数据访问层: 就是访问数据库, 执行对数据的查询,修改,删除等等的。

三层对应的处理框架
界面层—servlet—springmvc(框架)
业务逻辑层—service类–spring(框架)
数据访问层—dao类–mybatis(框架)

MyBatis 框架

mybatis是 MyBatis SQL Mapper Framework for Java (sql映射框架)

1)sql mapper :sql映射
可以把数据库表中的一行数据 映射为 一个java对象。一行数据可以看做是一个java对象。操作这个对象,就相当于操作表中的数据

2) Data Access Objects(DAOs) : 数据访问 , 对数据库执行增删改查。

MyBatis 提供的功能

1.提供了创建Connection ,Statement, ResultSet的能力 ,不用开发人员创建这些对象了;

2.提供了执行sql语句的能力, 不用你执行sql

3.提供了循环sql, 把sql的结果转为java对象, List集合的能力,替代如下代码:

  while (rs.next()) {
	Student stu = new Student();
	stu.setId(rs.getInt("id"));
	stu.setName(rs.getString("name"));
	stu.setAge(rs.getInt("age"));
	//从数据库取出数据转为 Student 对象,封装到 List 集合
	stuList.add(stu);
  }

4.提供了关闭资源的能力,不用你关闭Connection, Statement, ResultSet

开发人员做的是: 提供sql语句
最后是: 开发人员提供sql语句–mybatis处理sql—开发人员得到List集合或java对象(表中的数据)

总结:
mybatis是一个sql映射框架,提供的数据库的操作能力。增强的JDBC,
使用mybatis让开发人员集中精神写sql就可以了,不必关心Connection,Statement,ResultSet
的创建,销毁,sql的执行。

使用MyBatis 示例

搭建 MyBatis 开发环境

1.创建 mysql 数据库和表
在这里插入图片描述
2.创建maven工程
在pom文件中加入依赖和插件

<dependencies>
 	<dependency>
 		<groupId>junit</groupId>
 		<artifactId>junit</artifactId>
 		<version>4.11</version>
 		<scope>test</scope>
	</dependency>
	
 	<dependency>
 		<groupId>org.mybatis</groupId>
 		<artifactId>mybatis</artifactId>
 		<version>3.5.1</version>
	</dependency>
	
 	<dependency>
 		<groupId>mysql</groupId>
 		<artifactId>mysql-connector-java</artifactId>
 		<version>5.1.9</version>
 		</dependency>
 	</dependencies>
 	
<build>
 	<resources>
 		<resource>
 		<directory>src/main/java</directory><!--所在的目录-->
 		<includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
 			<include>**/*.properties</include>
 			<include>**/*.xml</include>
 		</includes>
 		<filtering>false</filtering>
 		</resource>
	</resources>
 <plugins>
 <plugin>
 	<artifactId>maven-compiler-plugin</artifactId>
 	<version>3.1</version>
 	<configuration>
 	<source>1.8</source>
 	<target>1.8</target>
	</configuration>
	</plugin>
 </plugins>

3.编写实体类Student


public class Student {
 	//属性名和列名一样 
 	private Integer id;
 	private String name;
 	private String email;
 	private Integer age;
 	// set ,get , toString
 	...
}

4.编写Dao接口StudentDao


package com.bjpowernode.dao;
import com.bjpowernode.domain.Student;
import java.util.List;
/*
* <p>Description: Dao 接口 </p>
* <p>Company: http://www.bjpowernode.com
*/
public interface StudentDao {
 	/*查询所有数据*/
 	List<Student> selectStudents();
}

5.编写 Dao 接口 Mapper 映射文件 StudentDao.xml
要求:

  1. 在 dao 包中创建文件 StudentDao.xml
  2. 要 StudentDao.xml 文件名称和接口 StudentDao 一样,区分大小写的一样。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import  ssl
ssl._create_default_https_context = ssl._create_unverified_context

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">
<!--
 namespace:必须有值,自定义的唯一字符串 
 推荐使用:dao 接口的全限定名称 
--> 
<mapper namespace="com.bjpowernode.dao.StudentDao">
 <!--
 <select>: 查询数据, 标签中必须是 select 语句
 id: sql 语句的自定义名称,推荐使用 dao 接口中方法名称, 
 使用名称表示要执行的 sql 语句
 resultType: 查询语句的返回结果数据类型,使用全限定类名 
 -->
 <select id="selectStudents" resultType="com.bjpowernode.domain.Student">
 <!--要执行的 sql 语句-->
 select id,name,email,age from student
 </select>
</mapper>

6.创建 MyBatis 主配置文件
项目 src/main 下创建 resources 目录,设置 resources 目录为 resources root
创建主配置文件:名称为 mybatis.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>
 <!--配置 mybatis 环境-->
 <environments default="mysql">
 <!--id:数据源的名称-->
 <environment id="mysql">
 <!--配置事务类型:使用 JDBC 事务(使用 Connection 的提交和回滚)-->
 <transactionManager type="JDBC"/>
 <!--数据源 dataSource:创建数据库 Connection 对象
 type: POOLED 使用数据库的连接池 
 -->

 <dataSource type="POOLED">
 <!--连接数据库的四个要素-->
 <property name="driver" value="com.mysql.jdbc.Driver"/>
 <property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
 <property name="username" value="root"/>
 <property name="password" value="123456"/>
 </dataSource>
 </environment>
 </environments>
 <mappers>
 <!--告诉 mybatis 要执行的 sql 语句的位置-->
 <mapper resource="com/bjpowernode/dao/StudentDao.xml"/>
 </mappers>
</configuration>

7.创建测试类 MyBatisTest

@Test
public void testStart() throws IOException {
 //1.mybatis 主配置文件 
 String config = "mybatis-config.xml";
 //2.读取配置文件 
 InputStream in = Resources.getResourceAsStream(config);
 //3.创建 SqlSessionFactory 对象,目的是获取 SqlSession 
 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
 //4.获取 SqlSession,SqlSession 能执行 sql 语句
 SqlSession session = factory.openSession();
 //5.执行 SqlSession 的 selectList()
 List<Student> studentList = session.selectList("com.bjpowernode.dao.StudentDao.selectStudents");
 //6.循环输出查询结果 
 studentList.forEach( student -> System.out.println(student));
 //7.关闭 SqlSession,释放资源
 session.close();
}

MyBatis 对象分析

Resources类

Resources 类,顾名思义就是资源,用于读取资源文件。其有很多方法通过加载并解析资源文件,返回不同类型的 IO 流对象。

SqlSessionFactoryBuilder 类

SqlSessionFactory 的 创 建 , 需 要 使 用 SqlSessionFactoryBuilder 对 象 的 build() 方 法 。 由 于SqlSessionFactoryBuilder 对象在创建完工厂对象后,就完成了其历史使命,即可被销毁。所以,一般会将该 SqlSessionFactoryBuilder 对象创建为一个方法内的局部对象,方法结束,对象销毁。

SqlSessionFactory 接口

SqlSessionFactory 接口对象是一个重量级对象(系统开销大的对象),是线程安全的,所以一个应用只需要一个该对象即可。创建 SqlSession 需要使用 SqlSessionFactory 接口的的 openSession()方法。
1.openSession(true):创建一个有自动提交功能的 SqlSession 2.openSession(false):创建一个非自动提交功能的 SqlSession,需手动提交
3.openSession():同 openSession(false)

SqlSession 接口

SqlSession 接口对象用于执行持久化操作。一个 SqlSession 对应着一次数据库会话,一次会话以SqlSession 对象的创建开始,以 SqlSession 对象的关闭结束。
SqlSession 接口对象是线程不安全的,所以每次数据库会话结束前,需要马上调用其 close()方法,将其关闭。再次需要会话,再次创建。 SqlSession 在方法内部创建,使用完毕后关闭。

创建工具类

创建MyBatisUtil 类

/**
* <p>Description: 实体类 </p>
* <p>Company: http://www.bjpowernode.com
*/
public class MyBatisUtil {
	//定义 SqlSessionFactory
 	private static SqlSessionFactory factory = null;
 	static {
 		//使用 静态块 创建一次 SqlSessionFactory
	 	try{
 			String config = "mybatis-config.xml";
 			//读取配置文件 
 			InputStream in = Resources.getResourceAsStream(config);
 			//创建 SqlSessionFactory 对象 
 			factory = new SqlSessionFactoryBuilder().build(in);
 			}catch (Exception e){
 			factory = null;
 			e.printStackTrace();
 			}
 		}
 	/* 获取 SqlSession 对象 */
 	public static SqlSession getSqlSession(){
 		SqlSession session = null;
 		if( factory != null){
 		session = factory.openSession();
		 }
 		return session;
 	} 
 }
data = pd.read_csv(
    'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())

使用 MyBatisUtil 类

@Test
public void testUtils() throws IOException {
	 SqlSession session = MyBatisUtil.getSqlSession();
	 List<Student> studentList = session.selectList(
	"com.bjpowernode.dao.StudentDao.selectStudents");
	 studentList.forEach( student -> System.out.println(student));
	 session.close();
}

该处使用的url网络请求的数据。


传统 Dao 开发方式的分析

在前面例子中自定义 Dao 接口实现类时发现一个问题:Dao 的实现类其实并没有干什么实质性的工作,它仅仅就是通过 SqlSession 的相关 API 定位到映射文件 mapper 中相应 id 的 SQL 语句,真正对 DB 进行操作的工作其实是由框架通过 mapper 中的 SQL 完成的。所以,MyBatis 框架就抛开了 Dao 的实现类,直接定位到映射文件 mapper 中的相应 SQL 语句,对DB 进行操作。这种对 Dao 的实现方式称为 Mapper 的动态代理方式。Mapper 动态代理方式无需程序员实现 Dao 接口。接口是由 MyBatis 结合映射文件自动生成的动态代理实现的。

MyBatis 框架 Dao 代理

Dao 代理实现 CURD

步骤
1.去掉 Dao 接口实现类

2.使用getMapper 获取代理对象
只需调用 SqlSession 的 getMapper()方法,即可获取指定接口的实现类对象。该方法的参数为指定 Dao接口类的 class 值。

public class TestDao {
    @Test
    public void TestSelect(){
        SqlSession sqlSession= MybatisUtils.getSqlSession();
        StudentDao Dao = sqlSession.getMapper(StudentDao.class);
        List<Student> students = Dao.selectStudent();
        System.out.println(students);
    }

原理

使用的是动态代理实现的,返回的对象都是MapperProxy类型的。
MapperProxy 类定义:

public class MapperProxy<T> implements InvocationHandler, Serializable

invoke方法:

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       try {
           if (Object.class.equals(method.getDeclaringClass())) {
               return method.invoke(this, args);
           }

           if (this.isDefaultMethod(method)) {
               return this.invokeDefaultMethod(proxy, method, args);
           }
       } catch (Throwable var5) {
           throw ExceptionUtil.unwrapThrowable(var5);
       }

       MapperMethod mapperMethod = this.cachedMapperMethod(method);
       return mapperMethod.execute(this.sqlSession, args);
   }
public Object execute(SqlSession sqlSession, Object[] args) {
      Object result;
      Object param;
      switch(this.command.getType()) {
      case INSERT:
          param = this.method.convertArgsToSqlCommandParam(args);
          result = this.rowCountResult(sqlSession.insert(this.command.getName(), param));
          break;
      case UPDATE:
          param = this.method.convertArgsToSqlCommandParam(args);
          result = this.rowCountResult(sqlSession.update(this.command.getName(), param));
          break;
      case DELETE:
          param = this.method.convertArgsToSqlCommandParam(args);
          result = this.rowCountResult(sqlSession.delete(this.command.getName(), param));
          break;
      case SELECT:
          if (this.method.returnsVoid() && this.method.hasResultHandler()) {
              this.executeWithResultHandler(sqlSession, args);
              result = null;
          } else if (this.method.returnsMany()) {
              result = this.executeForMany(sqlSession, args);
          } else if (this.method.returnsMap()) {
              result = this.executeForMap(sqlSession, args);
          } else if (this.method.returnsCursor()) {
              result = this.executeForCursor(sqlSession, args);
          } else {
              param = this.method.convertArgsToSqlCommandParam(args);
              result = sqlSession.selectOne(this.command.getName(), param);
              if (this.method.returnsOptional() && (result == null || !this.method.getReturnType().equals(result.getClass()))) {
                  result = Optional.ofNullable(result);
              }
          }
          break;
      case FLUSH:
          result = sqlSession.flushStatements();
          break;
      default:
          throw new BindingException("Unknown execution method for: " + this.command.getName());
      }

      if (result == null && this.method.getReturnType().isPrimitive() && !this.method.returnsVoid()) {
          throw new BindingException("Mapper method '" + this.command.getName() + " attempted to return null from a method with a primitive return type (" + this.method.getReturnType() + ").");
      } else {
          return result;
      }
  }

方法参数

parameterType

parameterType: 接口中方法参数的类型, 类型的完全限定名或别名。这个属性是可选的,因为 MyBatis 可以推断出具体传入语句的参数,默认值为未设置(unset)。接口中方法的参数从 java 代码传入到mapper 文件的 sql 语句。select,insert,update,delete都可以使用 parameterType 指定类型。
例如:


<delete id="deleteStudent" parameterType="int">
 	delete from student where id=#{studentId}
</delete>

<delete id="deleteStudent" parameterType="java.lang.Integer">
 	delete from student where id=#{studentId}
</delete>

一个简单参数

Dao 接口中方法的参数只有一个简单类型(java 基本类型和 String),占位符 #{ 任意字符 },和方法的参数名无关。
接口方法:

Student selectById(int id);

mapper文件:


<select id="selectById" resultType="com.bjpowernode.domain.Student">
 	select id,name,email,age from student where id=#{studentId}
</select>
#{studentId} , studentId 是自定义的变量名称,和方法参数名无关。

多个参数-使用@Param

当 Dao 接口方法多个参数,需要通过名称使用参数。在方法形参前面加入@Param(“自定义参数名”),mapper 文件使用#{自定义参数名}。

接口方法:

List<Student> selectMultiParam(@Param("personName") String name, @Param("personAge") int age);

mapper 文件:


<select id="selectMultiParam" resultType="com.bjpowernode.domain.Student">
 	select id,name,email,age from student where name=#{personName} or age=#{personAge}
</select>

多个参数-使用对象

使用 java 对象传递参数, java 的属性值就是 sql 需要的参数值。 每一个属性就是一个参数。
语法格式: #{ property,javaType=java 中数据类型名,jdbcType=数据类型名称 }javaType, jdbcType 的类型 MyBatis 可以检测出来,一般不需要设置。常用格式 #{ property }
接口方法:

List<Student> selectMultiObject(QueryParam queryParam);

mapper 文件:


<select id="selectMultiObject" resultType="com.bjpowernode.domain.Student">
 	select id,name,email,age from student where name=#{queryName} or age =#{queryAge}
</select><select id="selectMultiObject" resultType="com.bjpowernode.domain.Student">
 	select id,name,email,age from student where name=#{queryName,javaType=string,jdbcType=VARCHAR} or age =#{queryAge,javaType=int,jdbcType=INTEGER}
</select>

多个参数-按位置

参数位置从 0 开始, 引用参数语法 #{ arg 位置 } , 第一个参数是#{arg0}, 第二个是#{arg1}
注意:mybatis-3.3 版本和之前的版本使用#{0},#{1}方式, 从 mybatis3.4 开始使用#{arg0}方式。

接口方法:

List<Student> selectByNameAndAge(String name,int age);

mapper 文件:

<select id="selectByNameAndAge" resultType="com.bjpowernode.domain.Student">
 	select id,name,email,age from student where name=#{arg0} or age =#{arg1}
</select>

多个参数-使用 Map

Map 集合可以存储多个值,使用Map向 mapper 文件一次传入多个参数。Map 集合使用 String的 key,Object 类型的值存储参数。 mapper 文件使用 # { key } 引用参数值。
接口方法:

List<Student> selectMultiMap(Map<String,Object> map);

mapper 文件:

<select id="selectMultiMap" resultType="com.bjpowernode.domain.Student">
 select id,name,email,age from student where name=#{myname} or age =#{myage}
</select>

#和$

select id,name, email,age from student where id=#{studentId}
#的结果: select id,name, email,age from student where id=?

select id,name, email,age from student where id=${studentId}
$ 的结果:select id,name, email,age from student where id=1001

String sql=“select id,name, email,age from student where id=” + “1001”;
使用的Statement对象执行sql, 效率比PreparedStatement低
$ 可以替换表名或者列名, 你能确定数据是安全的。可以使用$

# 和 $区别
  1. #使用 ?在sql语句中做占位的, 使用PreparedStatement执行sql,效率高
  2. #能够避免sql注入,更安全。
  3. $不使用占位符,是字符串连接方式,使用Statement对象执行sql,效率低
  4. $有sql注入的风险,缺乏安全性。
  5. $:可以替换表名或者列名

封装 MyBatis 输出结果

resultType

resultType: 执行 sql 得到 ResultSet 转换的类型,使用类型的完全限定名或别名。 注意如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。resultType 和 resultMap,不能同时使用。
在这里插入图片描述

简单类型

接口方法:

int countStudent();

mapper 文件:


<select id="countStudent" resultType="int">
 select count(*) from student
</select>

对象类型

接口方法:

Student selectById(int id);

mapper 文件:


<select id="selectById" resultType="com.bjpowernode.domain.Student">
 select id,name,email,age from student where id=#{studentId}
</select>

Map

sql 的查询结果作为 Map 的 key 和 value。推荐使用 Map<Object,Object>。
注意:Map 作为接口返回值,sql 语句的查询结果最多只能有一条记录。大于一条记录是错误。
接口方法:

Map<Object,Object> selectReturnMap(int id);

mapper 文件:

<select id="selectReturnMap" resultType="java.util.HashMap">
 select name,email from student where id = #{studentId}
</select>

resultMap

resultMap 可以自定义 sql 的结果和 java 对象属性的映射关系。更灵活的把列值赋值给指定属性。常用在列名和 java 对象属性名不一样的情况。
使用方式:
1.先定义 resultMap,指定列名和属性的对应关系。
2.在中把 resultType 替换为 resultMap。
接口方法:

List<Student> selectUseResultMap(QueryParam param);

mapper 文件:


<!-- 创建 resultMap
 id:自定义的唯一名称,在<select>使用
 type:期望转为的 java 对象的全限定名称或别名 
--> 
<resultMap id="studentMap" type="com.bjpowernode.domain.Student">
 	<!-- 主键字段使用 id -->
 	<id column="id" property="id" />
 	<!--非主键字段使用 result-->
 	<result column="name" property="name"/>
 	<result column="email" property="email" />
 	<result column="age" property="age" />
</resultMap>
<!--resultMap: resultMap 标签中的 id 属性值--> 
<select id="selectUseResultMap" resultMap="studentMap">
 	select id,name,email,age from student where name=#{queryName} or age=#{queryAge}
</select>

实体类属性名和列名不同的处理方式

1.使用列别名和resultType

接口方法

List<PrimaryStudent> selectUseFieldAlias(QueryParam param);

mapper 文件:


<select id="selectUseFieldAlias" 
resultType="com.bjpowernode.domain.PrimaryStudent">
 select id as stuId, name as stuName,age as stuAge
 from student where name=#{queryName} or age=#{queryAge}
</select>

2.使用resultMap
接口方法

List<PrimaryStudent> selectUseDiffResultMap(QueryParam param);

mapper 文件:


<!-- 创建 resultMap
 id:自定义的唯一名称,在<select>使用
 type:期望转为的 java 对象的全限定名称或别名 
--> 
<resultMap id="primaryStudentMap" type="com.bjpowernode.domain.PrimaryStudent">
 	<!-- 主键字段使用 id -->
 	<id column="id" property="stuId" />
 	<!--非主键字段使用 result-->
 	<result column="name" property="stuName"/>
 	<result column="age" property="stuAge" />
</resultMap>
<!--resultMap: resultMap 标签中的 id 属性值--> 
<select id="selectUseDiffResultMap" resultMap="primaryStudentMap">
 	select id,name,email,age from student where name=#{queryName} or age=#{queryAge}
</select>

模糊 like

模糊查询的实现有两种方式,
一是 java 代码中给查询数据加上“%” ;

where name like #{studentName}

二是在 mapper 文件 sql 语句的条件位置加上“%”。

where name like "%" #{studentName} "%"

动态 SQL

动态 SQL,通过 MyBatis 提供的各种标签对条件作出判断以实现动态拼接 SQL 语句。这里的条件判断使用的表达式为 OGNL 表达式。常用的动态 SQL 标签有if、where、choose、foreach等。

动态 SQL,主要用于解决查询条件不确定的情况:在程序运行期间,根据用户提交的查询条件进行查询。提交的查询条件不同,执行的 SQL 语句不同。若将每种可能的情况均逐一列出,对所有条件进行排列组合,将会出现大量的 SQL 语句。此时,可使用动态 SQL 来解决这样的问题

动态 SQL-- if

对于该标签的执行,当 test 的值为 true 时,会将其包含的 SQL 片断拼接到其所在的 SQL 语句中。
语法: sql 语句的部分
接口方法:

List<Student> selectStudentIf(Student student);

mapper 文件:

<select id="selectStudentIf" resultType="com.bjpowernode.domain.Student">
 	select id,name,email,age from student
 	where 1=1
 	<if test="name != null and name !='' ">
 	and name = #{name}
 	</if>
 	<if test="age > 0 ">
 	and age &gt; #{age}
 	</if>
</select>

动态 SQL-- where

标签的中存在一个比较麻烦的地方:需要在 where 后手工添加 1=1 的子句。因为,若 where 后的所有条件均为 false,而 where 后若又没有 1=1 子句,则 SQL 中就会只剩下一个空的 where,SQL出错。所以,在 where 后,需要添加永为真子句 1=1,以防止这种情况的发生。但当数据量很大时,会严重影响查询效率。
使用标签,在有查询条件时,可以自动添加上 where 子句;没有查询条件时,不会添加where 子句。需要注意的是,第一个标签中的 SQL 片断,可以不包含 and。不过,写上 and 也不错,系统会将多出的 and 去掉。但其它中 SQL 片断的 and,必须要求写上。否则 SQL 语句将拼接出错。

语法: 其他动态 sql
接口方法:

List<Student> selectStudentWhere(Student student);

mapper 文件:

<select id="selectStudentWhere" resultType="com.bjpowernode.domain.Student">
 	select id,name,email,age from student
 	<where>
 	<if test="name != null and name !='' ">
 	and name = #{name}
	</if>
 	<if test="age > 0 ">
 	and age &gt; #{age}
 	</if>
 	</where>
</select>

动态 SQL-- foreach

标签用于实现对于数组与集合的遍历。对其使用,需要注意:
collection 表示要遍历的集合类型, list ,array 等。
open、close、separator 为对遍历内容的 SQL 拼接。

语法:

<foreach collection="集合类型" open="开始的字符" close="结束的字符" item="集合中的成员" separator="集合成员之间的分隔符">
 	#{item 的值}
</foreach>

1.遍历 List<简单类型>
表达式中的 List 使用 list 表示,其大小使用 list.size 表示。

需求:查询学生 id 是 1002,1005,1006
接口方法:

List<Student> selectStudentForList(List<Integer> idList);

mapper 文件:


<select id="selectStudentForList" 
resultType="com.bjpowernode.domain.Student">
 	select id,name,email,age from student
 	<if test="list !=null and list.size > 0 ">
 	where id in
 	<foreach collection="list" open="(" close=")" item="stuid" separator=",">
 		#{stuid}
 	</foreach>
 	</if>
</select>

2.遍历 List<对象类型>
接口方法:

List<Student> selectStudentForList2(List<Student> stuList);

mapper 文件:


<select id="selectStudentForList2" resultType="com.bjpowernode.domain.Student">
 	select id,name,email,age from student
 	<if test="list !=null and list.size > 0 ">
 	where id in
 	<foreach collection="list" open="(" close=")" item="stuobject" separator=",">
 		#{stuobject.id}
 	</foreach>
 	</if>
</select>

MyBatis 配置文件

主配置文件

之前项目中使用的 mybatis.xml 是主配置文件。
主配置文件特点:
1.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"> 

2.根元素

<configuration> 

3.主要包含内容:

  1. 定义别名
  2. 数据源
  3. mapper 文件

dataSource 标签

Mybatis 中访问数据库,可以连接池技术,但它采用的是自己的连接池技术。在 Mybatis 的 mybatis.xml配置文件中,通过<dataSource type=”pooled”>来实现 Mybatis 中连接池的配置。

dataSource 配置

在 MyBatis.xml 主配置文件,配置 dataSource:

<dataSource type="POOLED">
<!--连接数据库的四个要素-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" 
value="jdbc:mysql://localhost:3306/ssm?charset=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>

MyBatis 在初始化时,根据的 type 属性来创建相应类型的的数据源 DataSource,即:
type=”POOLED”:MyBatis 会创建 PooledDataSource 实例
type=”UNPOOLED” : MyBatis 会创建 UnpooledDataSource 实例
type=”JNDI”:MyBatis 会从 JNDI 服务上查找 DataSource 实例,然后返回使用

使用数据库属性配置文件

为了方便对数据库连接的管理,DB 连接四要素数据一般都是存放在一个专门的属性文件中的。MyBatis主配置文件需要从这个属性文件中读取这些数据
1.在 classpath 路径下,创建 properties 文件

2.使用 properties 标签
在这里插入图片描述
3.使用 key 指定值


<dataSource type="POOLED">
 <!--使用 properties 文件: 语法 ${key}-->
 <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>

typeAliases(类型别名)

Mybatis 支持默认别名,我们也可以采用自定义别名方式来开发,主要使用在mybatis.xml 主配置文件定义别名:

<typeAliases>
 	<!--
 	定义单个类型的别名
 	type:类型的全限定名称
 	alias:自定义别名 
 	-->
 	<typeAlias type="com.bjpowernode.domain.Student" alias="mystudent"/>
 	<!--
 	批量定义别名,扫描整个包下的类,别名为类名(首字母大写或小写都可以)
 	name:包名 
 	-->
 	<package name="com.bjpowernode.domain"/>
 	<package name="...其他包"/>
</typeAliases>

mapper.xml 文件,使用别名表示类型


<select id="selectStudents" resultType="mystudent">
 	select id,name,email,age from student
</select>

mappers(映射器)

1.<mapper resource=" " />
使用相对于类路径的资源,从 classpath 路径查找文件
例如:<mapper resource="com/bjpowernode/dao/StudentDao.xml" />

2.<package name=""/>
指定包下的所有 Dao 接口
如:<package name="com.bjpowernode.dao"/>
注意:此种方法要求 Dao 接口名称和 mapper 映射文件名称相同,且在同一个目录中。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值