1.新建Java project
2.导入jar包
选中jar包 右键Build Path
3.创建实体类
无参构造方法快速写法 Alt+Shift+s +c
有参构造方法快速写法 Alt+Shift+s +o
getter/setter快速写法 Alt+Shift+s +r
Override toString()快速写法 Alt+Shift+s +s
if else Alt+Shift+z + 3 选中
多行注释 Alt+Shift+j 选中方法名
注释 Ctrl+Shift+/ 选中的算是中文注释
其中 private 后面的是成员变量 而 属性则是去掉get 或者 set 后 第一个字母小写的 就是属性
4.建表
5.配置主配置文件
1 <?xml version="1.0" encoding="UTF-8"?>
2 "http://mybatis.org/dtd/mybatis-3-config.dtd">
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
6.映射文件
1 <?xml version="1.0" encoding="UTF-8"?>
2 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5
6
7 insert into student(name,age,score) value(#{name},#{age},#{score})8
9
7.dao 和 dao的实现类
dao
1 public interfaceIStudentDao {2 voidinsertStu(Student student);3 }
dao 的实现类
1 public class IStudentImpl implementsIStudentDao {2
3 privateSqlSession sqlSession;4
5 @Override6 public voidinsertStu(Student student) {7 InputStream inputStream;8 try{9 //1.加载主配置文件
10 inputStream = Resources.getResourceAsStream("mybatis.xml");11 //使用SqlSessionFactoryBuilder 创建 SqlSessionFactory 由Factory 获取SqlSession 因为SqlSession可以增删改查12 //2.创建SqlSessionFactory对象
13 SqlSessionFactory sessionFactory = newSqlSessionFactoryBuilder().build(inputStream );14 //3.创建SqlSession对象
15 sqlSession =sessionFactory.openSession();16 //4.相关操作
17 sqlSession.insert("insertStudent", student);18 //不写提交的话 会分配id但是不会插入到数据库 所以有提交的话 就会跳一个id
19 sqlSession.commit();20 } catch(IOException e) {21 //TODO Auto-generated catch block
22 e.printStackTrace();23 }finally{24 if(sqlSession != null){25 //用了close() 就不需要事务的回滚
26 sqlSession.close();27 }28 }29
30
31 }32
33 }
测试类
public classMyTest {privateIStudentDao dao;
@Beforepublic voidbefore(){
dao= newIStudentImpl();
}
@Testpublic voidtestInsert(){
Student student= new Student("张三",23,93.5);
dao.insertStu(student);
}
}
可能会报错 java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing 因为4.11以上版本不在包含hamcrest 所以我换成了3.8.1版本的jar包就可以了
MyBatisUtils
1 public classMyBatisUtils {2
3 private staticSqlSessionFactory sqlSessionFactory;4
5 /**
6 * SqlSessionFactory 是重量级的 但是是线程安全的 因为没有可修改的属性 所以把它做成单实例的比较好if7 * sqlSessionFactory 变成成员变量就不用赋初值了8 *@return
9 */
10 public staticSqlSession getSqlSession(){11 InputStream is;12 try{13 is = Resources.getResourceAsStream("mybatis.xml");14 if(sqlSessionFactory == null){15 sqlSessionFactory = newSqlSessionFactoryBuilder().build(is);16 }17 returnsqlSessionFactory.openSession();18 } catch(IOException e) {19 e.printStackTrace();20 }21 return null;22 }23 }
改造实现类 IStudentImpl
1 public class IStudentImpl implementsIStudentDao {2
3 privateSqlSession sqlSession;4
5 @Override6 public voidinsertStu(Student student) {7 8 try{9 sqlSession =MyBatisUtils.getSqlSession();10
11 sqlSession.insert("insertStudent", student);12
13 sqlSession.commit();14 } finally{15 if(sqlSession != null){16 //用了close() 就不需要事务的回滚
17 sqlSession.close();18 }19 }20 }21
22 }
从属性文件读取DB连接四要素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
jdbc_mysql.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/test17182
jdbc.username=root
jdbc.password=123456
接下去的是源码阅读
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
8.问题及源码阅读
输入流的关闭
SqlSession的创建(成员变量 赋初值)
1. 一般使用的是无参的方法
configuration:是配置文件mybatis.xml
TransactionFactory: 事务工厂我们写的是jdbc
2.接着看DefaultSqlSession
主要功能:赋初值
dirty :内存里的数据和数据库里的数据 不一样就是true的
增删改的执行(update 方法)
增删改 底层都是update方法
SqlSession的提交
autoCommit 和 dirty都是true (快捷键 alt + ← 或 alt + → 进入方法或回去)
因为isCommitOrRollbackRequired方法返回的是true 所以 required 就是 true所以是事务的提交了
SqlSession的关闭
因为刚刚提交过 所以根据上述的commit()方法 dirty 是 false 并且 openSession方法用的是无参的 所以autoCommit 是 false 且 force 是false 返回值就是false
事务不空 关闭事务
结论:只要没有commit 就会发生回滚
就是之前提到的没写commit 数据库的id被分配出去了,写了commit 数据库里就能插入了
所以主要原因在dirty 执行commit后 会把insert后的dirty设置为false ; 而没有commit的话 只有insert 内存中的数据和数据库中的不一致 dirty就是true了
导致rollback里传进来的就是true 执行了transaction.rollback