·MyBatis框架概述
·三层架构
mvc: web开发中,使用mvc架构模式。m: 数据,V: 视图,C: 控制器。
1,C控制器:接收请求,调用service对象, 显示请求的处理结果。当前使用servlet作为控制器
2,v视图:现在使用jsp,html, CSS, js。显示请 求的处理结果,把m中数据显示出来。
3,m数据:来自数据库mysq|, 来自文件,来自网络
·mvc作用:
1)实现解耦合p
2)让mvc各负其职。
3)使的系统扩展更好。更容易维护。
三层架构:
1.界面层(视图层) :接收用户的请求,调用service, 显示请求的处理结果的。包含了jsp, html, servlet等对象。对应的包controller,
2.业务逻辑层:处理业务逻辑,使用算法处理数据的。把数据返回给界面层。对应的是service包,和包中的很多的XXXService类。例如: StudentService ,OrderService, ShopService
3.持久层(数据库访问层) :访问数据库,或者读取文件,访问网络。获取数据。对应的包是dao。dao包中很多的StudentDao, OrderDao, ShopDao等等。
·三层架构请求的处理流程
用户发起请求--->界面--->业务逻辑--->持久层--->数据库(mysql)
1,结构清晰、耦合度低,各层分工明确
2,可维护性高,可扩展性高.
3,有利于标准化
4,开发人员可以只关注整个结构中的其中某- -层的功能实现
5,有利于各层逻辑的复用
·三层架构模式和框架
每一层对应着一个框架
1)界面层--SpringMVC框架
2)业务层--Spring框架
3)持久层--MyBatis框架
MyBatis框架:
MyBatis是一个优秀的基于java的持久层框架,内部封装了jdbc,开发者只需要关注sql语句本身,而不需要处理加载驱动、创建连接、创建statement、 关闭连接。。。
Spring框架:
Spring框架为了解决软件开发的复杂性而创建的。Spring 使用的是基本的JavaBean来完成以前非常复杂的企业级开发。Spring 解决了业务对象,功能模块之。。。
SpringMVC框架
Spring MVC属于SpringFrameWork 3.0版本加入的一个模块,为Spring 框架提供了构建Web应用程序的能力。现在可以Spring 框架提供的SpringMVC模。。。
·框架
1)什么是框架(framework)
框架:就是一个软件,完成了部分的功能。软件中的类和类之间的方法调用都已经规定好了。通过这些可以完
成某些功能。框架看做是模版。
框架是可以升级的,改造的。框架是安全的。
框架是对某一个方面有用的,不是全能的。
·MyBatis解决的主要问题
1,减轻使用JDBC的复杂性,不用编写重复的创建Connetion , Statement ;不用编写关闭资源代码。
2,直接使用java对象,表示结果数据。让开发者专注SQL的处理。其他分心的工作由MyBatis代劳。
·MyBatis可以完成:
1)注册驱动。
2)创建jdbc中使用的Connection, Statement, ResultSet
3)执行sq|语句,得到ResultSet
4)处理ResultSet,把记录集中的数据转为java对象, 同时还能把java对象放入到List集合。
5)关闭资源
6)实现sql语句和java代码的解耦合。
·搭建MyBatis开发环境
·第一个例子
·实现步骤:
0.创建student表(id, name, email, age)
1.新建maven项目
2.修改pom.xml
1)加入依赖mybatis依赖, mysq|驱动, junit
2)在<bui1d>加入资源插件
3.创建实体类Student。定义属性,属性名和列名保持一致
4.创建Dao接口,定义操作数据库的方法。
5.创建xm|文件(mapper文件),写sq|语句。
mybatis框架推荐是把sq|语句和java代码分开
mapper文件:定义和dao接口在同一目录,一个表一个mapper文件。
6.创建mybatis的主配置文件(xml文件) :有一个,放在resources目录下
1)定义创建连接实例的数据源(DataSource) 对象
2)指定其他mapper文件的位置
XML配置文件中包含了对MyBatis 系统的核心设置,包括获取数据库连接实例的数据源(OataSource)以及决定事务作用域和控制方式的事务管理器(TransactionManager)。
后面会再探讨XML配置文件的详细内容,这里先给出—个简单的示例;
7.创建测试的内容。
使用main方法,测试mybatis访问数据库
也可以使用junit访问数据库|
·在Mybatis配置日志文件
<!--设置日志类型-->
<settings>
<setting name= "logImpl" value= "STDOUT_LOGGING" />
</settings>
发现是自动提交,则,每执行完一条语句就自动提交到数据库中。
2.2概念
1.自动提交:当你的sq|语句执行完毕后,提交事务。数据库更新操作之间保存到数据。
2.手动(手工)提交事务:在你需要提交事务的位置,执行方法, 提交事务或者回顾事务。
· MyBatis的一些重要对象
1) Resources : mybatis框架中的对象,一个作用读取主配置信息。
Inputstream inputstream = Resources.getResourceAsStream("mybatis.xm1");
2) SqlSessionFactoryBuilder:负责创建SqlSessionFactory对象
sqlSessionFactory factory = new sqlSessionFactoryBuilder ().build(inputStream);
3) SqlSessionFactory:"重要对象
SqlSessionFactory是重量级对象:创建此对象需要使用更多的资源和时间。在项目中有一个就可以了
sqlSessionFactory接口:作用是SqlSession的工厂,就是创建SqlSession对象。
DefaultSqlSessionFactory实现类
sqlSessionFactory接口中的方法
·openSession():获取一个默认的SqlSession对象,默认是需要手工提交事务的。openSession(boolean);
boolean参数表示是否自动提交事务。
true:创建一个自动提交事务的SqlSession
false:等同于没有参数的openSession
4) sqlSession对象
sqlSession对象是通过SqlSessionFactory获取的。SqlSession本身是接。DefaultSqlSession:实现类
sqlSession作用是提供了大量的执行sql语句的方法:
注意SqlSession对象不是线程安全的,使用的步骤:
①:在方法的内部,执行sql语句之前,先获取SqlSession对象。
②:调用SqlSession的方法,执行sql语句。
③:关闭SqlSession对象,执行SqlSession.close()。
解读:在方法的内部获取的SqlSession对象是局部变量,对于多线程是安全的。
·如何开始新的模块?
·代理模式
/**测试方法中:调用dao的方法
student student = dao.selectById(1002);
1) studentDao:通过反射能够得到全限定类型名称
studentDao是StudentDao类型的,全限定名称gdm.DAO.StudentDao
2) selectById: studentDao中的方法名称,方法名称就是 mapper文件中标签的id
通过dao.selectById()能得到 sqLId="gdm.DAO.StudentDao.sss";
3) 确定调用sqlsession的那个方法
1.根据dao接口的方法返回中,如果返回是一个对象,例如student ,调用sqLSession. selectOne();
如果dao接口中的方法返回List,调用sqlSession的 selectList();
2.根拍mapper文件中的标签,如果标签是<insert>,调用sqLSession.insert()方法.
mybatis框架,发现使用dao的方法调用能确定执行sqL语句的必要信息,
mybatis简化dao对象的实现。
mybatis框架在程序执行期间,根据你的Dao接口,创建一个内存中的接口的实现类对象。
mybatis把这个技术叫做dao技术(动态代理,dao的动态代理)。
dao代理技术:mybatis创建 StudentDao接口的实现类proxy(==studentDaoImpl),
使用框架创建的StudentDaoImpl代替你自己手工实现的StudentDaoImpl类的功能,不用开发人员写dao接口的实现类。
使用dao的代理要求:
1. mapper文件中的namespace: 必须是DAO接口的全限定名称
2. mapper.文件中标签的id是DAO接口中的方法名称(一摸一样的)
*/
即:通过配置文件提供的接口,类的路径,来反射创建实例对数据库的操作。
如:
@Test
public void selectMAp(){
//获取连接
SqlSession session = MybatisUtil.getSqlSession();
//获取接口StudentDao的代理对象
//这样就可以调用接口StudentDao的方法了
StudentDao dao = session.getMapper(StudentDao.class);
Custom custom = dao.selectStudentById1(1);
session.close();
}
解读:代理模式就是为了获取StudentDao实例,去调用改接口的方法;
代理模式省略了创建类StudentDaoImpl去实现StudentDao。
·parameterType参数。
parameterType :指定dao接口中的方法的形参的类型。
这个属性的值可以使用java类型的全限定名称或者mybatis定义的别名
第一个用法:
java类型的全限定类型名称
parameterType="java . lang . Integer"
第二个用法:
mybatis定义的java类型的别名parameterType="int'
如:调用接口方法。
使用别名代替,Integer的别名是integer。
<select id="s" parameterType="integer" resultType="gdm.domain.Student">
<!-- select * from student where id = 1 -->
select * from student where id = #{studentId}
</select>
注意:parameterType: mybatis通过反射机制可以获取dao接 口方法参数的类型,可以不写。
·关于dao接口的方法参数类型
1,dao接口的方法形参如果是:
一个简单类型的简单类型(java基本数据类型和string)
mapper文件,获取这个参数值,使用#{任意字符}
接口方法
public interface StudentDao {
//查询一个学生
//返回一个Student对象,方便toString()方法查看
Student selectStudentById(Integer id);
Xml文件
select * from student where id = #{studentId}
- 如果是多个简单类型的简单类型。
·使用@Param符号(推荐)
在dao接口中
public interface StudentDao {
//根据或运算,查询符合id,eamal相关的值的多个用户。
List<Student> SelectByIOrE (@Param(value = "myid") Integer id,
@Param("myemail") String email);
在xml文件中
<!--多个简单类型的参数
当使用了@Param命名后,例如@Param( "myname")
在mapper中,使用#{命名的参数},例如 #{myname}
-->
<select id="SelectByIOrE" resultType="gdm.domain.Student">
select * from student where id=#{myid} or email=#{myemail}
</select>
·还可以使用位置{arg0},{arg1},{arg2}。。。这样固定的写法。
接口:
public interface StudentDao {
//位置参数
List<Student> SelectWWW ( Integer id,String email);
Xml文件
<select id="SelectWWW" resultType="gdm.domain.Student">
select * from student where id=#{arg0} or email=#{arg1}
</select>
3,引用类型
在dao接口中
public interface StudentDao {
//根据某用户作为参数
List<Student> selectByObject(Student student);
在xml文件中
<select id="selectByObject" resultType="gdm.domain.Student">
select * from student where id=#{id} or email=#{email}
</select>
4,多个参数,使用Map类型(不建议)
Map集合可以存储多个值,使用Map向mapper文件一次传入多个参数。Map集合使用String的key,
Object类型的值存储参数。mapper文件使用# { key }引用参数值。
接口
public interface StudentDao {
//使用Map<>作为参数
List<Student> SelectMap (Map<String,Object> map);
Xml文件
<!--
使用Map传递参数,
在mapper文件中,获取map的值,是通过key获取的,语法:#{key}
-->
<select id="SelectMap" resultType="gdm.domain.Student">
select * from student where id=#{myname} or email=#{myage}
</select>
测试代码
@Test
public void selectMap(){
//代理模式
//不需要实现接口的方法
SqlSession session = MybatisUtil.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
Map<String, Object> data = new HashMap<String, Object>();
data.put("myname","大kk");
data.put("mynage",20);
dao.SelectMap(data);
session.close();
}
·[掌握]占位符#和$
·#:占位符,告诉mybatis使用实际的参数值代替。并使用PrepareStatement对象执行sql语句,#{...}代替sql语句的“?”。这样做更安全,更迅速,通常也是首选做法,
<select id="SelectByIOrE" resultType="gdm.domain.Student">
select * from student where id=#{myid} or email=#{myemail}
</select>
执行sql语句相当于:
//mybatis出创建PrepareStatement对象,执行sq1语句
string sq1="select * from student where id=? or email =?";
PrepareStatement pst = conn.preparestatement(sq1);
pst.setInt(1,1001);//传递参数
Resultset rs= pst.executeQuery();//执行sq1语句
#特点:
1)使用的PrepareStatement对象,执行sql语句,效率高。
2)使用的PrepareStatement对象,能避免sql语句,sql语句执行更安全。
3)#常常作为列值使用的,位于等号的右侧,#仍位置的值和数据类型有关的。
·$表示字符串连接,把sql语句的其他内容和$科内容使用字符串(+)连接的方式连在一起。
<select id="SelectWWW" resultType="gdm.domain.Student">
select * from student where id=${myId}
</select>
相当于,如:myId=12.
String sql="select id ,name,email, age from student where id=" + "12";
//mybatis创建statement对象,执行sql语句。
statement stmt = conn.createstatement(sq1);
Resu1tset rs= stmt. executeQuery();
$的特点
1)使用Statement对象,执行sql语句,效率低。
2)${}占位符的值,使用的字符串连接方式,有sql注入的风险。有代码安全的问题。
3)${}数据是原样使用的,不会区分数据类型。
4)${}常用作表名或者列名,在能保证数据安全的情况下使用${}
·封装MyBatis输出结果
·resultType属性
resultType属性:在执行select时使用,作为<select>标签的属性出现的。
resultType:执行sql得到ResultSet转换的类型,使用类型的完全限定名或别名。
注意如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。
resultType和resultMap,不能同时使用。
resultType:表示结果类型,mysql执行sql语句,得到java对象的类型。它的值有两种
- java类型的全限定名称。
- 使用别名
如:
<select id="selectStudentById" resultType="gdm.domain.Student">
select * from student where id = #{studentId}
</select>
resu1tType:现在使用java类型的全限定名称。表示的意思mybatis执行sql,把Resultset中的数据转为student类型的对象。 mybatis会做以下操作:
1.调用com.gdm.domain.student的无参数构造方法,创建对象。
student student = new Student(); //使用反射创建对象
2.同名的列赋值给同名的属性。(类Student属性与数据库属性同名)
student.setId( rs.getInt("id"));
student.setName(rs.getstring( "name"));
3.得到java对象,如果dao接口返回值是List集合,mybatis把student对象放入到List集合。
所以执行Student mystudent = dao.selectById(1001);得到数据库中id=1001这行数据,
这行数据的列值,赋给了mystudent对象的属性。就能得到mystudent对象。就相当于获得id=1001这行数据。
·resultMap
resultMap:结果映射。自定义列名和java对象属性的对应关系。常用在列名和属性名不同的情况。
用法:
1.先定义resultMap标签,指定列名和属性名称对应关系
2.在select标签使用resultMap属性,指定上面定义的resultMap的id值
如果domain里面的某个类的属性与数据库的属性名字不一一对应,则会出现以下情况。
Xml文件
<!--使用resultMap定义列和属性的关系
定义resultMap
id:给resultMap的映射关系起个名称,唯一值
type:返回java类型的全限定名称
-->
<resultMap id="customMap" type="gdm.domain.Custom">
<!--定义列名和属性名的对应-->
<!--主键类型使用id标签-->
<id column="id" property="cid"/>
<!--非主键类型使用result标签-->
<result column="name" property="cname"/>
<!--列名和属性名相同不用定义-->
<result column="email" property="email"/>
<result column="age" property="age"/>
</resultMap>
<!--使用resultMap属性,指定映射关系的id-->
<select id="selectStudentById1" resultMap="customMap">
select * from student where id = #{sId}
</select>
<select id="selectStudentById2" resultMap="customMap">
select * from student where id = #{sId}
</select>
这样resultMap=“值”就修改了属性一致的问题。
·设置别名
·第一种方式
·在Mybatis,xml文件中
<!--设置别名-->
<typeAliases>
<!--第一种语法格式
type :java类型的全限定名称(自定义类型)
alias:自定义别名
-->
<typeAlias type="gdm.domain.Student" alias="Student"/>
</typeAliases>
则在**Dao.xml的文件就可以,把resulutType的值改为Student(与alias的值相同)的简化操作。
<select id="selectStudentsById"resultType="Student">
select * from student
</select>
优点:
别名可以自定义
缺点:
每个类型必须单独定义。
·第二种方式
·在Mybatis,xml文件中
<!--第二种方式
name:包名,mybatis会把这个包中所有类名作为别名(不用区分大小写)
-->
<package name="gdm.DAO"/>
<package name="gdm.domain"/>
</typeAliases>
则在**Dao.xml的文件就可以,把resulutType的值改为Student(与类名相同)的简化操作。
<select id="selectStudentsById"resultType="Student">
select * from student
</select>
优点:使用方便,一次给多个类定义别名
缺点:别名不能自定义,必须是类名。其如果:包1与包2有相同的类,会报错。
·模糊查询like
模糊查询的实现有两种方式,
一是java代码中给查询数据加上“%”;(推荐)
在xml文件:
<!--like第一种方式-->
<select id="selectLike " resultType="gdm.domain.Student">
select * from student where name like #{name}
</select>
接口中:
//模糊查询
List<Student> selectLike1(@Param("name") String name);
在测试代码:
@Test
public void selectLike(){
SqlSession session = MybatisUtil.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
String name="小%";
List<Student> students = dao.selectLike1(name);
session.close();
students.forEach(s-> System.out.println(s));
//for (Student s:students){
// System.out.println(s);
//}
}
二是在mapper文件sql语句的条件位置加上“%”
sql语句like的格式: where name like "%"空格#{name}空格"%"
在xml文件:
<!--like第二种方式-->
<select id="selectLikeTwo" resultType="gdm.domain.Student">
select * from student where name like "%" #{name} "%"
</select>
接口中:
//模糊查询
List<Student> selectLike2(@Param("name") String name);
在测试代码:
@Test
public void selectLike(){
SqlSession session = MybatisUtil.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
String name="小";
List<Student> students = dao.selectLike1(name);
session.close();
students.forEach(s-> System.out.println(s));
//for (Student s:students){
// System.out.println(s);
//}
}
·动态sql
什么是动态sql:同一个dao的方法,根据不同的条件可以表示不同的sql语句,主要是where部分有变化使用mybatis提供的标签,实现动态sql的能力,主要讲if , where,foreach,sql。
使用动态sql的时候, dao方法的形参使用java对象。
·if标签
语法
<if test="boolean判断结果">
sq1 代码
</if>
如:例子
在xml文件
<!--if
在mapper文件中-->
<select id="IF" resultType="gdm.domain.Student">
select* from student
where id=-1
<if test="name !=null and name !=''">
name = #{name}
</if>
<if test="age >0">
or age = #{age}
</if>
</select>
解读:id=-1是为了sql语句语法不容易出错误,若两个test都符合if条件,则把括号内语句name与or age加到where后面。(防止出现select* from student where or age = ?的语法错误)
即:select* from student where name = ? or age = ?
在接口
//if语句
//要是有对象传入
List<Student> IF(Student student);
测试代码
@Test
public void selectIF(){
SqlSession session = MybatisUtil.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
Student student = new Student();
student.setName("大");
student.setAge(6);
List<Student> students = dao.IF(student);
session.close();
students.forEach(s-> System.out.println(s));
}
· where标签
where标签只是代替了是SQL语句的where,没有什么特别之处,和if语法一样。
使用if标签时,容易引起sql语句语法错误。使用where标签解决if产生的语法问题。
使用时where ,里面是一个或多个if标签,当有一个if标签判断条件为true,where标签会转为WHERE
关键字附加到sql语句的后面。如果if没有一个条件为true ,忽略where和里面的if。
语法:
<where>
<if test="条件1">sq1语句1</if>
<if test=" 条件2">sq1语句2</if>
</where>
Mxl文件
<!--where -->
<select id="WHERE" resultType= "gdm.domain.Student" >
select * from student
<where>
<if test="name !=null and name != '' " >
or name =#{name}
</if>
<if test="age >0">
or age < #{age}
</if>
</where>
接口
//where语句
//要是有对象传入
List<Student> WHERE(Student student);
测试代码
@Test
public void selectWHERE(){
SqlSession session = MybatisUtil.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
Student student = new Student();
student.setName("大");
student.setAge(6);
List<Student> students = dao.WHERE(student);
session.close();
students.forEach(s-> System.out.println(s));
}
· foreach标签
foreach标签是为了应对sql语句的有特殊符号的状况。
<foreach collection="集合类型" open="开始的字符" close="结束的字符"
item="集合中的成员" separator="集合成员之间的分隔符">
#{item的值}
</foreach>
标签属性:
1,collection:表示,循环的对象是数组,还是1ist集合。
如果dao接口方法的形参是数组, 如:collecti on=" array" ,
如果dao接口形参是List, 如:collection="list"
2,open:循环开始时的字符。 如:sq1. append("(");
3,close:循环结束时字符。 如:sq1. append(")");
4,item:集合成员,自定义的变量。 如:Integer item = idlist.get(i); // item是集合成员
5,separator:集合成员之间的分隔符。 如:sq1. append(" ,"); //集合成员之间的分隔符
6,#{item的值}:获取集合成员的值。
如要查询以下语句。如(1,2,3)
select * from student where id in (1,2,3)
此时foreach派上用场。
Xml文件
<!--foreach第一种方式, 循环简单类型的List-->
<select id="Foreach1" resultType="gdm.domain.Student">
select * from student
<if test="list !=null and list.size>0">
where id
<foreach collection="list" open="(" close=")"
separator="," item= "myid">
#{myid}
</foreach>
</if>
</select>
这样设置为了sql语句语法不发生错误。当条件不符合是走select * from student语句。
接口:
//Foreach语句
//基本数据类型集合传入
List<Student> Foreach1(List<Integer> idList);
测试语句
@Test
public void Foreach1(){
SqlSession session = MybatisUtil.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
List<Integer> idList = new ArrayList<>();
idList.add(1);
idList.add(2);
idList.add(3);
List<Student> foreach = dao.Foreach1(idList);
foreach.forEach(f-> System.out.println(f));
session.close();
}
用法二(对象型):
Xlm文件
<!--foreach第二种方式, 循环List<Student>-->
<select id="Foreach2" resultType="gdm.domain.Student">
select * from student
<if test="list !=null and list.size>0">
where id in
<foreach collection="list" open="(" close=")"
separator="," item= "stu">
#{stu.id}
</foreach>
</if>
</select>
接口
//2
List<Student> Foreach2(List<Student> studentList);
测试代码
@Test
public void Foreach2(){
SqlSession session = MybatisUtil.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
List<Student> idList = new ArrayList<>();
Student student1 = new Student();
student1.setId(3);
Student student2 = new Student();
student2.setId(6);
idList.add(student1);
idList.add(student2);
List<Student> foreach = dao.Foreach2(idList);
foreach.forEach(f-> System.out.println(f));
session.close();
}
·sql标签
sq|标签标示一段sq|代码,可以是表名,几个字段,where条件都可以,可以在其他地方复用sq|标签的内容。
使用方式:
<!--定义代码片段-->
<sql id="S1">
select * from student
</sql>
<!--where -->
<select id="WHERE" resultType= "gdm.domain.Student" >
<include refid="S1"/>
<!--代替:select * from student-->
<where>
<if test="name !=null and name != '' " >
or name =#{name}
</if>
<if test="age >0">
or age < #{age}
</if>
</where>
</select>
自定义标签可以sql语句复用
第五章MyBatis配置文件
mybatis配置文件两大类: 1 mybatis主配置文件; 2 mybatis的mapper文件
1. mybatis主配置文件,提供mybatis全局设置的。包含的内容日志,数据源, mapper文件位置
2. mapper文件:写sq|语句的。 -个表-个mapper文件
environments:环境标签,在他里面 可以配置多个environment
属性: default ,必须是某个environment的id属性值。表示mybatis默认连接的数据库
environment:表示一个数据库的连接信息。
属性: id 自定义的环境的标识。唯一值。
transactionManager:事务管理器
属性: type 表示事务管理器的类型。
属性值:
1) JDBC:使用Connect i on对象,由mybatis自己完成事务的处理 。
2) MANAGED: 管理,表示把事务的处理交给容器实现(由其他软件完成事务的提交,回滚)
dataSource:数据源,创建的Connect ion对象,连接数据库。
属性: type 数据源的类型
属性值:
1) POOLED,mybatis会在内存中创建PooledDataSource类,管理多个Connection连接对象,使
用的连接池
2) UNPOOLED,不使用连接池,mybatis创建一个UnPooledDataSource这个类,每次执行sq1
语句先创建Connection对象,再执行sq1语句,最后关闭Connection
3) JNDI : j ava的命名和目录服务。-->
<environments default="development">这行标签为了方便切换数据库,修改default="???"即可
//数据库:development (代号)
<environment id="development">
<transactionManager type="JDBC"/>
<!--配置数据源:创建connection对象.-->
<dataSource type="POOLED">
<!--驱动内容-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<!--连接数据库的URL,其中 ' & ' 使用 ' & ' 代替-->
<property name="url" value="jdbc:mysql://localhost:3306/db1?rewriteBatchedStatements=true&useSSL=false&serverTimezone=UTC"/>
<!--数据库 用户名 与 密码 -->
<property name="username" value="root"/>
<property name="password" value="gdm"/>
</dataSource>
</environment>
//数据库:sss
<environment id="ssss">
<transactionManager type="JDBC"/>
<!--配置数据源:创建connection对象.-->
<dataSource type="POOLED">
<!--驱动内容-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<!--连接数据库的URL,其中 ' & ' 使用 ' & ' 代替-->
<property name="url" value="jdbc:mysql://localhost:3306/db1?rewriteBatchedStatements=true&useSSL=false&serverTimezone=UTC"/>
<!--数据库 用户名 与 密码 -->
<property name="username" value="qf"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
·使用properties与联合配置
需要把数据库的配置信息放到一个单独文件中,独立管理。这个文件扩展名是properties.在这个文件中,使用自定义的key=value的格式表示数据
使用步骤:
- 在resources目录中,创建xxxx.properties
- 在文件中,使用key=value的格式定义数据。例如jdbc.url=jdbc:mysq;://localhost:3306/springdb
Jdbc.properties文件
注意:url使用&代替&
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.ur1=jdbc:mysql://localhost:3306/db1?rewriteBatchedStatements=true&useSSL=false&serverTimezone=UTC"
jdbc.username=root
jdbc.password=gdm
3.在mybatis主配置文件,使用properties标签引用外部的属性配置文件
Mybatis.xml文件只需要增加一条<properties resource="Jdbc.properties"/>去指定properties的位置。
<!--使用外部属性配置文件
resource:指定类路径下的某个属性配置文件-->
<properties resource="Jdbc.properties"/>
<!--环境标签-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!--配置数据源:创建connection对象.-->
<dataSource type="POOLED">
<!--驱动内容-->
<property name="driver" value="${jdbc.driver}"/>
<!--连接数据库的URL,其中 ' & ' 使用 ' & ' 代替-->
<property name="url" value="${jdbc.url}/>
<!--数据库 用户名 与 密码 -->
<property name="username" value="${root}"/>
<property name="password" value="${gdm}"/>
</dataSource>
</environment>
</environments>
4.在使用值的位置,使用${key}获取key对应的value(等号右侧的值)。
·mapper标签使用的格式有两个常用的方式:
与接口名字相同,
如:以下两种方式。
<mappers>
<!--第一种方式,resources="mapper文件的路径”
优点:文件清晰。加载的文件是明确的。文件的位置比较灵活。
缺点:文件比较多,代码量会比较大,管理难度大
-->
<mapper resource="gdm/DAO/StudentDao.xml"/>
<mapper resource="gdm/DAO/CustomDao.xml"/>
<!--
第二种方式,使用<package>
name:包名,mapper文件所在的包名。
特点:把这个包中的所有mapper文件,一次加载。
使用要求:
1. mapper文件和dao接口在同一目录
2. mapper文件的namespace和dao接口名称完全一样。
-->
<package name="gdm.DAO"/>
</mappers>
·pagehelper插件
经常用来做网页的分页功能。PageHelper做数据分页。在你的select语句后面加入分页的sql 内容,如果你使用的mysql数据库,它就是在select * from student后面加入limit语句。
(1)
maven坐标
<dependency>
<groupld>com.github.pagehelper</groupld><artifactld>pagehelper</artifactld>
<version>5.1.10</version>
</dependency>
(2)加入plugin配置
在<environments>之前加入<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"/></plugins>
(3)PageHelper对象
查询语句之前调用PageHelper.startPage静态方法。
除了PageHelper.startPage方法外,还提供了类似用法的PageHelper.offsetPage方法。在你需要进行分页的 MyBatis查询方法前调用PageHelper.startPage静态方法即可,紧跟在这个方法后的第一个MyBatis查询方法会被进行分页。
如:
Xml文件
<select id="selectAllStudents" resultType="gdm.domain.Student">
select * from student order by id
</select>
接口:
public interface StudentDao {
List<Student> selectAllStudents();
测试代码
@Test
public void testPageHelper(){
//1.获取SqlSession
SqlSession session = MybatisUtil.getSqlSession();
//2.获取dao的代理
StudentDao dao = session.getMapper(StudentDao.class);
//调用PageHelper的方法
PageHelper.startPage(1,3);
List<Student> students = dao.selectAllStudents();
students.forEach( stu-> System.out.println( "stu=="+stu));
//3.关闭SqlSession对象
session.close();
}
·mybatis2级缓存
·一级缓存是保存在一次会话(sqlSession)中的(默认开启一级缓存)
不过进行增删改操作,会清除缓存。
·什么条件下会命中一级缓存?
1、相同的Sql和参数
2、必须是在相同的会话
3、必须是相同的方法
4、必须是相同的namespace(在同一个类(sql接口)中)
5、不能够在查询之前执行clearCache
6、不能执行任何的update,delete, insert
缓存结构:键值对
hashmap key值:hashcode+sqlid +sql语句
value:映射出来的java对象
·如何实现的?
·二级缓存是mapper中的,也可以配置第三方存储:如redis
二级缓存解决不同会话直接的缓存问题。
·二级缓存命中条件
- 必须设置@CacheNamespace
- put缓存之前必须关闭会话
3、必须是相同的方法
4、必须是相同的namespace(在同一个类(sql接口)中)
5、不能够在查询之前执行clearCache
6、不能执行任何的update,delete, insert