该技术博客是关于动力节点Mybatis教程的笔记总结,方便自己学习的同时希望能为大家带来帮助!
更多好文推荐 :
- 【步骤详细】手把手整合Spring + Mybatis
- Java常用类笔记
- 计算机底层原理——汇编语言
- 学习Java异常,吃透这篇足够
三层架构包含的三层:
三层的职责:
三层的处理请求的交互:
用户—> 界面层—>业务逻辑层—>数据访问层—>DB 数据库
为什么要使用三层?
MyBatis 框架:
MyBatis 是一个优秀的基于 java 的持久层框架,内部封装了 jdbc,开发者只需要关注 sql 语句本身,而不需要处理加载驱动、创建连接、创建 statement、关闭连接,资源等繁杂的过程。
MyBatis 通过 xml 或注解两种方式将要执行的各种 sql 语句配置起来,并通过 java 对象和 sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回。
Spring 框架:
Spring 框架为了解决软件开发的复杂性而创建的。Spring 使用的是基本的 JavaBean 来完成以前非常复杂的企业级开发。Spring 解决了业务对象,功能模块之间的耦合,不仅在 javase,web 中使用,大部分 Java 应用都可以从 Spring 中受益。
Spring 是一个轻量级控制反转(IoC)和面向切面(AOP)的容器。
SpringMVC 框架:
Spring MVC 属于 SpringFrameWork 3.0 版本加入的一个模块,为 Spring 框架提供了构建 Web 应用程序的能力。现在可以 Spring 框架提供的 SpringMVC 模块实现 web 应用开发,在 web 项目中可以无缝使用 Spring 和 Spring MVC 框架。
框架(Framework) 是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种认为,框架是可被应用开发者定制的应用骨架、模板。
简单的说,框架其实是半成品软件,就是一组组件,供你使用完成你自己的系统。从另一个角度来说框架一个舞台,你在舞台上做表演。在框架基础上加入你要完成的功能。
框架安全的,可复用的,不断升级的软件。
框架要解决的最重要的一个问题是技术整合,在 J2EE 的 框架中,有着各种各样的技术,不同的应用,系统使用不同的技术解决问题。需要从 J2EE 中选择不同的技术,而技术自身的复杂性,有导致更大的风险。
企业在开发软件项目时,主要目的是解决业务问题。 即要求企业负责技术本身,又要求解决业务问题。这是大多数企业不能完成的。框架把相关的技术融合在一起,企业开发可以集中在业务领域方面。
另一个方面框架可以提高开发的效率。
我们在学习使用JDBC操作数据库时,发现JDBC操作太过繁琐,有许多重复性的代码,代码显得非常臃肿冗余,除了sql语句编写,其他操作基本上是大同小异,很影响开发效率。
所以Mybatis框架的出现主要目的可以理解为:取代JDBC技术操作数据库!
MyBatis 框架:
MyBatis 本是 apache 的一个开源项目 iBatis, 2010 年这个项目由 apache software foundation 迁
移到了 google code,并且改名为 MyBatis 。2013 年 11 月迁移到 Github。
iBATIS 一词来源于“internet”和“abatis”的组合,是一个基于 Java 的持久层框架。iBATIS 提供的
持久层框架包括 SQL Maps 和 Data Access Objects(DAOs)
减轻使用 JDBC 的复杂性,不用重复的创建 Connetion , Statement ; 不用编写关闭资源代码。直接使用 java 对象,表示结果数据。让开发者专注 SQL 的处理。 其他分心的工作由 MyBatis 代劳。
MyBatis 可以完成:
# 创建数据库,名为ssm
create database ssm;
# 选中ssm数据库
use ssm;
# 在ssm数据库中创建表,表名为student
CREATE TABLE `student` (
`id` int(11) NOT NULL ,
`name` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
创建maven项目后,在pom.xml中导入相关依赖:
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.1version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.9version>
dependency>
dependencies>
在pom.xml中引入以下代码,否则没办法读取到Mapper映射文件:
<build>
<resources>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>falsefiltering>
resource>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>falsefiltering>
resource>
resources>
build>
创建包com.xu.pojo,在包中创建Student类:
package com.xu.pojo;
//推荐类名与数据库中的表名一致
public class Student {
//定义属性,目前要求:属性名和列名一致
private Integer id;
private String name;
private String email;
private Integer age;
//无参构造、有参构造、get、set、toString此处已省略
创建com.xu.dao包,在包中创建StudentDao接口:
package com.xu.dao;
import com.xu.pojo.Student;
import java.util.List;
//接口操作student表
public interface StudentDao {
//查询student表所有数据,表中每一行数据都能看做是一个student对象
List<Student> selectStudents();
}
<mapper namespace="com.xu.dao.StudentDao">
<select id="selectStudents" resultType="com.xu.pojo.Student">
select id,name,email,age from student order by id;
select>
mapper>
在resources目录下创建主配置文件:名为 mybatis-config.xml
说明:主配置文件名称是自定义的,内容如下:
<configuration>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"/>
<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="root"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/xu/dao/StudentDao.xml"/>
mappers>
configuration>
上述代码中mapper标签的注释图解,根据路径信息就可以找到并执行映射文件中的sql语句对数据库进行操作:
在test.java包下创建测试类MybatisTest:
import com.xu.dao.StudentDao;
import com.xu.pojo.Student;
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 java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class MybatisTest {
public static void main(String[] args) throws IOException {
//1.定义mybatis核心配置文件名,从类路径的根开始(target/classes)
String config = "mybatis-config.xml";
//2.读取mybatis核心配置文件
InputStream is = Resources.getResourceAsStream(config);
//3.创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//4.创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(is);
//5.【重要】获取SqlSession对象
SqlSession sqlSession = factory.openSession();
//6.获取StudentDao接口的代理对象
StudentDao mapper = sqlSession.getMapper(StudentDao.class);
//7.执行接口代理对象中的方法
List<Student> students = mapper.selectStudents();
//8.输出结果
for (Student student : students) {
System.out.println(student);
}
//9.关闭SqlSession对象
sqlSession.close();
}
}
在mybatis-config.xml核心配置文件中加入日志配置,可以在控制台输出执行的 sql 语句和参数:
<settings>
<setting name="logImpl" value="STDOUT_LOGGING" />
settings>
//添加学生操作,返回值int表示执行insert操作后,影响数据库的行数
//DML语句返回值都是int类型
int insertStudent(Student student);
<insert id="insertStudent">
insert into student values(#{id},#{name},#{email},#{age});
insert>
@Test
public void testInsert() throws IOException {
//1.定义mybatis核心配置文件名,从类路径的根开始(target/classes)
String config = "mybatis-config.xml";
//2.读取mybatis核心配置文件
InputStream is = Resources.getResourceAsStream(config);
//3.创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//4.创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(is);
//5.【重要】获取SqlSession对象
SqlSession sqlSession = factory.openSession();
//6.获取StudentDao接口的代理对象
StudentDao mapper = sqlSession.getMapper(StudentDao.class);
//7.执行接口代理对象中的方法
Student student = new Student(1003,"张飞","[email protected]",20);
int nums = mapper.insertStudent(student);
//8.【重要】mybatis默认不会自动提交事务,所以DML语句执行后需要手动提交事务
sqlSession.commit();
//9.输出insert语句影响数据的行数
System.out.println(nums);
//10.关闭SqlSession对象
sqlSession.close();
}
这里我只展示insert操作,其他的delete、update操作我就不进行演示了,因为这些DML操作都是同理的,为了使该技术博客不那么冗余,这里就不做那么多重复演示了!
Resources 类,顾名思义就是资源,用于读取资源文件。其有很多方法通过加载并解析资源文件,返回不同类型的 IO 流对象。
//定义mybatis核心配置文件名,从类路径的根开始(target/classes)
String config = "mybatis-config.xml";
//读取mybatis核心配置文件
InputStream is = Resources.getResourceAsStream(config);
SqlSessionFactory 的创建 , 需要使用 SqlSessionFactoryBuilder 对象的build() 方 法 。 由于SqlSessionFactoryBuilder 对象在创建完工厂对象后,就完成了其历史使命,即可被销毁。所以,一般会将该 SqlSessionFactoryBuilder 对象创建为一个方法内的局部对象,方法结束,对象销毁。
//创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(is);
SqlSessionFactory 接口对象是一个重量级对象(系统开销大的对象),是线程安全的,所以一个应用只需要一个该对象即可。创建 SqlSession 需要使用 SqlSessionFactory 接口的 openSession() 方法。SqlSessionFactory是一个接口,其实现类为DefaultSqlSessionFactory,SqlSessionFactory作用: 获取SqlSession对象
➢ openSession(true):创建一个有自动提交功能的 SqlSession
➢ openSession(false):创建一个非自动提交功能的 SqlSession,需手动提交
➢ openSession():同 openSession(false)
//创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(is);
//获取SqlSession对象
SqlSession sqlSession = factory.openSession();
SqlSession 接口对象用于执行持久化操作。一个 SqlSession 对应着一次数据库会话,一次会话以SqlSession 对象的创建开始,以 SqlSession 对象的关闭结束。
SqlSession 接口对象是线程不安全的,所以每次数据库会话结束前,需要马上调用其 close()方法,将其关闭。再次需要会话,再次创建。 SqlSession 在方法内部创建,使用完毕后关闭。
SqlSession接口定义了操作数据的方法,例如 selectOne()、selectList()、insert()、update()、delete()、commit()、rollback(),SqlSession接口的实现类DefaultSqlSession。
使用要求:SqlSession对象是线程不安全的,需要在方法内部使用,在执行sql语句之前,使用openSession()获取SqlSession对象。在执行完sql语句后,需要关闭它,执行close(),这样能保证它的使用是线程安全的。
//关闭SqlSession对象
sqlSession.close();
在com.xu.util包下创建MybatisUtil类:
package com.xu.util;
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 java.io.IOException;
import java.io.InputStream;
public class MybatisUtil {
private static SqlSessionFactory factory = null;
static {
try {
String config = "mybatis-config.xml";
InputStream is = Resources.getResourceAsStream(config);
factory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
e.printStackTrace();
}
}
//获取sqlSession的方法
public static SqlSession getSqlSession() {
SqlSession sqlSession = null;
if (factory != null) {
sqlSession = factory.openSession(); //非自动提交事务
}
return sqlSession;
}
}
@Test
public void testInsert() throws IOException {
//获取SqlSession对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
//获取StudentDao接口的代理对象
StudentDao mapper = sqlSession.getMapper(StudentDao.class);
//执行接口代理对象中的方法
List<Student> students = mapper.selectStudents();
//输出结果
for (Student student : students) {
System.out.println(student);
}
//关闭SqlSession对象
sqlSession.close();
}
MyBatis 框架抛开了 Dao 的实现类,直接定位到映射文件 mapper 中的相应 SQL 语句,对DB 进行操作。这种对 Dao 的实现方式称为 Mapper 的动态代理方式。
Mapper 动态代理方式无需程序员实现 Dao 接口。接口是由 MyBatis 结合映射文件自动生成的动态代理实现的。真正对数据库进行操作的工作其实是由框架通过 mapper 中的 SQL 完成的。
只需调用 SqlSession 的 getMapper()方法,即可获取指定接口的实现类对象。该方法的参数为指定接口实现类的 class 值。
@Test
public void testSelectStudents() {
/**
* 使用mybatis动态代理机制,使用sqlSession.getMapper(dao接口.class)
* getMapper能获取dao接口对应的实现类对象
*/
//1.获取SqlSession
SqlSession sqlSession = MybatisUtil.getSqlSession();
//2.调用getMapper()获取到StudentDao接口的实现类对象
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//3.调用接口实现类的方法,执行对数据库的操作
List<Student> students = dao.selectStudents();
//4.遍历输出结果
for (Student student : students) {
System.out.println(student);
}
//5.关闭SqlSession对象
sqlSession.close();
}
parameterType: 接口中方法参数的类型, 类型的完全限定名或别名。这个属性是可选的,因为 MyBatis 可以推断出具体传入语句的参数,默认值为未设置(unset)。接口中方法的参数从 java 代码传入到 mapper 文件的 sql 语句。
mybatis通过反射机制能够得知接口参数的类型,所以一般情况下,我习惯不写parameterType
Dao 接口中方法的参数只有一个简单类型(java 基本类型或 String类型),占位符 #{ 任意字符 },和方法的参数名无关。
接口方法:
Student selectById(int id);
mapper映射文件:
<select id="selectById" resultType="com.xu.pojo.Student">
select id,name,email,age from student where id = #{studentId}
select>
当 Dao 接口方法多个参数,需要通过名称使用参数。在方法形参前面加入@Param(“自定义参数名”),mapper 文件使用#{自定义参数名}。
接口方法:
List<Student> selectMultiParam(@Param("personName") String name,
@Param("personAge") int age);
mapper映射文件:
<select id="selectMultiParam" resultType="com.xu.pojo.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 }
创建保存参数值的对象:
public class QueryParam {
private String queryName;
private int queryAge;
//set ,get 方法
}
接口方法:
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>
#:占位符,告诉 mybatis 使用实际的参数值代替。并使用 PrepareStatement 对象执行 sql 语句, #{…}代替 sql 语句的 “?”。这样做更安全,更迅速,#通常是首选做法。
转化为 JDBC 的执行是:
String sql = "select id,name,email,age from student where id = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1,1005);
解释:
where id = ? 就是 where id = #{studentId}
ps.setInt(1,1005) , 1005 会替换掉 #{studentId}
$ :字符串替换,告诉 mybatis 使用$包含的“字符串”替换所在位置。使用 Statement 把 sql 语句和 ${}的内容连接起来。主要用在替换表名,列名,不同列排序等操作。
#和$区别:
resultType: 执行 sql 得到 ResultSet 转换的类型,使用类型的完全限定名或别名。 注意如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。resultType 和 resultMap,不能同时使用。
总而言之,resultType就是sql语句的执行结果转为java类型的对象!
接口方法:
int countStudent();
mapper映射文件:
<select id="countStudent" resultType="int">
select * from student;
select>
接口方法:
Student selectById(int id);
mapper映射文件:
<select id="selectById" resultType="com.xu.pojo.Student">
select id,name,email,age from student where id=#{studentId}
select>
框架的处理: 使用构造方法创建对象。调用 setXXX 给属性赋值。
Student student = new Student();
注意:Dao 接口方法返回是集合类型,需要指定集合中的类型,不是集合本身
sql 的查询结果作为 Map 的 key 和 value。推荐使用 Map
接口方法:
Map<Object,Object> selectReturnMap(int id);
mapper映射文件:
<select id="selectReturnMap" resultType="java.util.HashMap">
select name,email from student where id = #{studentId}
select>
resultMap 可以自定义 sql 的结果和 java 对象属性的映射关系。更灵活的把列值赋值给指定属性。常用在列名和 java 对象属性名不一样的情况。
使用方式:
接口方法:
List<Student> selectAllStudents();
mapper映射文件:
<resultMap id="studentMap" type="com.xu.pojo.Student">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="email" property="email"/>
<result column="age" property="age"/>
resultMap>
<select id="selectAllStudents" resultMap="studentMap">
select id,name,email,age from student;
select>
public class PrimaryStudent {
private Integer stuId;
private String stuName;
private Integer stuAge;
// set , get 方法
}
<select id="selectUseFieldAlias" resultType="com.xu.pojo.PrimaryStudent">
select id as stuId, name as stuName,age as stuAge from student;
select>
mapper文件:
<resultMap id="primaryStudentMap" type="com.xu.pojo.PrimaryStudent">
<id column="id" property="stuId" />
<result column="name" property="stuName"/>
<result column="age" property="stuAge" />
resultMap>
<select id="selectUseDiffResultMap" resultMap="primaryStudentMap">
select id,name,email,age from student;
select>
模糊查询的实现有两种方式:
例1:java 代码中提供要查询的 “%力%”
接口方法:
List<Student> selectLikeFirst(String name);
mapper文件:
<select id="selectLikeFirst" resultType="com.xu.pojo.Student">
select id,name,email,age from student where name like #{studentName}
select>
测试方法:
@Test
public void testSelectLikeOne(){
String name="%力%";
List<Student> stuList = studentDao.selectLikeFirst(name);
}
例2:mapper 文件中使用 like name “%” #{xxx} “%”
接口方法:
List<Student> selectLikeSecond(String name);
mapper文件:
<select id="selectLikeSecond" resultType="com.xu.pojo.Student">
select id,name,email,age from student where name like "%" #{studentName} "%"
select>
测试方法:
@Test
public void testSelectLikeSecond(){
String name="力";
List<Student> stuList = studentDao.selectLikeSecond(name);
}
动态 SQL,通过 MyBatis 提供的各种标签对条件作出判断以实现动态拼接 SQL 语句。这里的条件判断使用的表达式为 OGNL 表达式。常用的动态 SQL 标签有 if、where、choose、foreach 等。
MyBatis 的动态 SQL 语句,与 JSTL 中的语句非常相似。
动态 SQL,主要用于解决查询条件不确定的情况:在程序运行期间,根据用户提交的查询条件进行查询。提交的查询条件不同,执行的 SQL 语句不同。若将每种可能的情况均逐一列出,对所有条件进行排列组合,将会出现大量的 SQL 语句。此时,可使用动态 SQL 来解决这样的问题
对于该标签的执行,当 test 的值为 true 时,会将其包含的 SQL 片断拼接到其所在的 SQL 语句中。
<if test=”条件”>
sql 语句内容
if>
接口方法:
//如果使用动态SQL,那么参数类型必须是java对象
List<Student> selectStudentIf(Student student);
mapper文件:
<select id="selectStudentIf" resultType="com.xu.pojo.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 > #{age}
if>
select>
if 标签的中存在一个比较麻烦的地方:需要在 where 后手工添加 1=1 的子句。因为,若 where 后的所有 if 条件均为 false,而 where 后若又没有 1=1 子句,则 SQL 中就会只剩下一个空的 where,SQL出错。所以,在 where 后,需要添加永为真子句 1=1,以防止这种情况的发生。但当数据量很大时,会严重影响查询效率。
使用 where 标签,在有查询条件时,可以自动添加上 where 子句;没有查询条件时,不会添加 where 子句。需要注意的是,第一个 if 标签中的 SQL 片断,可以不包含 and。不过,写上 and 也不错,系统会将多出的 and 去掉。但其它 if 中 SQL 片段的 and,必须要求写上。否则 SQL 语句将拼接出错。
<where>
其他动态 sql
where>
接口方法:
List<Student> selectStudentWhere(Student student);
mapper文件:
<select id="selectStudentWhere" resultType="com.xu.pojo.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 > #{age}
if>
where>
select>
foreach 标签用于实现对于数组与集合的遍历。进行使用,需要注意:
➢ collection 表示要遍历的集合类型:list,array 等。
➢ open、close、separator 对遍历内容的 SQL 拼接。
<foreach collection="集合类型" open="开始的字符" close="结束的字符" item="集合中的成员" separator="集合成员之间的分隔符">
#{item 的值}
foreach>
表达式中的 List 使用 list 表示,其大小使用 list.size 表示。
需求:查询学生 id 是 1002,1005,1006
接口方法:
List<Student> selectStudentForList(List<Integer> idList);
mapper文件:
<select id="selectStudentForList" resultType="com.xu.pojo.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>
测试方法:
@Test
public void testSelectForList() {
List<Integer> list = new ArrayList<>();
list.add(1002);
list.add(1005);
list.add(1006);
List<Student> studentList = studentDao.selectStudentForList(list);
}
接口方法:
List<Student> selectStudentForList2(List<Student> stuList);
mapper文件:
<select id="selectStudentForList2" resultType="com.xu.pojo.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>
测试方法:
@Test
public void testSelectForList2() {
List<Student> list = new ArrayList<>();
Student s1 = new Student();
s1.setId(1002);
list.add(s1);
s1 = new Student();
s1.setId(1005);
list.add(s1);
List<Student> studentList = studentDao.selectStudentForList2(list);
}
sql 标签用于定义 SQL 片断,以便其它 SQL 标签复用。而其它标签使用该 SQL 片断,需要使用 include 子标签。该 sql 标签可以定义 SQL 语句中的任何部分,所以 include 子标签可以放在动态 SQL的任何位置。
接口方法:
List<Student> selectStudentSqlFragment(List<Student> stuList);
mapper文件:
<sql id="studentSql">
select id,name,email,age from student
sql>
<select id="selectStudentSqlFragment" resultType="com.xu.pojo.Student">
<include refid="studentSql"/>
<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-config.xml 是核心配置文件。
核心配置文件特点:
Mybatis 中访问数据库,可以连接池技术,但它采用的是自己的连接池技术。在 Mybatis 的 mybatis-config.xml 配置文件中,通过 dataSource type=”pooled” 来实现 Mybatis 中连接池的配置。dataSource可以理解为就是Connection对象
UNPOOLED:不使用连接池的数据源
POOLED:使用连接池的数据源
JNDI:使用JNDI实现的数据源
其中 UNPOOLED ,POOLED 数据源实现了 javax.sq.DataSource 接口, JNDI 和前面两个实现方式不同,了解可以。
在 mybatis-config.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="root"/>
dataSource>
MyBatis 在初始化时,根据 dataSource 的 type 属性来创建相应类型的的数据源 DataSource,即:
type=”POOLED”:MyBatis 会创建 PooledDataSource 实例
type=”UNPOOLED”:MyBatis会创建 UnpooledDataSource 实例
type=”JNDI”:MyBatis 会从 JNDI 服务上查找 DataSource 实例,然后返回使用
Mybatis 框架是对 JDBC 的封装,所以 Mybatis 框架的事务控制方式,本身也是用 JDBC 的 Connection对象的 commit(), rollback()
Connection 对象的 setAutoCommit()方法来设置事务提交方式:自动提交和手工提交
<transactionManager type="JDBC"/>
该标签用于指定 MyBatis所使用的事务管理器。MyBatis 支持两种事务管理器类型:JDBC 与 MANAGED。
设置自动提交的方式,factory 的 openSession() 分为有参数和无参数的。
SqlSession openSession();
SqlSession openSession(boolean autoCommit);
有参数为 true,使用自动提交,可以修改 MyBatisUtil 的 getSqlSession()方法。
session = factory.openSession(true);
再执行 insert 操作,无需执行 session.commit(),事务是自动提交的
为了方便对数据库连接的管理,DB 连接四要素数据一般都是存放在一个专门的属性文件中的。MyBatis主配置文件需要从这个属性文件中读取这些数据。步骤如下:
在 resources 目录创建 jdbc.properties 文件,文件名称自定义。
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?charset=utf-8
jdbc.username=root
jdbc.password=root
修改主配置文件,文件开始位置加入:
<properties resource="jdbc.properties"/>
<dataSource type="POOLED">
<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>
Mybatis 支持默认别名,我们也可以采用自定义别名方式来开发,主要使用在 select resultType=”别名”
mybatis-config.xml 主配置文件定义别名:
<typeAliases>
<typeAlias type="com.xu.pojo.Student" alias="mystudent"/>
<package name="com.xu.pojo"/>
<package name="其他包"/>
typeAliases>
mapper.xml 文件,使用别名表示类型:
<select id="selectStudents" resultType="mystudent">
select id,name,email,age from student
select>
使用相对于类路径的资源,从 classpath 路径查找文件:
<mapper resource="com/xu/dao/StudentDao.xml" />
指定包下的所有 Dao 接口:
<package name="com.xu.dao"/>
注意:此种方法要求 Dao 接口名称和 mapper 映射文件名称相同,且在同一个目录中。
插件使用步骤如下:
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelperartifactId>
<version>5.1.10version>
dependency>
在 environments 之前加入
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor" />
plugins>
查询语句之前调用 PageHelper.startPage 静态方法。
除了 PageHelper.startPage 方法外,还提供了类似用法的 PageHelper.offsetPage 方法。
在你需要进行分页的 MyBatis 查询方法前调用 PageHelper.startPage 静态方法即可,紧跟在这个方法后的第一个 MyBatis 查询方法会被进行分页。
@Test
public void testSelect() throws IOException {
//获取第 1 页,3 条内容
PageHelper.startPage(1,3);
List<Student> studentList = studentDao.selectStudents();
studentList.forEach( stu -> System.out.println(stu));
}