一、什么是mybatis
mybatis是对jdbc的封装,它让数据库底层操作变的透明。mybatis的操作都是围绕一个sqlSessionFactory实例展开的。mybatis通过配置文件关联到各实体类的Mapper文件,Mapper文件中配置了每个类对数据库所需进行的sql语句映射。在每次与数据库交互时,通过sqlSessionFactory拿到一个sqlSession,再执行sql命令。
二、代码实战(学生管理系统)
1、Maven依赖
SpringBoot整合mybatis:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
依赖分析:
MySQL连接依赖:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope> <!--运行期-->
</dependency>
数据源(druid)依赖:
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.11</version>
</dependency>
2、dao层
代码:
@Mapper
@Repository
public interface StudentDao {
List<StudentDO> findAll();
StudentDO findById(@Param("id") int id);
int save(@Param("stu") StudentDO student);
}
dao层负责进行数据库的行为交互,以上代码给出了查询、写入的接口其中
@Mapper 为mybatis注解,用于标识dao层的接口类
@Repository 为Spring注解,用于标识一个待注册的bean
3、与dao层对应的xml文件规范
StudengMapper.xml:
xml文件中有两个部分组成,一个是头部文件,一个是主体
头部文件:
<?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">
主体:
(1) mapper叫根节点,根节点有个属性是namespace=""、namespace=""、的作用是映射我们mapper的全路径,在以后的使用中会自动映射成我们mapper的实现类
(2) select里面的Id=“”一般和我们StudentDao里面的方法名保持一致
(3) 返回值这里有一个专门的属性叫resultType="java.lang.Integer"
(4) 方法名和返回值都对应之后看有无参数,如果有要加上parameterType=""\
<mapper namespace="com.wzy.studentmanager.dao.StudentDao">
<select id="findAll" resultType="com.wzy.studentmanager.model.StudentDO">
select * from student_table
</select>
<!-- StudentDO findById(int id) -->
<select id="findById" parameterType="int" resultType="com.wzy.studentmanager.model.StudentDO">
select * from student_table where id = #{id}
</select>
</mapper>
4、DB配置类
DB配置类替代了mybatis-config.xml的作用,二者均为配置mybatis的不同方式
整体代码:
@Slf4j
@Configuration
@MapperScan(basePackages = "com.wzy.studentmanager.dao",
sqlSessionFactoryRef = "studentFactory")
public class studentDBconfig {
@Primary
@Bean(name="studentDataSource")
public DataSource studentDataSource() throws Exception {
Properties properties = new Properties();
InputStream is = JdbcUtils.class.getResourceAsStream("/druid.properties");
try {
properties.load(is);
} catch (Exception e) {
log.error("datasource create error : ", e);
}
return DruidDataSourceFactory.createDataSource(properties);
}
@Primary
@Bean(name="studentFactory")
public SqlSessionFactory sqlSessionFactoryBean(@Qualifier("studentDataSource") DataSource dataSource) throws Exception{
SqlSessionFactoryBean sessionFactoryBean=new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource);
sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/*.xml"));
org.apache.ibatis.session.Configuration config = new org.apache.ibatis.session.Configuration();
config.setMapUnderscoreToCamelCase(true);
sessionFactoryBean.setConfiguration(config);
return sessionFactoryBean.getObject();
}
}
@MapperScan注解
@MapperScan(basePackages = "com.wzy.studentmanager.dao",
sqlSessionFactoryRef = "studentFactory")
basePackages指需要扫描的包含mapper接口的包
sqlSessionFactoryRef的官方解释:
/**
* Specifies which {@code SqlSessionFactory} to use in the case that there is more than one in the spring context.
* Usually this is only needed when you have more than one datasource.
*
* @return the bean name of {@code SqlSessionFactory}
*/
说明这个属性是针对包含多个数据源的情况,用于确定特定的SqlSessionFactory
数据源bean注册
@Primary
@Bean(name="studentDataSource")
public DataSource studentDataSource() throws Exception {
Properties properties = new Properties();
InputStream is = JdbcUtils.class.getResourceAsStream("/druid.properties");
try {
// 装载转化为流的properties属性
properties.load(is);
} catch (Exception e) {
log.error("datasource create error : ", e);
}
return DruidDataSourceFactory.createDataSource(properties);
}
这里通过Properties对象读取数据源配置属性,属性具体值放在'druid.properties'
InputStream is = JdbcUtils.class.getResourceAsStream("/druid.properties");
这一行用于读取配置资源
druid.propertie具体代码:
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://81.70.203.113:3306/studentManager?serverTimezone=UTC
username=root
password=Wzy3688389..
initialSize=10
minIdle=1
maxActive=10
maxWait=10000
timeBetweenEvictionRunsMillis=6000
minEvictableIdleTimeMillis=300000
testWhileIdle=true
testOnBorrow=true
testOnReturn=true
poolPreparedStatements=true
maxPoolPreparedStatementPerConnectionSize=20
filters=stat
可以看到是kv形式的文件属性设置
SqlSessionFactory的Bean注册
@Primary
@Bean(name="studentFactory")
public SqlSessionFactory sqlSessionFactoryBean(@Qualifier("studentDataSource") DataSource dataSource) throws Exception{
SqlSessionFactoryBean sessionFactoryBean=new SqlSessionFactoryBean();
// 配置前述的数据源
sessionFactoryBean.setDataSource(dataSource);
// 配置mybatis的xml文件
sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/*.xml"));
// 设置驼峰映射,注意创建org.apache.ibatis.session.Configuration对象
org.apache.ibatis.session.Configuration config = new org.apache.ibatis.session.Configuration();
config.setMapUnderscoreToCamelCase(true);
sessionFactoryBean.setConfiguration(config);
return sessionFactoryBean.getObject();
}
三、餐后甜点:不使用config类注册Bean获取SqlSession对象
一个连接MySQL数据库的sql会话对象sqlSession,需要通过sqlSessionFactor()对象才能创建sqlSession。sqlSessionFactor()需要通过sqlSessionFactor()Builder()来创建出来。
- 先new一个SqlSessionFactoryBuilder(),得到一个返回值builder
- 获取我们的SqlSessionFactory,要用builder.上我们的builder()方法,通过流的形式传一个In的参数。
- 通过Resources.getResourceAsStream(“”)读取我们的主配置文件才能调用我们的依赖信息,在这里抛异常。这里有一个返回值nputStream in(字节流),通过字节流就可以读取
- 这时builder.build(in);得到哟个返回值就是SqlSessionFactory factory。
- 得到SqlSessionFactory factory之后,根据图片的流程就要得到我们的SqlSession。
- factory.openSession()打开我们的Session,就可以得到我们的Session
- 执行sql语句。sqlSession.getMapper(这里的mapper利用的是我们的一个反射机制,机制利用的时我们的一个接口)通过sqlSession.getMapper(PersonMapper.class)调用一个调用方法,得到一个返回值count
- 输出对应的返回值
- 关闭sqlsession
代码:
public class TestMybatis {
@Test
public void testHelloWorld() throws IOException {
//1.通过流的机制获取主配置文件mybatis-config.xml的主要配置信息
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//2.实例化SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3.调用builder对象的builder()方法,获取SqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);
//4.调用factory对象的openSession()方法,获取SqlSession对象
SqlSession sqlSession = factory.openSession();
//5.调用接口的方法
Integer count = sqlSession.getMapper(PersonMapper.class).findCount();
//6.输出对应的返回值count
System.out.println("count:" + count);
//7.关闭 SqlSession
sqlSession.close();
}
}