SSM框架详细讲解(一)Mybatis基础到深入(一)-初入mybatis

Mybatis系列文章目录

一:Mybatis基础到深入(一)-mybatis的初步使用
二:Mybatis基础到深入(二)-mybatis配置文件的详细使用
三:Mybatis基础到深入(三)-mybatis的注解开发



我们在学习任何一个新的框架时,都要问问自己为什么我们会用这样的技术,这样的模板,这样的框架,它比我们传统写法的出入在哪,有哪些好处

一:原始JDBC存在的问题

Class.forName("com.mysql.jdbc.Driver"); 
Connection connection =  DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root"); 
String sql = "insert into tb_user(username,password) values(?,?)";  
PreparedStatement statement = connection.prepareStatement(sql); 
statement.setString(1,"zhangsan");  statement.setString(2,"zhangsan"); 
statement.executeUpdate();  connection.close();  statement.close(); 

原始jdbc开发存在的问题如下:

  1. 数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能
  2. sql 语句在代码中硬编码,造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要 改变java代码。
  3. 查询操作时,需要手动将结果集中的数据手动封装到实体中。插入操作时,需要手动将实体 的数据设置到sql语句的占位符位置 。

应对上述问题给出的解决方案:

  1. 使用数据库连接池初始化连接资源
  2. 将sql语句抽取到xml配置文件中
  3. 使用反射、内省等底层技术,自动将实体与表进行属性与字段的自动映射

二:MyBatis基本概念

2.1简介:
  1. mybatis是一个优秀的基于 java 的持久层框架,它内部封装了 jdbc,使开发者只需要关注 sql 语句本身,而不需要花费精力去处理加载驱动、创建连接、创建statement 等繁杂的过 程。
  2. mybatis通过xml配置或注解的方式将要执行的各种 statement 配置起来,并通过java 对象 和 statement 中sql 的动态参数进行映射生成最终执行的 sql 语句.
  3. 最后mybatis框架执行sql并将结果映射为java对象并返回。采用ORM思想解决了实体和数 据库映射的问题,对jdbc 进行了封装,屏蔽了jdbc api 底层访问细节,使我们不用与jdbc api 打交道,就可以完成对数据库的持久化操作。
2.2结构:

在这里插入图片描述

  • SqlMapConfig.xml, 此文件作为mybatis的核心配置文件,配置了mybatis的运行环境等信 息。

  • Mapper.xml, 即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在 SqlMapConfig.xml中加载。

  • SqlSessionFactory, 通过mybatis配置信息创建,即会话工厂对象

  • SqlSession, 由SqlSessionFactory获取,用来操作数据库。

  • Executor, mybatis底层自定的接口,用来操作数据库。

  • MappedStatement, mybatis的底层封装对象,它包装了mybatis配置信息及sql映射信息 等。mapper.xml文件中一个sql对应一个MappedStatement对象。

  • 输入映射,包括HashMap、基本类型、pojo,Executor通过MappedStatement在执行sql 前将输入的java对象映射至sql中,输入映射相当于JDBC编程中对preparedStatement设置 参数。

  • 输出映射,包括HashMap、基本类型、pojo,Executor通过MappedStatement在执行sql 后将输出结果映射至java对象中,输出映射相当于JDBC编程中对结果的解析处理过程。

三:MyBatis资源下载

MyBatis资源下载
在这里插入图片描述

四:Mybatis入门程序

需求:查询所有记录
a.加入jar包
在这里插入图片描述

b.创建mapper映射文件

<?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="test">
<!‐‐配置查询所有‐‐>
<select id="selectUserList" resultType="com.qzw.bean.User">
select * from user
</select>
</mapper>

namespace :命名空间,用于隔离sql语句,后面会讲另一层非常重要的作用。

c.创建SqlMapConfig.xml文件,并加载mapper映射文件

<?xml version="1.0" encoding="UTF‐8" ?>
<!DOCTYPE configuration
PUBLIC "‐//mybatis.org//DTD Config 3.0//EN"
"http://www.mybatis.org/dtd/mybatis‐3‐config.dtd">
<configuration>
<!‐‐ 和spring整合后 environments配置将废除‐‐>
<environments default="development">
<environment id="development">
<!‐‐ 使用jdbc事务管理‐‐>
<transactionManager type="JDBC" />
<!‐‐ 数据库连接池‐‐>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test?
serverTimezone=UTC" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper01.xml"></mapper>
</mappers>
</configuration>

d.代码测试

@Override
public List<User> selectUserList() throws Exception {
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("sqlMapperConfig.xml")
);
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> userList = sqlSession.selectList("selectUserList");
sqlSession.close();
return userList;
}

五:mapper映射文件说明

在这里插入图片描述

六:根据id查询用户信息

A.映射文件:

  • 映射文件:
    在mapper01.xml中添加
<select id="selectUserById" parameterType="int" resultType="cn.qzw.bean.User">
select * from user where id = #{id}
</select>

B.测试代码

七:根据用户名查询用户信息(模糊查询)

A.方式一:使用#{username}

  • a.配置mapper01.xml
<select id="selectUserListLikeName1" parameterType="String"
resultType="com.qzw.bean.User">
select * from user where username like #{username}
</select>
<select id="selectUserListLikeName2" parameterType="java.lang.String"
resultType="com.qzw.bean.User">
select * from user where username like "%"#{username}"%"
</select>
  • b.dao层
@Override
public List<User> selectUserListLikeName1(String name) throws Exception {
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("SqlMapConfig.xml"));
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> userList =
sqlSession.selectList("selectUserListLikeName1","%"+name+"%");
sqlSession.close();
return userList;
}
@Override
public List<User> selectUserListLikeName2(String name) throws Exception {
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("SqlMapConfig.xml"));
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> userList = sqlSession.selectList("selectUserListLikeName2",name);
sqlSession.close();
return userList;
}

B.方式二:使用${value}

  • a.配置mapper01.xml
<select id="selectUserListByName3"parameterType="java.lang.String"
resultType="com.qzw.bean.User">
select * from user where username like '%${username}%'
</select>
  • b.dao层
@Override
public List<User> selectUserListLikeName3(String name) throws Exception {
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("SqlMapConfig.xml"));
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> userList = sqlSession.selectList("selectUserListLikeName3",name);
sqlSession.close();
return userList;
}
#{}和${}的区别:

#{}可以防止sql注入漏洞
${}不可以防止sql注入漏洞
什么是sql注入:简单来说,可以在你原来的sql基础上,插入一些sql语句,这就导致了你的sql不安全,可以被修改从而被别人获取你不想被泄露的数据

八:新增

  • mapper映射文件:
<insert id="insertUser" parameterType="cn.qzw.bean.User">
insert into user(id,username) values(#{id},#{username})
</insert>
  • dao层代码
@Override
public void addUser(User user) throws Exception {
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("SqlMapConfig.xml"));
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.insert("addUser",user);
sqlSession.commit();
sqlSession.close();
}
  • 注意事项:
    需要提交操作

insert实现主键返回

  • 主键返回

自增主键返回

  • 在insert标签中加入selectKey标签
<insert id="addUser" parameterType="com.qzw.bean.User">
<selectKey keyProperty="id" order="AFTER" resultType="long" >
select last_insert_id();
</selectKey>
insert into user(username,password) values(#{username},#{password});
</insert>
  • 属性介绍:

keyProperty:返回的主键存储在pojo中的哪个属性
order:selectKey的执行顺序,是相对与insert语句来说,由于mysql的自增原理执行完
insert语句之后才将主键生成,所以这里selectKey的执行顺序为after resultType:返回的主键是什么类型

  • 测试代码:
UserDao userDao = new UserDao();
User user = new User(1, "张三", "张三");
long id = user.getId();
userDao.addUser(user);
id = user.getId();

十:删除用户

  • mapper映射文件
<delete id="deleteUserById" parameterType="int" >
delete from tb_user where id = #{id}
</delete>
  • dao层代码
public void deleteUserById(int id) throws Exception {
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("SqlMapConfig.xml"));
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.delete("deleteUserById",id);
sqlSession.commit();
sqlSession.close();
}
  • 注意事项
    需要提交操作

十一:修改用户

  • mapper映射文件
<update id="updateUser" parameterType="com.qzw.bean.User">
update tb_user set username = #{username} ,password = #{password} where id = #
{id}
</update>
  • dao层代码
- public void updateUser(User user) throws Exception {
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("SqlMapConfig.xml"));
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.update("updateUser",user);
sqlSession.commit();
sqlSession.close();
}

十二:核心API介绍说明

  • SqlSessionFactoryBuilder
    SqlSessionFactoryBuilder用于创建SqlSessionFacoty,SqlSessionFacoty一旦创建完成就
    不需要SqlSessionFactoryBuilder了,因此SqlSessionFactoryBuilder可以是匿名对象,可以
    及时回收.
  • SqlSessionFactory
    SqlSessionFactory是一个接口,接口中定义了openSession的不同重载方法,
    SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常
    以单例模式管理SqlSessionFactory。
  • SqlSession
    SqlSession是一个面向用户的接口,每个数据库操作都应该有它自己的SqlSession实例。
    SqlSession的实例不能共享使用,它也是线程不安全的。因此最佳的范围是请求或方法中。
    绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。

十三:原始dao开发方法

  • 概述
    使用Mybatis操作数据库,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法。
  • dao层代码
public class UserDaoImpl implements UserDao {
private SqlSessionFactory sqlSessionFactory ;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public List<User> selectUserList() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> userList = sqlSession.selectList("selectUserList");
return userList;
}
@Override
public void updateUser(User user) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.update("updateUser",user);
sqlSession.commit();
sqlSession.close();
}
}
  • 测试代码
public class DaoTest {
UserDao userDao;
@Before
public void init() throws IOException {
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("SqlMapConfig.xml"));
userDao = new UserDaoImpl(sqlSessionFactory);
}
@Test
public void updateUser() throws Exception {
userDao.updateUser(new User(1,"root","root"));
}
}
原始dao方式存在的问题 :

SqlSession操作方法需要指定statement的id,配置文件和实现类的耦合度太高了,
statement的id改变,实现类代码也要改变 原始Dao开发方法需要程序员编写Dao接口和Dao实现类,存在大量的dao接口实现类

十四:Mapper动态代理方式

  • A.映射文件
    修改namespace的值为接口全类名。
  • B.dao接口
    接口中方法的名称和映射文件中定义的statement的id相同
    接口中方法的输入参数类型和映射文件中定义的statement的parameterType相同
    接口方法的返回值类型和映射文件中定义的statement的resultType相同
  • C.在SqlMapConfig.xml中加载映射文件
  • D.代码测试
SqlSessionFactory sessionFactory = new
SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("SqlMapConfig.xml"));
SqlSession session = sessionFactory.openSession();
IUserDao userDao = session.getMapper(IUserDao.class);
List<User> users = userDao.selectUserList();
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值