Mybatis框架
Mybatis框架
1:三层框架
**界面层:**和用户打交道的,接收用户的请求参数,显示处理结果的。(jsp html servlet)
**业务逻辑层:**接收了界面层传递的数据,计算逻辑,调用数据库,获取数据。
**数据访问层:**就是访问数据库,执行对数据的查询,修改,删除等等。
三层对应的包:
界面层:controller包(servlet类)
业务逻辑层:service包(XXXservice类)
数据库访问层:dao包(XXXDao类)
三层中类的交互:
用户使用界面层–>业务逻辑层—>数据库访问层—>数据库(mysql)
三层对应的处理框架:
界面层(servlet类)—>springMVC(框架)
业务逻辑层(service类)—>spring(框架)
数据库访问层(dao类)—>myBatis(框架)
2:框架
框架介绍:
是一个舞台,模板。
框架是一个软件,半成品的软件,定义好了一些基础功能,需要加入你的功能就是完整的。基础功能是可以重复使用的,可升级的。
模板:
1:规定好了一些条款,内容。
2:加入自己的东西。
框架是一个模板
1:框架中定义好了一些功能,这些功能是可用的。
2:可以加入项目中自己的功能,这些功能可以利用框架中写好的功能。
框架的特点:
1:框架一般不是全能的,不能做所有的事情。
2:框架是针对某一个领域有效,特长在某一个方面,比如myBatis做数据库操作,但是它不能做其他的。
3:框架是一个软件。
3:使用JDBC的缺陷
1:代码比较多,开发效率低
2:需要关注Connection,Statement,ResultSet对象的创建和销毁
3:对ResultSet查询的结果,需要自己封装List集合。
4:重复的代码比较多。
5:业务代码和数据库操作混合在一起。
4:myBatis框架
一个框架,早期叫做ibatis,代码在gitHup
myBatis是 MyBatis SQL Mapper Framework for Java(sql映射框架)
1:sql Mapper:sql映射
可以把数据库表中的一行数据,映射为一个java对象。
一行数据可以看做是一个java对象,操作这个对象,就相当于操作表中的数据。
Data Access Object (DAOs):
数据访问,对数据库进行增删改查。
2:myBatis提供了那些功能?
1:提供了创建Connection,Statement,ResultSet的能力,不用开发人员创建这些对象了。
2:提供了执行sql语句的能力,不用你执行sql语句。
3:提供了循环sql,把sql的结果转换为java对象,List集合的能力。
4:提供了关闭资源的能力,不用你关闭Connection,Statement,ResultSet。
开发人员做的是:提供sql语句。
最后是:开发人员提供sql语句—>myBatis处理sql—>开发人员得到List集合或java对象(表中的数据)。
3:总结
myBatis是一个sql映射框架,提供操作数据库的能力,增强的JDBC。
使用myBatis让开发人员集中精神写sql就可以了,不必关心Connection,Statement,ResultSet的创建和销毁以及sql语句的执行。
5:myBatis使用步骤:
下载地址:https://github.com/mybatis/mybatis-3/releases
实现步骤:
1:新建student表。
2:加入maven的myBatis坐标,mysql驱动的坐标。
3:创建实体类,Student–保存表中的一行数据的。
4:创建持久层的dao接口,定义操作数据库的方法。
5:创建一个myBatis使用的配置文件,叫做sql映射文件:写sql语句的。一般一个表一个sql映射文件。
这个文件是xml文件。
1:在接口所在的目录中。
2:文件的名称,和接口保持一致。
6:创建myBatis的主配置文件:
一个项目就一个主配置文件。
主配置文件提供了数据库的连接信息和SQL映射文件的位置信息。
7:创建使用myBatis类:
通过myBatis访问数据库。
接口创建步骤:
/**
* 接口:操作student表
*/
public interface StudentDao {
//查询student表的所有数据
List<Student> stuSelect();
//插入数据方法
//参数:student,表示要插入到数据库的数据
//返回值:int,表示执行insert操作后,影响数据库的行数
int insertStudent(Student student);
}
sql映射文件解释:
<?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.sss.dao.StudentDao">
<!--
select:表示查询操作
id:你要执行的sql语句的唯一标识,myBatis会使用找个id的值来找到要执行的sql语句。
可以自定义,但是要求你使用接口中的方法名称。
resultType:表示结果类型的,是sql语句执行后得到ResultSet,遍历这个ResultSet得到java对象的类型。
值写的是类型的全限定名称
-->
<select id="stuSelect" resultType="com.sss.entity.Student">
select id,name,email,age from student order by id
</select>
<!--插入操作-->
<insert id="insertStudent">
insert into student values(#{id},#{name},#{email},#{age})
</insert>
</mapper>
<!--
sql映射文件:写sql语句的,myBatis会执行这些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 是当前文件的根标签,必须的。
namespace : 叫做命令空间,唯一值的,可以是自定义的字符串。
要求你使用dao接口的全限定名称。
4:在当前文件中,可以使用特定的标签,表示数据库的特定操作。
<select>:表示执行查询,select语句。
<update>:表示更新数据库的操作,就是在<update>标签中,写的是update sql语句。
<insert>:表示插入,放的是insert语句。
<delete>:表示删除,放的是delete语句。
-->
<select>:表示执行查询,select语句。
<update>:表示更新数据库的操作,就是在<update>标签中,写的是update sql语句。
<insert>:表示插入,放的是insert语句。
<delete>:表示删除,放的是delete语句。
–>
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:控制myBatis全局行为-->
<settings>
<!--设置myBatis输出日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--环境配置:数据库的连接信息
default:必须和某个environment的id值一样
告诉myBatis使用那个数据库的连接信息,也就是访问那个数据库。
-->
<environments default="development">
<!--environment:一个数据库信息的配置,环境
id:一个唯一值,自定义,表示环境的名称。
-->
<environment id="development">
<!--
transactionManager:myBatis的事务类型
type:JDBC(表示使用jdbc中的Connection对象的commit,rollback做事务处理。)
-->
<transactionManager type="JDBC"/>
<!--
dataSource:表示数据源,连接数据库的。
type:表示数据源的类型,POOLED表示使用连接池。
-->
<dataSource type="POOLED">
<!--
driver,url,username,password 是固定的,不能自定义。
-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--连接数据库的url字符串-->
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<!--访问数据库的用户名-->
<property name="username" value="root"/>
<!--访问数据库的密码-->
<property name="password" value="999"/>
</dataSource>
</environment>
</environments>
<!-- sql mapper(sql映射文件)的位置-->
<mappers>
<!--一个mapper标签指定一个文件的位置
从类路径开始的路径信息。target/clasess(类路径)
-->
<mapper resource="com/sss/dao/StudentDao.xml"/>
</mappers>
</configuration>
<!--
myBatis的主配置文件:主要定义了数据库的配置信息,和sql映射文件的位置。
1:约束文件:
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
约束文件的名称:mybatis-3-config.dtd
2:<configuration></configuration>:根标签
-->
<build>
<resources>
<resource>
<!--所在的目录-->
<directory>src/main/java</directory>
<includes><!--包括目录下的.properties,.xml文件都会被扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<!--filtering 选项 false 不启用过滤器,*.property 已经起到过滤的作用了-->
<filtering>false</filtering>
</resource>
</resources>
</build>
myBatis读取数据步骤案例:
//访问myBatis读取student数据。
//1:定义myBatis主配置文件的名称,从类路径的根开始(target/clasess)
String config = "myBatis.xml";
//2:读取这个config表示的文件。
InputStream in = Resources.**getResourceAsStream**(config);
//3:创建sqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//4:创建sqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);
//5:【重要】获取SqlSession对象,从SqlSessionFactory中获取SqlSession
SqlSession sqlSession = factory.openSession();
//6:【重要】指定要执行的sql语句的标识。sql映射文件中的namesapce + "." + 标签的id值
String sqlId = "com.sss.dao.StudentDao" + "." + "stuSelect";
//7:执行sql语句,通过sqlId找到语句。
List<Student> listStu = sqlSession.selectList(sqlId);
//8:输出结果
//listStu.forEach(student -> System.out.println(student));
for (Student stu : listStu) {
System.**out**.println(stu);
}
//9:关闭sqlSession对象
sqlSession.close();
6:主要类的介绍:
1:Resources:
myBatis中的一个类,负责读取主配置文件的。
InputStream in = Resources.getResourceAsStream(config);
2:sqlSessionFactoryBuilder:
负责调用build()方法,来创建sqlSessionFactory对象。
//3:创建sqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//4:创建sqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);
3:sqlSessionFactory:
重量级对象,程序创建一个对象耗时比较长,使用资源比较多。在整个项目中,有一个就够用了。
SqlSessionFactory factory = builder.build(in);
sqlSessionFactory是一个接口,接口的实现类:DefaultSqlSessionFactory
sqlSessionFactory作用:通过调用openSession()方法,获取sqlSession对象。
SqlSession sqlSession = factory.openSession();
openSession()方法说明:
openSession():无参数的,获取的是非自动提交事务的sqlSession对象
openSession(boolean):布尔类型参数:true:获取自动提交事务的sqlSession,false:获取的是非自动提交事务的sqlSession对象。
4:sqlSession:
sqlSession接口:定义了操作数据库的方法,例如:
selectOne(),selectList(),insert(),update(),delete(),commit(),rollback()
sqlSession接口的实现类: DefaultSqlSession,这个类中实现了操作数据库方法的实现。
使用要求:sqlSession对象不是线程安全的,需要在方法内部使用,在执行sql语句之前,调用openSession()方法,获取sqlSession对象。在执行完sql语句后,需要关闭它,执行sqlSession.close();这样能保证他的使用是线程安全的。
7:myBatis工具类(简化代码)
实现代码:
package org.example.utils;
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;
/**
* myBatis工具类
*/
public class MyBatisUtils {
private static SqlSessionFactory sf = null;
//在静态代码块中获取SqlSessionFactory对象【重量级对象,只需要创建一次】
static {
String config = "myBatis.xml"; //定义myBatis主配置文件
try {
//读取主配置文件
InputStream in = Resources.getResourceAsStream(config);
//创建sqlSessionFactory对象,使用sqlSessionFactoryBuild对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
sf = builder.build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession(){
SqlSession sqlSession = null;
if (sf != null){
sqlSession = sf.openSession(); //非自动提交事务
}
return sqlSession;
}
}
8:动态代理及传入参数
1:动态代理介绍:
使用sqlSession.getMapper(dao接口.class) 获取这个dao接口的实现类对象。
myBatis的动态代理:myBatis根据dao的方法调用,获取执行sql语句的信息。
myBatis根据你的dao接口,创建出一个dao接口的实现类,并创建出这个类的对象。
完成sqlSession调用方法,访问数据库。
简单说就是:通过myBatis的动态代理,就不需要创建接口的实现类,myBatis内部进行实现。
2:使用动态代理方式的要求:
1.dao接口和mapper文件放在一起,同一个目录下。
2.dao接口和mapper文件名称一致。
3.mapper文件中的namespace的值是dao接口的全限定名称。
4.mapper文件中的,,等,它们的id是接口中方法的名称。
实现代码:
@Test
public void testSelectStudent(){
/**
* 使用myBatis的动态代理机制,使用SqlSession.getMapper(dao接口)
* getMapper能获取dao接口对应的实现类对象。
* MyBatisUtils:自定义封装好的工具类
*/
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudenDao dao = sqlSession.getMapper(StudenDao.class);
//调用dao的方法,执行数据库的操作。
List<Student> studentList = dao.selectStudent();
for (Student student:studentList) {
System.**out**.println(student);
}
}
3:传入参数:
从java代码中把数据传入到mapper文件的sql语句中。
1):parameterType:写在mapper文件中的一个属性,表示dao接口中方法的参数的数据类型。
例如:StudentDao接口方法:
Student selectStudentById(Integer id);
2):传入一个简单类型的参数:
简单类型:myBatis把java的基本数据类型和字符串都叫做简单数据类型。
在mapper文件获取简单类型的一个参数的值,使用#{任意字符}
例如:
<?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="org.example.dao.StudenDao">
<!--
parameterType:dao接口中方法参数的数据类型。
parameterType它的值是java的数据类型全限定名称或者是myBatis定义的别名。
例如:parameterType="java.lang.Integer"
注意:parameterType不是强制的,myBatis通过反射机制能够发现接口参数的数据类型。
所以可以没有,一般我们也不写
-->
<select id="selectStudentById" parameterType="java.lang.Integer" resultType="org.example.entity.Student">
select id,name,email,age from student where id=#{id}
</select>
</mapper>
3):传入多个参数,使用@param命名参数
接口方法:
public List<Student> selectMulitParam(@Param("myname") String name,@Param("myage") Integer age);
使用 @Param(“参数名”) String name
mapper文件中这样写:
<select>
select * from student where name=#{myname} or age=#{myage}
</select>
4):使用java对象传入多个参数
1:先创建储存对象的java类
2:接口方法:
/**
* 多个参数,使用java对象作为接口中方法的参数
* @param param
* @return
*/
List<Student> selectMultiObject(QueryParam param);
3:mapper文件sql语句怎么写?
<!--多个参数,使用java对的属性值,作为参数的实际值
使用对象语法:#{属性名,javaType=类型名称,jdbcType=数据类型} 很少用
javaType:指java中的属性数据类型。
jdbcType:指数据库中的数据类型。
最完整的方式:
例如:name=#{paramName,javaType=java.lang.String,jdbcType=VARCHAR}
简化方式:#{属性名},javaType,jdbcType的值myBatis反射能获取,不用提供。
-->
<select id="selectMultiObject" resultType="org.example.entity.Student">
/*select id,name,email,age from student where name=#{paramName,javaType=java.lang.String,jdbcType=VARCHAR}
or age=#{paramAge,javaType=java.lang.Integer,jdbcType=INTEGER}*/
select id,name,email,age from student where name=#{paramName} or age=#{paramAge}
</select>
9:#和$的区别
1:#使用 ?在sql语句中做占位的,使用PreparedStatement执行sql,效率高。
2:#能够避免sql注入,更安全。
3:$不使用占位符,是字符串连接方式,使用Statement对象执行sql,效率低。
4:$有sql注入的风险,缺乏安全性。
5:$:可以替换表名或者列名。
#:占位符
告诉 mybatis 使用实际的参数值代替。并使用 PrepareStatement 对象执行 sql 语句, #{…}代替sql 语句的“?”。这样做更安全,更迅速,通常也是首选做法,
mapper 文件:
<select id="selectById" resultType="com.bjpowernode.domain.Student">
select id,name,email,age from student where id=#{studentId}
</select>
转为 MyBatis 的执行是:
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 使用 包 含 的 “ 字 符 串 ” 替 换 所 在 位 置 。 使 用 S t a t e m e n t 把 s q l 语 句 和 包含的“字符串”替换所在位置。使用 Statement 把 sql 语句和 包含的“字符串”替换所在位置。使用Statement把sql语句和{}的
内容连接起来。主要用在替换表名,列名,不同列排序等操作。
例 1: 分别使用 id , email 列查询 Student
接口方法:
Student findById(int id);
Student findByEmail(String email);
mapper 文件:
<select id="findById" resultType="com.bjpowernode.domain.Student">
select * from student where id=#{studentId}
</select>
<select id="findByEmail" resultType="com.bjpowernode.domain.Student">
select * from student where email=#{stuentEmail}
</select>
测试方法:
@Test
public void testFindStuent(){
Student student1 = studentDao.findById(1002);
System.out.println("findById:"+student1);
Student student2 = studentDao.findByEmail("zhou@126.net");
System.out.println("findByEmail:"+student2);
}
例 2:通用方法,使用不同列作为查询条件
接口方法:
Student findByDiffField(@Param("col") String colunName,@Param("cval") Object
value);
mapper 文件:
<select id="findByDiffField" resultType="com.bjpowernode.domain.Student">
select * from student where ${col} = #{cval}
</select>
测试方法:
@Test
public void testFindDiffField(){
Student student1 = studentDao.findByDiffField("id",1002);
System.out.println("按 id 列查询:"+student1);
Student student2 = studentDao.findByDiffField("email","zhou@126.net");
System.out.println("按 email 列查询:"+student2);
}
10:myBatis的输出结果
myBatis执行了sql语句,得到了java对象。
1:resultType结果类型
指sql语句执行完毕后,数据转为的java对象,java对象类型是任意的。
resultType结果类型的值:1:类型的全限定名称【建议使用】。2:类型的别名,例如java.lang.Integer别名是int
resultType结果类型处理方式:
1:myBatis执行sql语句,然后myBatis调用类的无参数构造方法,创建对象。
2:myBatis把ResultSet指定列值,赋值给同名的属性。
2:定义自定义类型的别名
1:在myBatis主配置文件中定义,使用定义别名。
2:可以在resultType中使用自定义的别名。
在myBatis主配置文件中设置:
<!--定义别名-->
<typeAliases>
<!--可以指定一个类型,一个自定义的别名
type:自定义类型的全限定名称
alias:别名(短小,容易记忆的)
-->
<typeAlias type="org.example.entity.Student" alias="stu"/>
<!--
第二种方式:
<package> name是包名,这个包中所有类,类名就是别名(类名不区分大小写)
例如:<package name="org.example.vo"/> 这个包中的QueryParam类,就是别名。
【常用方式】
-->
<package name="org.example.vo"/>
</typeAliases>
3:resultMap:结果映射
指定列名和java对象的属性对应关系。
1:你自定义列值赋值给那个属性。
2:当你的列名和属性名不一样时,一定使用resultMap
3:resultMap和resultType只能出现一个。
mapper文件:
<!--定义resultMap
id:自定义名称,表示你定义的这个resultMap
type:java类型的全限定名称
-->
<resultMap id="studentMap" type="org.example.entity.Student">
<!--定义列名和java属性的关系-->
<!--主键列,使用id标签
column:列名
property:java类型的属性名
-->
<id column="id" property="id"></id>
<!--非主键类,使用result-->
<result column="name" property="name"></result>
<result column="email" property="email"></result>
<result column="age" property="age"></result>
</resultMap>
<!--列名和属性名不一样,第一种解决方式:-->
<select id="selectStudents" resultMap="studentMap">
select id,name,email,age from student
</select>
<!--查询所有学生信息
resultType的默认原则是,同名的列值赋值给同名的属性,使用列别名(java对象的属性名)
-->
<!--列名和属性名不一样,第二种解决方式:-->
<select id="selectDiff" resultType="org.example.entity.Student">
select id as id,name as name,email,age from student
</select>
4:like模糊查询
dao接口:
/**
* 第一种模糊查询,在java代码中指定 like的内容
*/
List<Student> selectLikeOne(String name);
/**
* 第二种模糊查询,name就是关值,在mapper文件中拼接 like "%" 关 "%"
*/
List<Student> selectLikeTwo(String name);
mapper文件:
<!--第一种like,java代码中指定like的内容【推荐使用第一种方式】-->
<select id="selectLikeOne" resultType="org.example.entity.Student">
select id,name,email,age from student where name like #{name}
</select>
<!--第二种like方式:在mapper文件中拼接 like的内容-->
<select id="selectLikeTwo" resultType="org.example.entity.Student">
select id,name,email,age from student where name like "%" #{name} "%"
</select>
@Test:
/**
* 测试模糊查询
*/
@Test
public void testSelectLikeOne(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudenDao dao = sqlSession.getMapper(StudenDao.class);
String name = "%关%";
List<Student> student = dao.selectLikeOne(name);
for (Student student1: student) {
System.out.println(student1);
}
}
@Test
public void testSelectLikeTwo(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudenDao dao = sqlSession.getMapper(StudenDao.class);
List<Student> student = dao.selectLikeTwo("关");
for (Student student1: student) {
System.out.println(student1);
}
}
11:动态Sql
介绍:
动态sql:sql的内容是变化的。可以根据条件获取到不同的sql语句。主要是where部分发生变化。
动态sql的实现,使用的是myBatis提供的标签,,,
1:if是判断条件的
语法:
<if test="判断java对象的属性值">
部分的sql语句
</if>
mapper文件:
<!--if
<if test = "使用参数java对象的属性值作为判断条件,语法 属性名 = xxx值">
-->
<select id="selectStudentIf" resultType="org.example.entity.Student">
select id,name,email,age from student
where 1=1
<if test="name != null and name !='' ">
name = #{name}
</if>
<if test="age > 0">
or age > #{age}
</if>
</select>
2:where
用来包含多个if的,当多个if有一个成立的,会自动增加一个where关键字,并去掉if中多余的 and or 等。
mapper文件:
<!--
where:<where> <if></if>...</where>
-->
<select id="selectStudentWhere" resultType="org.example.entity.Student">
select id,name,email,age from student
<where>
<if test="name != null and name !='' ">
name = #{name}
</if>
<if test="age > 0">
or age > #{age}
</if>
</where>
</select>
3:foreach
循环java中的数据,List集合的,主要用在sql的in语句中。
查找学生id是 1001,1002,1003的三个学生。
select * from student where id in (1001,1002,1003);
foreach第一种方式:传入的是单个数据
dao接口:
//foreach 用法 1
List<Student> selectForeach(List<Integer> list);
mapper文件:
<!--
foreach 使用 1
collection:表示接口中的方法参数的类型,如果是数组使用array,如果是List集合使用list
item:自定义的,表示数组或集合成员的变量。
open:循环开始时的字符
close:循环结束时的字符
separator:集合成员之间的分割符
循环体: #{myid}
-->
<select id="selectForeach" resultType="org.example.entity.Student">
select * from student where id in
<foreach collection="list" item="myid" open="(" close=")" separator=",">
#{myid}
</foreach>
</select>
@Test:
/**
* 测试foreach 1
*/
@Test
public void testSelectForeach(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudenDao dao = sqlSession.getMapper(StudenDao.class);
List<Integer> list = new ArrayList<>();
list.add(1001);
list.add(1002);
list.add(1003);
List<Student> studentList = dao.selectForeach(list);
for (Student student : studentList) {
System.out.println(student);
}
sqlSession.close();
}
foreach 第二种方式:传入的是java集合对象
dao接口:
//foreach 用法 2
List<Student> selectForeachTwo(List<Student> stulist);
mapper文件:
<select id="selectForeachTwo" resultType="org.example.entity.Student">
select * from student where id in
<foreach collection="list" item="stu" open="(" close=")" separator=",">
#{stu.id}
</foreach>
</select>
@Test:
/**
* 测试foreach 2
*/
@Test
public void testSelectForeachTwo(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudenDao dao = sqlSession.getMapper(StudenDao.class);
List<Student> studentList = new ArrayList<>();
Student student = new Student();
student.setId(1001);
studentList.add(student);
System.out.println(studentList);
List<Student> studentList1 = dao.selectForeachTwo(studentList);
for (Student student3 : studentList1) {
System.out.println(student3);
}
sqlSession.close();
}
4:sql代码片段
用来复用一些sql语句。
步骤:
1:先使用 sql语句
2:再使用,
<!--定义sql片段-->
<sql id="studentSql">
select id,name,email,age from student
</sql>
<select id="selectStudentIf" resultType="org.example.entity.Student">
<include refid="studentSql"/>
</select>
12:数据库的属性配置文件
把数据库连接信息放到一个单独的文件中,和myBatis主配置文件分开。
目的是便于修改,保存,处理多个数据库的信息。
1:在resources目录下定义一个属性配置文件,xxx.properties,例如 jdbc.properties
在属性配置文件中,定义数,格式是key=value
key:一般使用 . 做多级目录的。
例如:jdbc.mysql.driver 或者 jdbc.driver
jdbc.mysql.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.user=root
jdbc.password=999
2:在myBatis主配置文件中,使用指定文件的位置。
在需要使用值的地方,${key}
<!--指定properties文件的位置,从类路径根开始找文件-->
<properties resource="jdbc.properties"></properties>
<environments default="development">
<environment id="development">
<!--
transactionManager:myBatis提交事务,回滚事务的方式
type:事务的处理类型。
1):JDBC:表示myBatis底层是调用JDBC中的Connection对象的,commit,rollback
2):MANAGED:把myBatis的事务处理委托给其他容器(一个服务器,一个框架(spring))
-->
<transactionManager type="JDBC"/>
<!--
dataSource:表示数据源,java体系中,规定实现了javax.sql.DataSource接口的都是数据源
数据源表示连接Connection对象的。
type:指定数据源的类型
1):POOLED:使用连接池,myBatis会创建PooledDataSource类
2):UPOOLED:不使用连接池,在每次执行sql语句,先创建连接,执行sql,再关闭连接。
myBatis会创建一个UnPooledDataSource,管理Connection对象的使用。
3):JNDI:java命令和目录服务(windows注册表)
-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.mysql.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
mapper文件位置的指定:
<!-- sql mapper(sql映射文件)的位置-->
<mappers>
<!--第一种方式:指定多个mapper文件-->
<mapper resource="org\example\dao\StudentDao.xml"/>
<!--<mapper resource="org\example\dao\StudentDao.xml"/>-->
<!--第二种方式:使用包名
name:xml文件(mapper文件)所在的包名。表示这个包中所有的xml文件一次都能加载到myBatis
使用package的要求:
1:mapper文件名称需要和接口名称一样,区分大小写。
2:mapper文件的dao接口需要在同一目录
-->
<!-- <package name="org.example.dao"/>-->
</mappers>
13:扩展:PageHelper
PageHelper做数据分页的。
步骤:
1:pom.xml:添加依赖
<!--pageHelper分页插件依赖-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
2:myBatis主配置文件:
<!--配置插件:在environments之前加入插件-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
3:dao接口:
//使用pageHelper分页数据
List<Student> selectAll();
4:mapper文件:
<!--查询所有-->
<select id="selectAll" resultType="org.example.entity.Student">
select id,name,email,age from student
</select>
5:@Test
/**
* 测试分页
*/
@Test
public void testSelectAll(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudenDao dao = sqlSession.getMapper(StudenDao.class);
//加入pageHelper的方法,分页方法
//两个参数
//pageNum:第几页,从1开始
//pageSize:一页中有多少行数据
PageHelper.startPage(1,3);
List<Student> studentList1 = dao.selectAll();
for (Student student : studentList1) {
System.out.println(student);
}
sqlSession.close();
}