抄自:快速入门MyBatis第一天(共两天) - 知乎,只做圈画重点,添加一些自己的实现截图。
1. MyBatis概述
1.1. MyBatis是什么
MyBatis是一个持久层(DAO)框架,本质上是JDBC的一次封装。
1.2. MyBatis的作用
MyBatis是一个持久层框架,那么作用当然就是操作数据库(增删改查CRUD)。
1.3. 为什么需要学习MyBatis
MyBatis的理念:让开发者编写10%的代码(相对于原生JDBC)就可以实现数据库的操作。
解决方案:持久层(DAO)的零实现,所谓的零实现,就是不用写实现类代码,直接使用接口就可以操作数据库。
MyBatis的定义,提高开发的效率、程序的健壮性、可扩展性、优雅性!!!真的写很少代码就可以增删改查。
在同等实现效果下,显著减少技术代码的编写,从而可以让开发人员关注业务逻辑代码的编写。
借用jQuery的理念就是:写的更少,做的更多(write less do more)。
1.4. MyBatis的作用
MyBatis框架能够让我们以最少的代码实现操作数据库。从而提高开发的效率!!!
--如何将代码减少呢?
【1】持久层的零实现 (不需要写实现类,底层通过动态代理实现)。
【2】无需编写结果集ResultSet和javaBean属性之间的映射关系的java代码,通过xml配置文件配置即可。
配置文件的作用:记载对象和对象之间的映射关系或者依赖关系,在程序运行过程中动态读取配置文件中的信息完成特定的程序应用。
1.5. MyBatis配置流程图
Resources:资源类,用于读取总配置文件。
SqlSessionFactoryBuilder:会话工厂构造类,通过读取的总配置文件构建会话工厂。
SqlSessionFactory:会话工厂。
SqlSession:会话操作对象,用于生成对应模块接口的代理对象(0实现)。
1.6. MyBatis的个人理解
MyBatis是一个持久层的框架,所谓的框架,无非就是一群牛逼的人封装了某一个java原生功能,而MyBatis就是对原生JDBC的一次封装,相对于我们自己的封装,MyBatis会更加的强大、健壮、高效。
MyBatis的底层实现就是JDBC,我们封装过功能都清楚,封装无非就是将重复一样的代码在一个方法中写死,而那些随着业务场景不同的代码,则通过形参进行控制。封装过后,我们只需将变化的形参传递给封装的方法,那么我们就可以得到既定的返回值。封装把我们从编写繁琐无味的重复性代码中解放出来,从而使得我们可以更加关注业务逻辑代码的编写,进而降低开发成本,提高开发效率。
所以学习MyBatis框架,首先学习如何使用Mybatis封装好的方法(功能),清楚MyBatis在开发中的使用流程,在熟练使用MyBatis进行业务开发之后,我们可以尝试的去学习Mybatis的源码,使得我们能更加灵活使用MyBatis进行开发。
MyBatis在项目中的使用流程:
【1】导包(MyBatis和数据库驱动的jar包)。
【2】编写mybatis-config.xml和xxxMapper.xml配置文件。
注意:
[1]通常一个项目对应一个数据库实例、而一个数据库实例对应一个mybatis-config.xml配置文件,而项目中的一个模块对应一个xxxMapper.xml配置文件)。
[2] xxxMapper.xml配置文件中编写模块DAO层接口中的抽象方法的sql语句。每一个方法的实际sql类型对应一个标签(select、insert、update、delete),这样做只是为了将代码语义化,方便后期代码维护。
【3】借助MyBatis封装好的SqlSessionFactoryBuilder对象的build方法构建一个数据库实例的sql会话对象(sqlSession)。
注意:build方法需要一个字节输入流(InputStream),是mybatis-config.xml总配置文件的字节输入流。
【4】通过sql会话对象的getMapper方法构建某一模块DAO层的代理对象(底层实现是动态代理)。
【5】通过代理对象调用模块DAO层接口中定义的方法。
2. 入门示例
2.1. 配置流程说明
--获得数据库连接
第一步:导入包(任何框架需要的事情)
第二步:创建总配置文件mybatis-config.xml,看官方文档
第三步:创建一个MyBatisUtils工具类,(获得SqlSession对象)
--需求:插入数据到数据库
第四步:创建一个映射接口(如UserMapper)
第五步:创建一个映射文件(如UserMapper.xml)
第六步:在总配置文件中配置映射文件(在mybatis-config.xml配置文件中mappers标签中引入一个mapper标签,resources属性值为的映射文件的路径)
第七步:编写测试插入数据代码(通过UserMapper接口调用UserDao中的方法)。
3. log4j日志框架的配置
3.1. 说明
log4j是一个日志输出框架,就是用于输出日志的。
MyBatis的日志输出是通过log4J输出的。主流框架大部分都是log4j输出的。Spring框架也可以通过log4j输出日志!!
问题:既然log4j功能类似System.out.println(),为什么使用log4j而不直接使用System.out.println()?
答:log4j提供了强大的日志输出的自定义功能。
1. 通过级别输出日志 (调试、信息、警告、错误、致命异常)。
2. 可以指定输出到控制台,以及输出到文件。
3. 可以设置输出的日志格式。
所以学习LOG4J.需要学会自定义配置LOG4J的输出格式以及输出等级。
3.2. 下载路径
Log4j的下载地址:http://logging.apache.org/log4j/1.2/
3.3. 配置步骤
3.3.1. 第一步:导入log4j-1.2.17.jar的包
3.3.2. 第二步:在src下创建一个log4j.properties文件
注意:文件名必须为log4j.properties
# Global logging configuration
log4j.rootLogger=debug, stdout
log4j.logger.org.cjw.mapper=TRACE // 需要修改为自己的包名
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
3.4. 运行效果
4. MyBatis完成CRUD操作
4.1. 单行查询
4.1.1. 映射文件
<select id="selectUserById" resultType="org.cjw.pojo.User">
select * from tb_user where id = #{id}
</select>
4.1.2. 测试方法
@Test
public void testSelectUserById() {
SqlSession session = MyBatisUtil.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.selectUserById(1);
System.out.println(user.getName());
}
4.1.3. 测试结果
4.2. 多行查询
4.2.1. 映射文件
<!-- 多行查询
resultType : 无论是多行查询还是单行查询,返回的结果类型都是对应的JavaBean的类型
-->
<select id="selectAll" resultType="org.cjw.pojo.User">
select * from tb_user
</select>
4.2.2. 测试方法
@Test
public void testSelectAll() {
SqlSession session = MyBatisUtil.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
List<User> users = userMapper.selectAll();
for (User user : users) {
System.out.println(user.getName());
}
}
4.2.3. 测试结果
4.3. 删除操作
4.3.1. 映射文件
<delete id="deleteUserById">
delete from tb_user where id = #{id}
</delete>
4.3.2. 测试方法
@Test
public void testDeleteUserById() {
SqlSession session = MyBatisUtil.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
userMapper.deleteUserById(1);
session.commit();
} catch (Exception e) {
e.printStackTrace();
session.rollback();
} finally {
session.close();
}
}
4.3.3. 测试结果
4.4. 修改操作
4.4.1. 映射文件
<update id="updateUserById" parameterType="org.cjw.pojo.User">
update tb_user set
name = #{name}, age = #{age}, email = #{email}, password = #{password}
where id = #{id}
</update>
4.4.2. 测试方法
@Test
public void testUpdateUserById() {
SqlSession session = MyBatisUtil.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = new User();
user.setId(2L);
user.setName("zhangsan");
user.setEmail("zhangsan@126.com");
user.setPassword("zhangsan123123123");
userMapper.updateUserById(user);
session.commit();
} catch (Exception e) {
e.printStackTrace();
session.rollback();
} finally {
session.close();
}
}
4.4.3. 测试结果
5. ResultMap 手动映射
MyBatis的查询结果集都是自动映射封装的,单行查询将数据库一条数据封装成对应的Java对象。多行查询,先将每一行封装成对象,再将每个对象添加到集合中,最后返回一个List集合对象。
但是:必须保证查询结果集和pojo对象的属性名相同,否则无法自动封装。
问题: 如何解决查询结果集名称和pojo对象属性不同的映射封装?
解决方案:
1. 使用手动映射封装 <resultMap>标签:
column
对应的是数据库的列名或别名;property
对应的是结果集的字段或属性。2. 可以使用MyBatis的驼峰命名法,但是也必须遵循一定规则才行。
<select id="selectUserById" resultMap="user_map">
select id u_id, name u_name, age u_age, email u_email, password u_password from tb_user where id = #{id}
</select>
<resultMap id="user_map" type="User">
<id property="id" column="u_id" />
<result property="name" column="u_name"/>
<result property="age" column="u_age"/>
<result property="email" column="u_email"/>
<result property="password" column="u_password"/>
</resultMap>