MYBATIS01_概述及优缺点快速搭建工程Mybatis的增删改查操作总结
Posted 所得皆惊喜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MYBATIS01_概述及优缺点快速搭建工程Mybatis的增删改查操作总结相关的知识,希望对你有一定的参考价值。
文章目录
①. JDBC的缺点(了解)
- ①. 原始jdbc操作(查询数据)
- ②. 原始jdbc操作(插入数据)
- ③. 原始jdbc开发存在的问题如下:
- 数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能
- sql语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可能较大,sql 变动需要改变java代码
- 查询操作时,需要手动将结果集中的数据手动封装到实体中。插入操作时,需要手动将实体的数据设置到sql语句的占位符位置
- ④. 应对上述问题给出的解决方案:
- 使用数据库连接池初始化连接资源
- 将sql语句抽取到xml配置文件中
- 使用反射、内省等底层技术,自动将实体与表进行属性与字段的自动映射
②. Mybatis概述及优缺点
-
②. Mybatis的优点:
- 与JDBC相比,减少了50%的代码量
- SQL代码从程序中彻底分离出来,可以分离
- 提供XML标签,支持写动态SQL
- 提供映射标签,支持对象与数据库的ORM字段关系映射
- ③. Mybatis的缺点:
- SQL语句编写工作量大,熟练度很高
- 数据库移植性比较差,如果切换数据库的话,SQL语句会有很大的差异
- ④. mybatis的工作原理
- 读取MyBatis配置文件mybatis-config.xml。mybatis-config.xml作为MyBatis的全局配置文件,配置了MyBatis的运行环境等信息,其中主要内容是获取数据库连接
- 加载映射文件Mapper.xml。Mapper.xml文件即SQL映射文件,该文件中配置了操作数据库的SQL语句,需要在mybatis-config.xml中加载才能执行。mybatis-config.xml可以加载多个配置文件,个配置文件对应数据库中的一张表
- 创建会话工厂,通过MyBatis的环境等配置信息构造会话工厂SqlSessionFactory
- 创建SqlSession对象。由会话工厂创建SqlSession对象,该对象中包含了执行SQL的所有方法
- MyBatis底层定义了一个Executor接口来操作数据库,它会根据SqlSession传递的形参的所有方法
- 在Execuotor接口的执行方法中,包含了一个MappedStatement类型的参数,该参数是对映射信息
的封装,用来存储要映射的SQL语句的id、参数等。Mapper.xml文件中的一个SQL对应一个
MappedStatement对象,SQL的id是MappedStatement的id - 输入参数映射。在执行方法时,MapperStatement对象会对用户执行SQL语句的输入参数进行定义(可以定义为Map、List、基本数据类型和POJO类型),Executor执行器会通过MappedStatement对象在执行SQL前,将输入的Java对象映射到SQL语句中。这里对输入参数的映射过程就类似于JDBC编程中对PreparedStatement对象设置参数的过程
- 输出结果映射。在数据库中执行完SQL语句后,MappedStatement对象会对SQL执行输出的结果进行定义(可以定义为Map和List类型、基本类型、POJO类型),Executor执行器会通MappedSt atement对象在执行SQL语句后,将输出结果映射至Java对象中。这种将输出结果映射到Java对象的过程就类似于JDBC编程中对结果的解析处理过程
③. 快速搭建Mybatis工程
- ①. 输入官网网址
- ②. 导入依赖
<!--mybatis坐标-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!--mysql对应版本的连接器驱动
5.7 和 8.0 都用这个驱动
-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
<scope>runtime</scope>
</dependency>
<!--单元测试坐标-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--日志坐标-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.12</version>
</dependency>
- ③. 通过官网写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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm_mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/xiaozhi/mapper/UserMapper.xml"/>
</mappers>
</configuration>
- ④. 编写实体类及MyBatis核心文件
@Data
@ToString
public class User
private Integer id;
private String userName;
<?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.xiaozhi.dao.UserMapper">
<select id="findEmpById" resultType="com.xiaozhi.entity.User" parameterType="Integer">
select * from user where id=#id;
</select>
</mapper>
- ⑤. 编写测试代码
public class EmpTest
/*通过id查询*/
@Test
public void test1()throws Exception
//1.加载配置文件
InputStream inputStream= Resources.getResourceAsStream("sqlMapConfig.xml");
//2.获取工厂对象
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//3.创建会话对象
SqlSession sqlSession=sqlSessionFactory.openSession();
//4.执行操作 namespace+id
User emp =sqlSession.selectOne("com.xiaozhi.dao.UserMapper.findEmpById",1);
System.out.println(emp);
//5.释放资源
sqlSession.close();
- ⑥. 加入日志文件,可以看到打印的SQL log4j.properties
# log4j.properties
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%dABSOLUTE %5p %c1:%L - %m%n
### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=D:/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%dABSOLUTE %5p %c1:%L - %m%n
### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=debug, stdout
④. MyBatis的增删改查操作
- ①. 抽取工具类
public class MybatisUtils
/*私有构造方法*/
private MybatisUtils()
private static SqlSessionFactory sqlSessionFactory;
static
try
//1.加载配置文件
InputStream inputStream= Resources.getResourceAsStream("sqlMapConfig.xml");
//2.给SqlSessionFactory工厂赋值
sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
catch (IOException e)
e.printStackTrace();
//3.获取sqlSession会话对象
public static SqlSession getSqlSession()
return sqlSessionFactory.openSession();
- ②. 查询(查询所有、通过id进行查询、模糊查询)
<?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.xiaozhi.dao.UserMapper">
<!--查询所有的对象-->
<select id="findAll" resultType="com.xiaozhi.entity.User">
select * from user
</select>
<!--根据id进行查询-->
<select id="findUserById" parameterType="Integer" resultType="com.xiaozhi.entity.User">
select * from user where id=#id
</select>
<!--模糊查询-->
<select id="findUserByName" parameterType="String" resultType="com.xiaozhi.entity.User">
select * from user where username like concat('%',#value,'%')
</select>
</mapper>
/*1.查询所有*/
@Test
public void SelectAll()throws Exception
//1.加载配置文件
InputStream inputStream=Resources.getResourceAsStream("sqlMapConfig.xml");
//2.获取SqlSesiionFactory会话工厂
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//3.创建sqlSession会话对象
SqlSession sqlSession=sqlSessionFactory.openSession();
//4.执行操作
List<User> list=sqlSession.selectList("userMapper.findAll");
System.out.println(list);
//5.释放资源
sqlSession.close();
/*2.通过id查询用户信息*/
@Test
public void selectById()throws Exception
//1.加载配置文件
InputStream inputStream=Resources.getResourceAsStream("sqlMapConfig.xml");
//2.创建SqlSessionFactory工厂对象
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//3.创建SqlSession会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//4.执行sql
User user=sqlSession.selectOne("userMapper.findUserById",1);
System.out.println(user);
//5.释放资源
sqlSession.close();
/*3.根据姓名进行模糊查询*/
@Test
public void selectByName()throws Exception
//1.获取会话对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//2.执行sql
List<User> list = sqlSession.selectList("userMapper.findUserByName", "x");
System.out.println(list);
- ③. 添加一个用户
#id:从输入user对象中获取id属性值
<!--插入数据-->
<insert id="insertUser" parameterType="com.xiaozhi.entity.User">
insert into user(id,username)values(#id,#username)
</insert>
/*4.新增一条User记录*/
@Test
public void add()throws Exception
//1.获取会话对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//2.执行sql
//2.1 创建User对象
User user=new User();
user.setId(2);
user.setUsername("xiaozhi");
int row=sqlSession.insert("userMapper.insertUser",user);
System.out.println(row);
//3.进行事务的提交
sqlSession.commit();
//4.释放资源
sqlSession.close();
- ④. 修改一条记录
<!--修改-->
<update id="updateUser" parameterType="com.itheima.domain.User">
update user set username=#username,password=#password where id=#id
</update>
/*5.修改*/
@Test
public void update()throws Exception
//1.获取会话对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//2.执行sql
User user=new User();
user.setId(2);
user.setUsername("xiaoxing");
int result=sqlSession.update("userMapper.updateUser",user);
System.out.println(result);
//3.进行事务的提交
sqlSession.commit();
//4.释放资源
sqlSession.close();
- ⑤. 通过id进行删除
<!--删除-->
<delete id="deleteById" parameterType="java.lang.Integer">
delete from user where id=#id
</delete>
/*6.删除*/
@Test
public void delete()throws Exception
//1.获取会话对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//2.执行sql
int result=sqlSession.delete("userMapper.deleteById",1);
System.out.println(result);
//3.进行事务的提交
sqlSession.commit();
//4.释放资源
sqlSession.close();
⑤. 映射文件总结
-
①. namespace命名空间:作用就是对sql进行分类化管理,理解sql隔离。通常会设置成包名+sql映射文件名注意:使用namespace代理方式开发,namespace有特殊的作用
-
②. 通过select执行数据查询
<select id="" parameterType="" resultType="">
- id:标识映射文件的sql,称为statement的id
(将sql语句封装mappedStatement对象中,所以将id称为statement的id ) - #:表示占位符,相当于?
- #id:其中的id表示接收输入的参数,参数名称是id,如果输入参数是简单类型,#中的参数名可以任意,可以value或其他名称
- parameterType:指定输入参数类型,这里指定int型
- resultType:指定sql输出结果的映射的java类型,resultType表示将单条记录映射成的java对象
<mapper namespace="test">
<select id="findCustomerById" parameterType="Integer"
resultType="com.itcast.mybatis.po.User">
select * from user where id = #id
</select>
</mapper>
- ③. parameterType 和 resultType
- parameterType:在映射文件中通过parameterType指定输入参数的类型
- resultType:在映射文件中通过resultType指定输出结果的类型
- ④. selectOne(statement,parament)和selectList(statement,parament)
- 第一个参数statement:映射文件中statement的id,等于=namaspace+statementId
- 第二个参数parament:指定和映射文件中所匹配paramtype类型的参数(输入参数)
- session.selectOne 结果是与映射文件中所匹配的resultType类型的对象
- ⑤. selectOne和selectList
- selectOne:表示查询出一条记录进行映射。如果使用了selectOne可以实现,那么使用selectLis也可以实现 (List中只有一个对象)
- selectList:表示查询出一个列表(多个列表)进行映射,如果使用了,如果使用selectList要查询多天记录,不能使用selectOne
- ⑥. 模糊查询注意事项
# 第一种情况是字符串的拼接,会引起sql注入,不推荐使用
1.select * from user where username like ‘%$value%’
2.select * from user where username like concat('%',#value,'%')
- ⑦. # 和 $
#:
1. #表示一个占位符号,#接收输入参数,类型可以是简单类型,pojo等
2. 如果接受简单类型,#里面的可以写成value或其他的
3. #接受的是pojo。要通过user.user.username的形式获取
$两万字Mybatis源码剖析
阶段3 1.Mybatis_01.Mybatis课程介绍及环境搭建_05.mybatis环境搭建-前期准备