目录
1.Resources:mybatis框架中的对象,一个作用读取主配置信息
2.SqlSessionFactoryBuilder:负责创建SqlSessionFactory对象
1.日志的使用
我们打开官方教程,看到可以一下几种日志供我们使用
我们来看这一段话
不少应用服务器(如 Tomcat 和 WebShpere)的类路径中已经包含 Commons Logging。注意,在这种配置环境下,MyBatis 会把 Commons Logging 作为日志工具。这就意味着在诸如 WebSphere 的环境中,由于提供了 Commons Logging 的私有实现,你的 Log4J 配置将被忽略。这个时候你就会感觉很郁闷:看起来 MyBatis 将你的 Log4J 配置忽略掉了(其实是因为在这种配置环境下,MyBatis 使用了 Commons Logging 作为日志实现)。如果你的应用部署在一个类路径已经包含 Commons Logging 的环境中,而你又想使用其它日志实现,你可以通过在 MyBatis 配置文件 mybatis-config.xml 里面添加一项 setting 来选择其它日志实现。
这段话的意思也就是或如果我们使用了类似于Tomcat,WebShpere之类的服务器,那么MyBatis会默认使用这些 服务器自带的Commons Logging作为日志工具。而如果我们还想使用其他日志来进行实现,我们必须在主配置文件中添加一项setting来选择其他日志实现。
格式如下:
<configuration>
<settings>
...
<setting name="logImpl" value="LOG4J"/>
...
</settings>
</configuration>
name代表了我们日志的名称,而value的值是我们选择何种日志实现方式
可选的值有:SLF4J、LOG4J、LOG4J2、JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING、NO_LOGGING
我们一般使用的是LOG4J和STDOUT_LOGGING
结合我们昨天学习的东西,我们去mybatis的主配置文件添加以下代码:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--设置日志-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!--配置数据源:创建Connection对象-->
<dataSource type="POOLED">
<!--driver:驱动的内容-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<!--链接数据库的url-->
<property name="url" value="jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf-8"/>
<!--用户名-->
<property name="username" value="root"/>
<!--密码-->
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--指定其他mapper文件的位置:
指定其他mapper文件目的是找到其他文件的sql语句
-->
<mappers>
<!--
使用mapper的resource属性执行mapper文件的路径
这个路径是从target/classes路径开启的
使用注意:
resource="mapper文件的路径,使用的是 \ 做分隔路径"
一个mapper resource指定一个mapper文件
-->
<mapper resource="com\lu\dao\StudentDao.xml"/>
</mappers>
</configuration>
我们重新来运行代码,执行查询操作
我们可以看到输出的信息比以前更详细了,但出现了几个新的概念。
什么是自动提交?
当你的sql语句执行完毕后,提交事务。数据库更新操作之间保存到数据
什么是手动提交事务?
在你需要提交事务的位置,执行方法,提交事务或者回滚事务
我们下面通过一个添加学生数据的例子,来更清楚的弄懂自动提交和手动提交事务的区别。
2.添加学生数据
既然我们要添加学生数据,我们首先需要在StudentDao结构中定义一个方法
代码如下:
package com.lu.dao;
import com.lu.entity.Student;
public interface StudentDao {
//查询一个学生
Student selectStudentById(Integer id);
//添加学生
//返回值int,表示本次操作影响的数据库的行数
int insertStudent(Student student);
}
然后在StudentDao.xml文件中来写sql语句
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lu.dao.StudentDao">
<select id="selectStudentById" resultType="com.lu.entity.Student">
select id,name,email,age from student where id = #{studentId}
</select>
<!--添加insert-->
<insert id="insertStudent">
insert into student values(1003,"王五","wangwu@qq.com",18)
</insert>
</mapper>
接下来我们来测试,测试代码如下:
@Test
public void testInsertStudent() throws IOException {
String config = "mybatis";
InputStream inputStream = Resources.getResourceAsStream(config);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
String sqlId = "com.lu.dao.StudentDao" + "." + "insertStudent";
int rows = session.insert(sqlId);
System.out.println("使用mybatis添加一个学生,rows = " + rows);
session.close();
}
执行以下:
看控制台我们好像成功了,也返回了rows=1
我们去数据库查看
却没有发现1003王五的数据,这到底是什么回事呢?
我们看划横线的地方,这里关闭了JDBC事务的自动提交
所以原因是mybatis默认执行sql语句是 手动提交事务 的模式,在做insert,update,delete后需要提交事务。
我们再来修改代码
@Test
public void testInsertStudent() throws IOException {
String config = "mybatis";
InputStream inputStream = Resources.getResourceAsStream(config);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
String sqlId = "com.lu.dao.StudentDao" + "." + "insertStudent";
int rows = session.insert(sqlId);
session.commit();
System.out.println("使用mybatis添加一个学生,rows = " + rows);
session.close();
}
再来看控制台的输出:
这里多出来了一行提交JDBC事务,就是我们上面多加的哪一行代码session.commit()
我们再去看数据库,发现数据已经添加上去了
好了,到这里我们这个例子已经成功的搞定了自动提交事务和手动提交事务的区别,那么还有一个问题,就是添加的数据我们是写死的,怎么能够动态的添加的,其实昨天我们已经讲了,就是使用占位符
3.使用占位符
我们来修改StudentDao.xml文件中的insert语句
<!--添加insert
如果传入给mybatis是一个Java对象,使用#{属性名}获取此属性的值
属性值放到 #{} 占位符,mybatis执行此属性对应的getXXX()方法
例如 #{id} 执行的是getId();
-->
<insert id="insertStudent">
insert into student values(#{id},#{name},#{email},#{age})
</insert>
我们来修改测试代码:
@Test
public void testInsertStudent() throws IOException {
String config = "mybatis";
InputStream inputStream = Resources.getResourceAsStream(config);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
String sqlId = "com.lu.dao.StudentDao" + "." + "insertStudent";
Student student = new Student();
student.setId(1004);
student.setName("维桑");
student.setEmail("weisang@qq.com");
student.setAge(24);
int rows = session.insert(sqlId, student);
session.commit();
System.out.println("使用mybatis添加一个学生,rows = " + rows);
session.close();
}
执行程序:
看着应该是成功了,我们去数据库查看数据
插入成功了,这就是占位符的使用
下面我们来回顾以下,具体的讲解以下MyBatis的一些重要对象
4.MyBatis的一些重要对象
1.Resources:mybatis框架中的对象,一个作用读取主配置信息
InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
2.SqlSessionFactoryBuilder:负责创建SqlSessionFactory对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
3.SqlSessionFactory:重要对象
SqlSessionFactory是一个重量级对象:创建此对象需要使用更多的资源和时间。在项目中有一个就行了。
SqlSessionFactory接口:作用是SqlSession的工厂,就是创建SqlSession对象
DefaultSqlSessionFactory实现类
public class DefaultSqlSessionFactory implements SqlSessionFactory {}
SqlSessionFactory接口中的方法
openSession():获取一个默认的SqlSession对象,默认是需要手工提交事务的
openSession(boolean):boolean参数表示是否自动提交事务
true:创建一个自动提交事务的SqlSession
false:等同于没有参数的openSession()
那么这时候我们就可以设置成自动提交事务,就不要在代码中写session.commit()了
修改代码:
@Test
public void testAutoCommitInsertStudent() throws IOException {
String config = "mybatis";
InputStream inputStream = Resources.getResourceAsStream(config);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession(true);
String sqlId = "com.lu.dao.StudentDao" + "." + "insertStudent";
Student student = new Student();
student.setId(1005);
student.setName("卢桑");
student.setEmail("lusang@qq.com");
student.setAge(22);
int rows = session.insert(sqlId, student);
System.out.println("使用mybatis添加一个学生,rows = " + rows);
session.close();
}
重新执行:
我们去数据库中查看:
数据插入成功
4.SqlSession对象
SqlSession对象是通过SqlSessionFactory获取的。SqlSession本身是接口,它的实现类是
public class DefaultSqlSession implements SqlSession { }
SqlSession提供了大量的执行sql的方法
selectOne():执行select语句,得到最多一条记录,多余1行是错误
selectList():执行select语句,返回多行数据
selectMap():执行select语句,得到一个Map集合
insert():执行insert语句
update():执行update语句
delete():执行delete语句
commit():提交事务
rollback():回滚事务
注意SqlSession对象不是线程安全的,
使用的步骤:
- 确保SqlSession的对象在方法的内部,执行sql语句之前,先获取SqlSession对象
- 调用SqlSession的方法,执行sql语句
- 关闭SqlSession对象,执行SqlSession.close()