MyBatista的API和CURD详解

API(Application Programming Interface),今天我主要谈的是,重量级组件SqlSessionFactory创建过程中的涉及到的几个类的API.首先我们来说一下,线程出现安全问题的条件:

(1)只有单例模式才会出现线程安全的问题

(2)单例对象中含有可修改的属性.

(3)多线程环境(即多个线程共享同一个单例对象)

单例模式的使用场景:

(1)当对象需要频繁的创建和销毁时

(2)对象的创建和销毁过程需要消耗大量的系统资源(CPU和运行内存)

(3)需要将该对象声明成全局的变量

(1)SqlSession接口,该接口的实现类是org.apache.ibatis.sessiondefaults.DefaultSqlSession,该对象时多例的,(一个线程会一个,一个线程简单来说就代表的是一个用户)

(2)SqlSessionFactory接口,该接口的实现类是org.apache.ibatis.sessiondefaults.DefaultSqlSessionFactory,这个对象的作用就是为了创建SQLSession对象,然而SQLSession对象时多例的,每次为一个线程创建一个SQLSession对象,都需要一个SQLSessionFactory对象,但是SQLSessionFactory又是一个重量级组件,并且DefaultSqlSessionFactory类中没有含有可以修改的成员变量,所以SQLSessionFactory可以使用单例模式,它的生命周期和整个应用程序的生命周期一致.代码如下:

//声明底层对象

private static SqlSessionFactory factory;

public static SqlSession getSqlSession() throws IOException {

  
  //获取指定文件的输入流对象
  InputStream is = Resources.getResourceAsStream("mybatis.xml");
  
  if(factory == null) {
   factory = new SqlSessionFactoryBuilder().build(is);
  }
  return factory.openSession();
 
  
 }

(3)SQLSessionFactoryBuilder类,该类的作用就是为了创建SQLSessionFactory对象,由于SQLSessionFactory是单例对象,只需要创建一次,一旦创建完毕,即可被销毁,所以SQLSessionFactory定义为局部变量.

==========================

下面是对一些疑问的总结:

(1)我们在加载主配置文件的IO流为啥没有进行关闭,却没有警告?

InputStream is = Resources.getResourceAsStream("mybatis.xml");因为你,源码中已经对这个IO流进行了关闭,所以不需要我们关闭也同样能够使用,并且没有警告.

(2)factory.openSession()和factory.openSession(false)两个重载方法,虽然参数不同,但是二者的作用是一样的,此时的false 的作用是关闭自动提交的功能,所以如果我们使用Session执行除了select之外的操作命令时,如果我们不手动提交,是不会写入到数据库的,千万注意.

(3)dirty,脏的意思,是一个Boolean类型的值,它的功能是判断内存中的数据和数据库中的数据是否一致,一致值为false,不一致为true,默认的是false.

(4)阅读源码可以发现,增删改查的底层操作都是归于update,只不过是调用相应的参数一致的update方法.

(5)sqlsession 的提交最终会转换成事务的提交.

============================================================================                                                          CURD(create,update,retrive,delete)

CURD,也可以称为CRUD指的是对数据库的增删改查的操作,

 @Test
 public void test02() {
   Student student = new Student("李四",20,98.5);
   //插入前:Student [id=null, name=李四, age=20, score=98.5]
   System.out.println("插入前:"+student);
   dao.insertStudentCatchId(student);
   System.out.println("插入后:"+student);
   //插入后:Student [id=null, name=李四, age=20, score=98.5]
   //分析为什么二者输出的结果数一致的:第一个student的ID为null,这个是肯定的,关键是第二个学生的
   //student的虽然在数据库中生了id,并且插入到了数据库中,但是并没有把数据库中的id值赋值给在内存中
   //的student的id,所以输出的结果是一致的.
 }

为什么数据在插入之后,id的值依旧是空值呢?

数据在插入到数据库之后,数据库会自动的生成相应的ID值,但是数据库没有能力把生成的ID值,赋值给内存中的对象的id属性.

那么我们如何获取新插入的数据的ID值呢?

(1)select @@identity该标签的作用是显示系统变量的值,其中identity表示的就是新插入的数据的ID

(2)select last_insert_id();这个函数的功能也是获取新插入的数据的ID.如果你认为这样写有点丑,我们还可以起别名,例如:select last_insert_id() newID;此时的newId就是别名,

这两种方式在使用的时候,必须要紧跟着insert语句,否则执行的结果是0,并且我们这哎Mapper.xml文件中使用的时候,应该是这样写的:

 <!-- 获取新插入数据的id值 -->
 <insert id="insertStudentCatchId" parameterType="Student">
  insert into student (name,age,score) values(#{name},#{age},#{score})
  <selectKey resultType="int" keyProperty="id">
   <!-- select @@identity -->
   select last_insert_id()
  </selectKey>
 </insert>

注意:<selectKey resultType="查询结果的数据类型" keyProperty="表示的是查询的结果要封装给所传参数的哪一个属性"

order="Before/After"/>order的作用就是,说明insert语句的执行顺序和ID的生成顺序谁先谁后,mysql是限制性插入,然后生成id,oracle是先生成id,在插入,然后执行insert.

注意:在select标签中,我们必须制定查询的结果应该被封装成的类型,使用resultType或者是resultMap来限制,

当我们使用模糊查询是,常用的有三种方法,我们谈谈他们的优缺点

(1)select * from student where name like '%' #{} '%'(推荐使用)

(2)select * from student where name like concat('%' ,#{}, '%')第一种和第二种使用的都是PreparedStatment,预编译处理SQL语句,执行效率比较高.

(3)select * from student where name like '%${}%'这种方法使用的是纯粹的字符串拼接,无法防止Sql注入.有可能数据泄露.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值