??作者:Java学术趴
?公众号:Java学术趴
?特别声明:原创不易,未经授权不得转载或抄袭,如需转载可联系小编授权。
?版权声明:文章里的部分文字或者图片来自于互联网以及百度百科,如有侵权请尽快联系小编。微信搜索公众号Java学术趴联系小编。
☠️每日毒鸡汤:努力奔跑吧,反正没有一片属于你的风景
?大家好!我是你们的老朋友Java学术趴,今天继续给大家分享小趴经过一个星期整理出来的MaBatis框架核心知识。其中包含框架介绍、入门案例、常用接口、动态代理以及MyBatis的深入理解。MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。以下就为大家详细介绍MyBatis框架。如果大家喜欢的话,点赞支持支持小趴,这是对小趴最大的认可,文章有点长,希望大家认真阅读,一定会对你有帮助的,感谢阅读。
三层架构包括:
三层的职责:
三层对应的包:
三层的处理请求的交互:
为什么要使用三层:
重点 :因为每一层都对应一个处理框架
三层对应的处理框架:
框架的定义:
框架解决的问题:
框架的特点:
常用的J2EE开发框架:
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 框架。
- _sql mapper_ : _sql映射_ 可以把数据库表中的一行数据 映射为 一个java对象。一行数据可以看做是一个java对象。操作这个对象,就相当于操作表中的数据。
- _Data Access Objects(DAOs)_ : 数据访问 , 对数据库执行增删改查。
// 这是以前使用JDBC时获取到的数据库查询结果,此时需要使用循环来获取到查询的结果,并将这个结果写入到一个List集合中,很麻烦。
// 此时使用MyBatis框架,他会把这些sql语句当做是一个个的对象,在底层对自动帮我们完成这个循环,我们获取到的是一个装满sql对象的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);
}
开发人员提供sql语句--->MyBatis处理sql--->开发人员得到List集合或者java对象(表中的数据)
openSession()方法的几种形式:
➢ openSession(true):创建一个有自动提交功能的 SqlSession 。
➢ openSession(false):创建一个非自动提交功能的 SqlSession,需手动提交 。
➢ openSession():无参数,获取的是非自动提交事务的SqlSession对象。
使用要求:
<?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 : 里边填写接口路径,这个类在项目中是唯一的,可以保证namespace值唯一-->
<mapper namespace="com.yunbocheng.dao.StudentDao">
<!--
mybatis的配置文件:注意,一般是一个表文件一个这种配置文件。
这个sql映射文件是写 sql语句的,mybatis会执行这些sql。
对于这个sql映射文件的解释:
1.指定约束文件
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
mybatis-3-mapper.dtd : 是约束文件的名称,扩展名是dtd的。
2. 约束文件的作用
限制、检查在当前文件中出现的标签,属性必须符合mybatis的要求。
3.mapper(sql mapper 这个mapper就是映射的意思):是当前文件的根标签。必须的,不可以改变。
namespace :叫做命名空间,这个空间是一个唯一值。可以是自定义的字符串
要求使用dao接口的【全限定名称】。定位的这个接口,而不是这个xml配置文件
【全限定名称】 = 包名 + 接口名(类名)
<mapper namespace="com.yunbocheng.dao.StudentDao">
4. 在当前文件中,可以使用特定的标签,表示数据库的特定操作。
<select> : 表示执行查询,执行的是select语句。
<update> : 表示更新数据库的操作,就是在<update>标签中写的是update sql语句
<insert> : 表示插入,放的是insert语句
<delete> : 表示删除,执行的delete语句
5. 编写sql语句
<select id="selectstudents" resultType="Student">
/* 此时会将以下的数值依此赋值给Student对象 */
select id,name,email,age from student order by id;
</select>
id : 代表执行的sql语句的唯一标识,mybatis会使用这个id的值来找到要
执行的sql语句。这个id值可以自定义。但是要求使用接口中的方法名称。
就相当于使用这个id值来代表这条sql语句。
resultType : 代表结果的类型,是sql语句执行后得到的ResultSet,
遍历这个ResultSet得到Java对象的类型。
这个值写类型的全限定名称。
也就是把查询到的数据传递给com.yunbocheng.entity.Student类
此时MyBatis会自动创建出的一个student对象。并给属性赋值。
MyBatis会把从数据库中的id值赋给Student类中id的属性。
MyBatis会把从数据库中的name值赋给Student类中name的属性。
MyBatis会把从数据库中的email值赋给Student类中email的属性。
MyBatis会把从数据库中的age值赋给Student类中age的属性。
返回的这个类型和接口中方法的返回类型一致,都是一个student对象的集合。
以上就是一个标准的 mybatis配置文件。
以上 parameterType 使用的是 Java数据类型的全限定名称。
以上省略了parameterType ,使用的是 parameterType的默认值。默认值为未设置(unset)
以上 parameterType 使用的是mybatis定义的别名 。
这个时候mybatis会自动将1005这个值传递给 mapper文件中的占位符 id=#{id}。
1. mybatis**创建Connection , PreparedStatement 对象**// 以下这些代码都是在mapper文件中的操作,是MyBatis帮我们操作的。 String sql = "select id,name,email,age from student where id= ?"; PreparedStatement pst = conn.PreparedStatement(sql); pst.setInt(1,1001);
2. 执行sql封装为 resultType = "com.yunbocheng.domain.Student" 这个对象。
ResultSet rs = ps.executeQuery(); Student student = null; while(rs.next()){ // 从数据库取出id=1001的这一行数据,存储到一个java对象属性中。 // 注意 :在Student类中必须有每个属性的set/get,以及创建对象时的无参构造。 student = new Student(); student.setId(rs.getInt("id")); student.setName(rs.getString("name")); student.setEmail(rs.getString("email")); student.setAge(rs.getInt("age")); // 也可以将这些数据写在一个student类的有参构造的方法中。 // 此时查询的是id=1001这个对象,而不是一多个student,此时不用放在一个集合中。 } return student; // 把mapper文件中查询到的这个student赋给了dao方法调用的返回值。也就是以下这段代码 // 以下这段代码是测试类代码 Student student = dao.selectStudentById(1001); System.out.println("student = " + student);
第二步 : 创建传递多个参数的查询语句。
注意 :必须保证接口中的自定义参数名 与 mapper文件中的自定义参数名一致
第三步 : 使用测试类传递参数,将参数传递给 mapper文件返回最后的结果。
以上查询的是 : 名字是程云博以及年龄是50的student数据。
注意 :在这个类中要声明属性值,以及无参构造,以及set/get方法。
第二步 : 在dao接口中创建一个参数为以上QueryParma类的对象的抽象方法。
注意 :这个返回值是一个Student对象集合,而不是QueryParma对象集合。
注意 :这个并不一定非要创建出另外一个类,使用现有的Student类完全没问题。只不过是其中的属性值的数量不同
第三步 : 在mapper文件中,创建使用该抽象方法查询数据库的SQL语句。
javaType对应的就是 :这个数据类型的 全限定名称 java.lang.String。
jdbcType对应的就是 :由mybatis提供的(见下表)
注意 :这个语句有原始语句与简写语句之分。
原始语句 :
简化语句 :
注意 :mapper文件中的定位符#{自定义名称},必须和QueryParma(传递参数的类)类中属性值的名称一致
第四步 :使用测试类来创建传递参数的QueryParma对象,输出查询结果
以上查询出的是名称为程云博和年龄为50的数据。
第一步:在接口中创建抽象方法
注意 :抽象方法中的参数从左到右进行编号,比如下边的这个参数,name位置是0,age是1。
第二步 :在mapper文件中创建SQL语句
**注意 :在mybatis3.4之后开始使用 #{arg0}的语法格式,我们这里使用的是3.5.7版本。
注意 :#{arg0}对应的是name,如果将name对应的#{arg0}改为#{arg1},此时会将age的值传递给name,此时会赋值反。结果会变为 name = 20 age = 程云博。
第三步 :在测试类中显示查询结果
此时查询到的就是name是程云博或者年龄是20岁的信息。
第一步 :在接口中创建抽象方法,使用的是Map集合,返回值是Student对象集合。
第二步 :在mapper文件中创建SQL语句 语法格式 :#{map的key值}
注意 :这个key值必须和测试类中创建的Map中的key值一致。
第三步 :在测试类中显示查询结果
注意 : 在我们日常的开发中,不建议参数是Map集合,因为什么信息也表达不出来,可读性差,不建议使用。
此时需要使用*" '李四' "*这种格式,才能保证拼接完的字符是以下格式(正确的SQL格式)
将两个语句放在一起比较
<!--使用 #占位符的结果-->
<!--这个原理是 :将#{studentId}代表的值替换掉SQL语句中的 ? 占位符-->
<!--替换-->
select id,name, email,age from student where id=#{studentId}
# 的结果: select id,name, email,age from student where id=?
<!--使用 $字符串拼接的结果-->
<!--这个原理是 :将${studentId}代表的值拼接到SQL语句最后的 id = 的后边-->
<!--拼接-->
select id,name, email,age from student where id=${studentId}
$ 的结果:select id,name, email,age from student where id=1001
resultType处理方式:
<!--mapper文件中的语句,Mybatis动态代理-->
<select id="selectMultiPosition" resultType="com.bjpowernode.domain.Student">
select id,name, email,age from student
</select>
<!--以上MyBatis动态代理对等的jdbc代码-->
ResultSet rs = executeQuery(" select id,name, email,age from student" )
while(rs.next()){
Student student = new Student();
student.setId(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setEmail(rs.getString("email"));
student.setAge(rs.getInt("age"));
}
第一步 :定义接口中的方法
int countStudent();
第二步 :mapper 文件:
注意:返回值类型可以是全限定名称也可以是别名。
<!--此时 resultType 的返回值是一个int类型,代表查询到的结果数-->
<select id="countStudent" resultType="int">
select count(*) from student
</select>
第三步 :测试方法
@Test
public void testRetunInt(){
int count = studentDao.countStudent();
System.out.println("学生总人数:"+ count);
}
第一步 :接口中的抽象方法
Student selectById(int id);
第二步 :mapper文件
<!--此时返回的结果是一个Student对象-->
<select id="selectById" resultType="com.bjpowernode.domain.Student">
select id,name,email,age from student where id=#{studentId}
</select>
这个是时候会使用框架处理 :使用构造方法创建对象。调用 setXXX 给属性赋值。
第三步 :测试程序
@Test
public void testSelectStudent(){
StudentDao studentDao = new StudentDaoImpl();
List<Student> students = studentDao.testSelect();
for (Student student : students) {
System.out.println(student);
}
}
第一步 :接口定义抽象方法返回Map
Map<Object,Object> selectReturnMap(int id);
第二步 :mapper文件 (返回值map的全限定名称是 java.util.HashMap或者是别名map)
<!--此时返回值是一个Map集合,且这个集合中只能有一条记录。推荐使用Map<Object,Object>-->
<select id="selectReturnMap" resultType="java.util.HashMap">
select id,name from student where id = #{studentId}
</select>
第三步 :测试方法(返回的结果是:列名是map的key,列值是map的value)。
@Test
public void testReturnMap(){
Map<Object,Object> retMap = studentDao.selectReturnMap(1002);
System.out.println("查询结果是 Map:"+retMap);
}
注意 :上边SQL语句获取的是id,name的字段值。所以传递到Map集合中的是<id,name>。
返回的结果是 :查询的结果是 Map : {name=李四, id=1001}。 查询的结果是:{列名=列值,列名=列值}的格式。
以上查询到的是两个key,如果是多个key,其map就是多增加列名和列值。
注意 :使用map只能返回一行数据,返回大一一行的数据会报错,是错误的。
1. 你自定义列值赋值给哪个属性。
2. 当你的列名和属性名不一样时,一定使用resultMap。这个返回值类型主要解决列名和属性名不一样的问题。
第一步 :创建一个接口的抽象方法
/**
* 使用resultMap定义映射关系
*/
List<Student> selectAllStudents();
第二步 :mapper文件
<!--使用resultMap
1. 先定义一个resultMap
2. 在select标签中,使用resultMap来调用已定义的resultMap。
-->
<!--定义resultMap
id : 自定义名称,表示定义的这个resultMap
type : java类型的全限定名称。相当于以前select的resultType。
-->
<resultMap id="studentMap" type="com.yunbocheng.entity.Student">
<!--数据库中的列名和java属性的关系-->
<!--主键列,使用id标签
column : 数据库中的列名
property : java类型的属性名
-->
<id column="id" property="id"/>
<!--非主键列,使用result标签-->
<result column="name" property="name"/>
<result column="email" property="email"/>
<result column="age" property="age"/>
</resultMap>
<!--此时这个 resultMap的值就是这个id值studentMap-->
<select id="selectAllStudents" resultMap="studentMap">
select id,name,email,age from student;
</select>
第三步 :测试类 (返回值是一个List集合)
@Test
public void testSelectAllStudents(){
// 使用工具类获取到SqlSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
// 使用mybatis动态代理模式获取到dao的实现类对象
StudentDao dao = sqlSession.getMapper(StudentDao.class);
// 使用dao的是实现类对象来调用其中的抽象方法。
List<Student> students = dao.selectAllStudents();
for (Student student : students) {
System.out.println(student);
}
}
注意 :resultMap和resultType不要一起用,二选一。
使用方式
package com.yunbocheng.entity;
public class PrimaryStudent {
private Integer stuId;
private String stuName;
private Integer stuAge;
// 省略了 set , get 以及toString方法
List<PrimaryStudent> selectUseFieldAlias(QueryParam param);
<select id="selectUseFieldAlias"
resultType="com.yunbocheng.entity.PrimaryStudent">
select id as stuId, name as stuName,age as stuAge
from student where name=#{queryName} or age=#{queryAge}
</select>
@Test
public void testSelectUseFieldAlias(){
QueryParam param = new QueryParam();
param.setQueryName("程云博");
param.setQueryAge(20);
List<PrimaryStudent> stuList;
stuList = studentDao.selectUseFieldAlias(param);
stuList.forEach( stu -> System.out.println(stu));
}
使用方式
List<PrimaryStudent> selectUseDiffResultMap(QueryParam param);
<!-- 创建 resultMap
id:自定义的唯一名称,在<select>使用
type:期望转为的 java 对象的全限定名称或别名
-->
<resultMap id="primaryStudentMap"
type="com.yunbocheng.entity.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>
@Test
public void testSelectUseDiffResultMap(){
QueryParam param = new QueryParam();
param.setQueryName("程云博");
param.setQueryAge(20);
List<PrimaryStudent> stuList;
stuList = studentDao.selectUseDiffResultMap(param);
stuList.forEach( stu -> System.out.println(stu));
}
实现方式
/**
* 第一种模糊查询
* 在Java代码指定 like 的内容。
*/
public List<Student> selectLikeOne(String name);
<!--第一种like,java代码指定 like内容-->
<select id="selectLikeOne" resultType="com.yunbocheng.entity.Student">
select id,name,email,age from student where name like #{name};
</select>
@Test
public void selectSelectLikeOne(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
// 准备好like的内容,使用dao接口的实现类对象调用方法
String name = "%程%";
List<Student> students = dao.selectLikeOne(name);
for (Student student : students) {
System.out.println("查询到的学生 :" + student);
}
}
查询到的结果 :
实现方式
/**
* 第二种模糊like查询的方法
* name就是 程 这个值,在mapper文件中拼接 like %程%
*/
List<Student> selectLikeTwo(String name);
<!--第二种方式 :在mapper文件中拼接like内容 %程%-->
<!--如果要求查询的第一个字符是程,那么就不写第一个 "%"-->
<!--注意 :这个"%"与#{name}之间的空格必须存在-->
<!--这个name为查询的值,比如 程,这样拼接之后就是 %程%-->
<select id="selectLikeOne" resultType="com.yunbocheng.entity.Student">
select id,name,email,age from student where name like "%" #{name} "%";
</select>
@Test
public void selectSelectLikeTwo(){
SqlSession sqlSession = MyBatisUtils1.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
// 准备好like的内容,使用dao接口的实现类对象调用方法
String name = "李";
List<Student> students = dao.selectLikeOne(name);
for (Student student : students) {
System.out.println("查询到的学生 :" + student);
}
}
- **if 标签**
- **where 标签**
- **foreach 标签**动态 SQL,通过 MyBatis 提供的各种标签对条件作出判断以实现动态拼接 SQL 语句。这里的条件判 断使用的表达式为 OGNL 表达式。常用的动态 SQL 标签有、、、等。 MyBatis 的动态 SQL 语句,与 JSTL 中的语句非常相似。 动态 SQL,主要用于解决查询条件不确定的情况:在程序运行期间,根据用户提交的查询条件进行 查询。提交的查询条件不同,执行的 SQL 语句不同。若将每种可能的情况均逐一列出,对所有条件进行 排列组合,将会出现大量的 SQL 语句。此时,可使用动态 SQL 来解决这样的问题在 mapper 的动态 SQL 中若出现大于号(>)、小于号(<)、大于等于号(>=),小于等于号(<=)等 符号,最好将其转换为实体符号。否则,XML 可能会出现解析出错问题。特别是对于小于号(<),在 XML 中是绝不能出现的。否则解析 mapper 文件会出错。
<if test="判断java对象的属性值">
部分sql语句
</if>
对于该标签的执行,当 test 的值为 true 时,会将其包含的 SQL 片断拼接到其所在的 SQL 语句中。 语法: sql 语句的部分
实现方式
/*
测试动态sql中的 if 标签
动态sql要使用java对象作为参数
*/
List<Student> selectStudentIf(Student student);
<!--if标签
<if : test="使用接口中参数Java对象的属性值作为i判断条件">
语法格式 :属性=xxx值 (当然也可以是 属性!=xxx值)
-->
<select id="selectStudentIf" resultType="com.yunbocheng.entity.Student">
select id,name,email,age from student
where id > 0
<if test="name != null and name != '' ">
name = #{name}
</if>
<if test="age > 0">
and age > #{age};
</if>
</select>
以上语句拼接出的SQL语句是:
select id,name,email,age from student where name = ? and age > ?; //?占位符
// 测试if标签
@Test
public void testSelectStudentIf(){
SqlSession sqlSession = MyBatisUtils1.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
student.setName("");
student.setAge(10);
List<Student> students = dao.selectStudentIf(student);
for (Student student1 : students) {
System.out.println("if===" + student1);
}
}
实现方式:
/**
* 测试动态sql中的 where 标签
* 动态sql要使用java对象作为参数
*/
List<Student> selectStudentWhere(Student student);
即使我们传递的名字是一个空的,这个时候也会拼接出正确的SQL,不会报错
<select id="selectStudentWhere" resultType="com.yunbocheng.entity.Student">
select id,name,email,age from student
<where>
<if test="name != null and name != '' ">
name = #{name}
</if>
<if test="age > 0">
and age > #{age};
</if>
</where>
</select>
// 测试where标签
@Test
public void testSelectStudentWhere() {
SqlSession sqlSession = MyBatis.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
student.setName("");
student.setAge(100);
List<Student> students = dao.selectStudentWhere(student);
for (Student student1 : students) {
System.out.println(student1);
}
}
select * from student where id in (1001,1002,1003);
<foreach collection="集合类型" open="开始的字符" close="结束的字符"
item="集合中的成员" separator="集合成员之间的分隔符">
#{item 的值}
</foreach>
参数解释:
实现方式需求:查询学生 id 是 1002,1005,1006
List<Student> selectStudentForeach(List<Integer> stulist);
<!--
测试foreach标签 此时遍历的是一个简单类型
-->
<select id="selectStudentForeach" resultType="com.yunbocheng.entity.Student">
<!--此时item的值是一个属性,直接使用即可-->
select id,name,email,age from student where id in
<foreach collection="list" item="myid" open="(" close=")" separator=",">
#{myid}
</foreach>
</select>
<!--注意:这个collection中的liet与测试方法中的list没有关系。-->
// 测试foreach
@Test
public void testSelectForEachOne() {
SqlSession sqlSession = MyBatis.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List<Integer> list = new ArrayList<>();
list.add(1002);
list.add(1003);
list.add(1004);
List<Student> students = dao.selectStudentForeach(list);
for (Student student1 : students) {
System.out.println(student1);
}
}
List<Student> selectStudentForeachTwo(List<Student> stuList);
<!--
测试foreach遍历对象集合
-->
<select id="selectStudentForeachTwo" resultType="com.yunbocheng.entity.Student">
select id,name,email,age from student where id in
<!--此时stu是一个Student对象集合 这个stu与测试方法中的studentList没有关系-->
<foreach collection="list" item="stu" open="(" close=")" separator=",">
<!--这个语法格式是 :对象.属性值 获取的是id属性的值,如果是 #{stu.name}此时获取的name属性-->
#{stu.id}
</foreach>
</select>
// 测试foreach遍历对对象集合
@Test
public void testSelectForEachTwo() {
SqlSession sqlSession = MyBatis.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//定义一个Student对象集合
List<Student> studentList = new ArrayList<>();
// 创建第一个Student对象
Student student1 = new Student();
// 给id属性赋值
student1.setId(1002);
// 将这个对象加入到Student对象集合中
studentList.add(student1);
// 创建第二个Student对象
Student student2 = new Student();
student2.setId(1003);
studentList.add(student2);
// 此时对象集合中有两个对象(student1 student2)
List<Student> studentList1 = dao.selectStudentForeachTwo(studentList);
for (Student student : studentList1) {
System.out.println(student);
}
}
<select id="selectStudentForeachTwo" resultType="com.yunbocheng.entity.Student">
select id,name,email,age from student where id in (
<!--此时stu是一个Student对象集合 这个stu与测试方法中的studentList没有关系-->
<foreach collection="list" item="stu" separator=",">
<!--这个语法格式是 :对象.属性值 获取的是id属性的值,如果是 #{stu.name}此时获取的name属性-->
#{stu.id}
</foreach>
)
</select>
使用方式
实现方式
<!--这个定义一个 if标签 方法-->
List<Student> selectStudentIf(Student student);
<!--这个定义一个 where标签 方法-->
List<Student> selectStudentWhere(Student student);
<!--定义sql片段,给以下这段代码定义为动态片段,定义一个别名,以后代码可以重复利用-->
<sql id="studentSql">
</sql>
<!--以下代码是使用 if标签 查询数据的SQL语句-->
<select id="selectStudentIf" resultType="com.yunbocheng.entity.Student">
<include refid="studentSql"/>
where id>0 and
<if test="name != null and name != '' ">
name = #{name}
</if>
<if test="age > 0">
and age > #{age};
</if>
</select>
<!--以下代码是使用 where标签 查询数据的SQL语句-->
<select id="selectStudentWhere" resultType="com.yunbocheng.entity.Student">
<include refid="studentSql"/>
<where>
<if test="name != null and name != '' ">
name = #{name}
</if>
<if test="age > 0">
and age > #{age};
</if>
</where>
</select>
// 测试sql-代码片段
@Test
public void testSelectStudentIf() {
SqlSession sqlSession = MyBatis.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
student.setName("程云博");
student.setAge(10);
List<Student> students = dao.selectStudentIf(student);
for (Student student1 : students) {
System.out.println("if===" + student1);
}
}
<!--定义一个只包含列名的代码片段-->
<sql id="studentOne">
id,name,email,age
</sql>
<!--使用动态代码片段创建SQL语句-->
<select id="selectStudentIf" resultType="com.yunbocheng.entity.Student">
select <include refid="studentOne"/> from student
where id>0 and
<if test="name != null and name != '' ">
name = #{name}
</if>
<if test="age > 0">
and age > #{age};
</if>
</select>
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">
1. 根元素,configuration
2. 主要包含内容: _定义别名_ _数据源_ _mapper 文件_
上图看出 Mybatis 将数据源分为三类:
其中 UNPOOLED ,POOLED 数据源实现了 javax.sq.DataSource 接口, JNDI 和前面两个实现方式不同,了解可以。
<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
<transactionManager type="JDBC"/>
session = factory.openSession(true);
使用方式
<typeAliases>
<!--
定义单个类型的别名
type:类型的全限定名称
alias:自定义别名
-->
<typeAlias type="com.yunbocheng.entity.Student" alias="mystudent"/>
<!--
批量定义别名,扫描整个包下的类,别名为类名(首字母大写或小写都可以)
name:包名
-->
<package name="com.yunbocheng.entity"/>
<package name="...其他包"/>
</typeAliases>
<select id="selectStudents" resultType="mystudent">
select id,name,email,age from student
</select>
<!--resource代表这个项目的一个mapper文件地址,这个地址从Java根路径开始-->
<mapper resource="com/yunbocheng/dao/StudentDao.xml" />
<!--name: xml文件(mapper文件)所在的包名,可以导入多个包名-->
<!--name:xml文件(mapper文件)所在的包名,这个包中的所有xml文件一次都能加载给mybatis-->
<package name="com.yunbocheng.entity"/>
<package name="com.yunbocheng.entity1"/>
<package name="com.yunbocheng.entity2"/>
可以搜索?微信公众号:Java学术趴,?发送MyBatis,免费给发给大家项目源码,代码是经过小编亲自测试?的,绝对可靠,免费拿去使用。
-------------------------------?看完的大佬们可以关注一下小编,会一直更新小技巧,免费分享给大家呦!!!?----------------------------
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。