MyBatis

·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}

  1. 如果是多个简单类型的简单类型。

·使用@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对象的类型。它的值有两种

  1. java类型的全限定名称。
  1. 使用别名

如:

<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 ,必须是某个environmentid属性值。表示mybatis默认连接的数据库
environment:表示一个数据库的连接信息。
属性: id 自定义的环境的标识。唯一值。


transactionManager:事务管理器
属性: type 表示事务管理器的类型。
属性值:
1) JDBC:使用Connect i on对象,由mybatis自己完成事务的处理 。
2) MANAGED: 管理,表示把事务的处理交给容器实现(由其他软件完成事务的提交,回滚)

dataSource:数据源,创建的Connect ion对象,连接数据库。
属性: type 数据源的类型
属性值:
1) POOLEDmybatis会在内存中创建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的格式表示数据

使用步骤:

  1. 在resources目录中,创建xxxx.properties

  1. 在文件中,使用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文件的namespacedao接口名称完全一样。
    -->
    <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

二级缓存解决不同会话直接的缓存问题。

 

 

·二级缓存命中条件

  1. 必须设置@CacheNamespace

 

  1. put缓存之前必须关闭会话

 

 

3、必须是相同的方法

4、必须是相同的namespace(在同一个类(sql接口)中)

5、不能够在查询之前执行clearCache

6、不能执行任何的update,delete, insert

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值