Mybatis--增强的JDBC、SSM

MyBatis是一个SQL映射框架,它提供了数据库操作能力,包括SQL映射和数据访问对象(DAO)。相比JDBC,MyBatis减少了大量重复代码,提升了开发效率。在使用MyBatis时,需要定义DAO接口,实现接口的XML文件,配置数据库连接,以及在DAO实现类中执行SQL。MyBatis通过占位符防止SQL注入,支持条件查询和缓存机制,从而提高了安全性与性能。
摘要由CSDN通过智能技术生成

一、概述

1、mybatis是一个sql映射框架,提供了数据库操作能力

  (1)sql映射(sql mapper)

           将数据库中的一行数据映射为一个java对象

           操作这个对象就相当于操作 表中的数据

(2)数据访问(Data Access Objects )--Dao

           对数据进行增删改查

2、功能

  • 提供了创建Connection,Statement,ResultSet的能力
  • 提供了执行sql,将sql结果转换成对象,封装到list集合的能力

        开发人员只需要提供sql语句,mybatis处理sql,

        开发人员得到表中数据封装的list集合或java对象

  • 提供了关闭资源的能力

3、与JDBC的比较

(1)JDBC缺点

     JDBC代码较多,开发效率较低,

     需要关注Connection,Statement,Resultset对象的创建和销毁

     重复代码比较多

     业务代码和数据库操作混在一起

(2)mybatis优点

      开发人员只需要提供sql语句即可,其他重复代码由框架内部实现

二、映射步骤---dao层

1、定义接口类---xxxDao

     声明相应的数据操作函数

    public interface StudentDao{

         public  List<Student>  SelectStudents();//查询所有学生

         public int insertStudent(Student student);//增加学生

}

2、实现接口----xxxDao.xml

      具体实现接口类中声明的函数,利用mapper标签写相应的sql语句

     优点:

        不需要写连接数据,通过数据库对象调用sql语句,释放资源等操作

        只需要在此xml文件中,利用特定的标签符号写入需要的sql语句即可

    <mapper namespace="指定要映射的dao接口类 (包名+类名)">

         <select id="dao中对应方法名" resultType=“结果返回值类型”>... </select>

        <update id="dao中对应方法名" resultType=“结果返回值类型”>...</update>

        <insert id="dao中对应方法名" resultType=“结果返回值类型”>... </insert>

        <delete id="dao中对应方法名" resultType=“结果返回值类型”>...</delete>       

     <mapper>

 [注]一个类的全限定名称----包名+类名-----选中类,右键 copy reference即可

3、连接数据库----mybatis.xml

      连接数据库,将xxxDao.xml告诉容器

<configuration>     

<settings>

   <!--设置mybatis全局行为:输出日志-->

   <setting name="logImpl" value="STDOUT_LONGGING">

</settings>

<environments default="本工程默认连接运行的数据库">

    <environment id=“自定义代表数据库名”>

       <!--1、事务类型,使用jdbc中连接对象的commit和roback做事务处理-->

      <transactuonManager type="JDBC"/>

     <!--2、数据库连接信息-->

      <dataSourece type="POOLED">

           <property name="driver" value="com.mysql.jdbc.Driver"/>

           <property name="url" value="jdbc:mysql://localhost:3306/真实数据库名"/>

           <property name="username" value="root"/>

            <property name="password" value="xxx"/>

     </dataSourece>

    </environment>

   <environment id=“自定义代表数据库名”>

      数据库2连接信息

   </environment>

    <!--3、指定sql映射文件位置-->

  <mappers>

      <mapper resource="类路径.xml">  //从类路径target/clasess开始的路径信息

 </mappers>

</environments> 

</configuration>     

4、具体操作并获取操作结果 --xxxDaoImpl

  SqlSessionFactoryBuilder---用来创建SqlSessionFactory对象

  SqlSessionFactory---用来获取SqlSession

  SqlSession---用来执行sql语句

(1)查

 public  List<Student>  SelectStudents(){
   //1、读取mybatis配置文件,获取数据库信息及mapper文件信息
       String config="mybatis.xml";
       InputStream in=Resources.getResourceAsStream(congfig);
   //2、获取SqlSessionFactoryBuilder
       SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
   //3、获取 SqlSessionFactory
       SqlSessionFactory factory=builder.build(in);
   //4、获取 SqlSession
       SqlSession  sqlSession=factory.openSession();
   //5、执行sql语句

       String sqlId="sql映射文件中的namespace.select标签id值";//获取mapper文件中的sql标签语句
       List<Student> students=sqlSession.selectList(sqlId);//执行查询

       sqlSession.close();
  //6、返回结果
      return students;

}

(2)增

    <1>将共有的获取SqlSession过程封装成工具类   

public class MyBatisUtils{

 private static SqlSessionFactory factory=null;
 //SqlSessionFactory对象只用创建一次
 static{
      try{
      //1、读取mybatis配置文件,获取数据库信息及mapper文件信息
       String config="mybatis.xml";
       InputStream in=Resources.getResourceAsStream(congfig);
      //2、获取SqlSessionFactoryBuilder
       SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
      //3、获取 SqlSessionFactory
       factory=builder.build(in);
       }
     catch(IOException e){e.printStackTrace();}
     
    }

    //4、封装函数,获取 SqlSession
    public static SqlSession getSqlSession(){
      SqlSession sqlSession=null;
      if(factory!=null){
        sqlSession=factory.openSession();
      }
    }
    return  sqlSession;

}

[注]一个对象的创建只需要一次时,则可以放在static代码块中,类加载时就执行,且只执行一次

      若后面需要用到该对象,在代码块之外先声明一下,类加载时对象就会创建并赋值

    <2>具体实现

 public int insertStudent(Student student){
  //1、获取 SqlSession
      SqlSession  sqlSession=MyBatisUtils.getSqlSession();
  //2、执行sql语句
      String sqlId="sql映射文件中的namespace.insert标签id值";//获取mapper文件中的sql标签语句  
      int n=sqlSession.insert(sqlId,student);
  //3、提交事务和关闭资源
      sqlSession.commit();  
      sqlSession.close();

}

5、测试 (一般用于业务层或控制层)

(1)一般方式

public class TestMybatis{

 //查询
  public void testSelect(){
   StudentDao=new StudentDaoImpl();
   List<Student>  studentList=dao.SelectStudents();
   for(Student stu:studentList){
    System.out.println(stu);
    }
   
  }
 
  //添加
  public void testInsert(){
   StudentDao=new StudentDaoImpl();
   Student s=new Student();
   s.setId(001);
   s.setName("张三");
   int n=dao.insertStudent();
    System.out.println("添加对象数量"+n);
   
  }

}

(2)动态代理方式

public class TestMybatis{

 //查询
  public void testSelect(){
   SqlSession  sqlSession=MyBatisUtils.getSqlSession();
   StudentDao dao=sqlSession.getMapper(StudentDao.class);
 // StudentDao=new StudentDaoImpl();
   List<Student>  studentList=dao.SelectStudents();
   for(Student stu:studentList){
    System.out.println(stu);
    }
   
  }
 
  //添加
  public void testInsert(){
   SqlSession  sqlSession=MyBatisUtils.getSqlSession();
   StudentDao dao=sqlSession.getMapper(StudentDao.class);
   Student s=new Student();
   s.setId(001);
   s.setName("张三");
   int n=dao.insertStudent();
    System.out.println("添加对象数量"+n);
   
  }

}

三、sql映射xml文件--sql语句的编写

1、增删改查标签

  <mapper namespace="指定要映射的dao接口类 (包名+类名)">

         <select id="dao中对应方法名" resultType=“结果返回值类型”>... </select>

        <update id="dao中对应方法名" resultType=“结果返回值类型”>...</update>

        <insert id="dao中对应方法名" resultType=“结果返回值类型”>... </insert>

        <delete id="dao中对应方法名" resultType=“结果返回值类型”>...</delete>       

     <mapper>

2、传参

(1)传入参数类型---parameterType(可省略)

       用来标识待传入参数的类型

    <select id="dao中对应方法名" parameterType="int" resultType=“结果返回值类型”>

          select name  from student  where id=#{studentId}

   </select>         

(2)传参

   【传一个参数】 

    #{任意字符}  --占位符

    使用#{}之后,mybatis执行的sql是使用jdbc中PreparedStatement对象,由mybatis内部执行    

<select id="selectStudentByid"  resultType=“com.entity.Student”>

    select id,name,email from student  where id=#{studentId}

</select>         

 【传两个参数】

  方式一:命名参数,@Param("自定义参数名称")

  <1> dao接口--命名参数

    List<Student> selectMultiParam(@Param("myname")String name,

                                                           @Param("mynage")int age )

  <2>dao.xml

   <select id="selectMultiParam"   resultType=“com.entity.Student”>

    select id,name,email from student  where name=#{myname} or age=#{myage}

</select>      

方式二:对象传参 ,将要传入的参数封装成一个对象

 <1>将要传入的参数封装成一个java对象(类),对象属性是要传入的参数

public class QueryParam{

private String myName;

private String myAge;

}

   <2> dao

   List<Student> selectMultiParam(QueryParam param

   <3>dao.xml

<select id="selectMultiParam"  resultType=“com.entity.Student”>

    select id,name,email from student  where name=#{myname} or age=#{myage}

</select>    

(3)占位符#和$

   #特点:

  • #使用?在sql语句种做占位的,使用PrepareStatement执行sql,效率高
  • #能够避免sql注入,更安全

   $特点:

  • $采用字符串连接方式,使用Statement对象执行sql,效率低
  • $有sql注入风险
  • $可替换表名或列名

3、结果处理

   (1) resultType

<select id="selectMultiParam"  resultType=“com.entity.Student”>

</select>    

  (2)resultMap

  •   给指定的属性赋值
  •   解决数据库列名和实体类属性名不同

         如,表中列名为name  属性名为stuname

<1>自定义表类不匹配的类--resultMap标签,并定义列和属性的关系,如列id,类属性sid

<resultMap id="myStudentMap"  resultType=“com.entity.Student”>

      <id column=" id" property=“sid”>

      <result column="name" property=“sname”>

      <result column="age" property=“sage”>

</resultMap >    

<2>映射.

<select id="selectMultiParam"  resultMap=“myStudentMap”>

</select>    

4、模糊查询

<select id="selectBylike"  resultType=“com.entity.Student”>

    select id,name,email from student  where name like #{myname} 

</select>    

5、控制语句---标签形式

(1)if

<select id="selectStudentif"  resultType=“com.entity.Student”>

    select id,name,email from student  where

     <if test="name!=null and name!=' ' ">

       name= #{myname} 

    </if>

</select>    

(2)where

<select id="selectStudentif"  resultType=“com.entity.Student”>

    select id,name,email from student 

   <where>

     <if test="name!=null and name!=' ' ">

       name= #{myname} 

    </if>

    <where>

</select>    

(3)foreach

dao:

List<Student> selectStudentFor(List<Student> stulist)

 dao.xml

<select id="selectStudentFor"  resultType=“com.entity.Student”>

    select * from student where id in

     <foreach collection"list" item="mystu" open="(" close=")" separator=",">

           #{mystu.myname} 

    </foreach >

</select> 

四、Mybatis缓存

1、一级缓存--SqlSession级别(默认开启)

  • 一级缓存时SqlSession范围的:当同一个SqlSession中执行两次相同的SQL语句时,第一次执行完毕会将结果保存到缓存中,第二次查询直接从缓存中获取
  •  操作数据库时需要创建SqlSession对象,对象中由一个HashMap存储缓存数据
  • 不同SqlSession之间缓存数据区域互不影响
  • 当SqlSession执行DML操作时,Nybatis需将缓存清空--保证数据的有效性

2、二级缓存--Mapper级别(默认关闭)

  • 多个SqlSession使用同一个Mapper的SQL语句操作数据库,得到的数据存在二级缓存的HashMap中
  • 多个SqlSession共用二级缓存,作用域是Mapper中的同一个namespace
  • 不同SqlSession两次执行相同namespace下的SQL语句会将数据保存在二级缓存中,第二次直接从二级缓存中取出数据

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值