一、MyBatis优缺点、使用场合、作用流程
MyBatis优缺点:
一、MyBatis优点:
1. 与JDBC相比,减少了50%以上的代码量。
2. 灵活,SQL写在XML里,降低耦合度,便于统一管理和优化,可重用。
3. 提供XML标签,支持编写动态SQL语句(XML中使用if, else)。
4. 提供映射标签,支持对象与数据库的ORM字段关系映射(在XML中配置映射关系,也可以使用注解)。
二、MyBatis缺点:
1. SQL语句的编写工作量较大。
2. SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
MyBatis框架适用场合:
1.MyBatis专注于SQL本身,是一个足够灵活的DAO层解决方案。
2.对性能的要求很高,或者需求变化较多的项目,如互联网项目,MyBatis将是不错的选择。
MaBatis作用流程:
1、 mybatis配置
1)SqIMapConfig.xmI,此文件作为 mybatis的全局配置文件,配置了mybatis的运行环境等信息。
2)mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqIMapConfig.xml中加载。
2、 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
3、 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
4、 mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个 一个是基本执行器、一个是缓存执行器。
5、 Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个刘对应一个Mapped Statement对象,sql的id即是Mapped statement的id
6、 Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、 pojo ' Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
7、 Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、 pojo Executor通过Mapped Statement在执行sql后将输出结果映射至Java 对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。
MyBatis架构图
二、MaBatis知识点
1)#{} 和 ${}
#{}表示一个占位符号,
#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。
#{}可以有效防止sql注入。#{}可以接收简单类型值或pojo属性值。
${}表示拼接sql串,
$ {}可以将parameterType传入的内容拼接在sql中且不进行jdbc类型转换,
$ {}可以接收简单类型值或pojo属性值,如果parameterType 传输单个简单类型值,${}括号中只能是value
2)parameterType和resultType
parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sq |中。
resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为 resultType指定类型的对象。
如果有多条数据,则分别进行映射,并把对象放到容器List中
3)SqISessionFactoryBuiIder
1.SqlSessionFactoryBuiIder用于创建SqlSessionFacoty,。
2.SqlSessionFacoty一旦创建完成就不需要SqISessionFactoryBuiIder了。
3.因为SqISession是通过 SqlSessionFactory创建的。所以可以将SqlSessionFactoryBuilder当成一个工具类使用。
4.最佳使用范围是方法范围即方法体内局部变量。
4)SqISessionFactory
1)SqlSessionFactory是一个接口,接口中定义了opensession的不同重载方法,
2)SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory
5)SqlSession
1)SqlSession是一个面向用户的接口,sqlSession中定义了数据库操作方法。
2)每个线程都有自己的SqlSession实例。SqlSession的实例不能共享使用,线程不安全。
最佳范围: 请求或方法范围。绝对不能将 SqlSession实例的引用放在一个类的静态字段或实例字段中
三者关系及作用:
1.SqlSession中封装了对数据库的操作,如:查询、插入、更新、删除等。
2.SqlSession通过SqlSessionFactory创建。
3.SqlSessionFactory是通过SqlSessionFactoryBuilder进行创建。
三、MyBatis入门
步骤:
1. 创建java工程。导入依赖jar包
2. 创建源文件夹。命名为config
3. 在config文件中,配置SqlMapConfig.xml(核心配置文件)
4. 在config文件中,配置log4j.properties(日志文件)
5. 复制pojo到工程目录下(类似于JavaBean)
6. 配置sql查询的映射文件
7. 在SqlMapConfig中配置加载映射文件
动态代理dao开发规则
1. namespace必需是接口的全路径名
2. 接口方法名与映射文件的sql id一致
3. 接口的输入参数必需与映射文件的parameterType类型一致
4. 接口的返回类型必须与映射文件的resultType类型一致
动态代理dao开发步骤
1. 创建UserMapper.xml映射文件
2. 创建UserMapper接口
3. 加载UserMapper.xml
四、代码示例
SqlMapConfig.xml
<?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>
<!-- 加载外部配置文件 -->
<properties resource="jdbc.properties"></properties>
<!-- 别名配置 -->
<typeAliases>
<!-- 单个别名定义 -->
<typeAlias type="mybatis.pojo.User" alias="User"/>
<!-- 按包批量定义别名 别名为类名 -->
<!-- <package name="mybatis.pojo"/> -->
</typeAliases>
<!-- 和spring整合后 environments配置将废除 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!-- 加载配置文件 -->
<mappers>
<!-- 根据xml路径加载映射文件 -->
<!-- <mapper resource="mybatisMapper/user.xml"/> -->
<!-- 根据类路径加载映射文件 -->
<mapper class="mybatis.dao.UserDao"/>
</mappers>
</configuration>
Mapper.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">
<!--
namespace命名空间:用来隔离sql
在动态代理开发DAO中: namespace必须和Mapper接口类路径一致
-->
<mapper namespace="mybatis.dao.UserDao">
<!--
根据id查询 设置查询参数为int类型 返回值为User类
-->
<select id="queryUserById" parameterType="int" resultType="mybatis.pojo.User">
SELECT
*
FROM
`user`
where `id` = #{id}
</select>
<!--
模糊查询 : 若传参为简单类型参数,则${}中必须为value
-->
<select id="queryUserByUsername" parameterType="String" resultType="User">
SELECT *
FROM `user`
where `username` like '%${value}%'
</select>
<!-- <select id="getUserByUsername2" parameterType="String" resultType="mybatis.pojo.User">
SELECT *
FROM `user`
where `username` like #{username}
</select> -->
<!-- 插入 -->
<insert id="insertUser" parameterType="User" >
<!-- selectKey:用于配置主键返回
keyProperty:要绑定的pojo属性
resultType:属性数据类型
order:指定什么时候执行,AFTER之后
-->
<selectKey keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO `user` (
`username`,
`birthday`,
`sex`,
`address`
)
VALUES
(
#{username},
#{birthday},
#{sex},
#{address}
)
</insert>
<!-- 修改 -->
<update id="updateUser" parameterType="User">
UPDATE
`user`
SET
`username` = #{username},
`birthday` = #{birthday},
`sex` = #{sex},
`address` = #{address}
WHERE `id` = #{id} ;
</update>
<!-- 删除 -->
<delete id="deleteUser" parameterType="int">
DELETE
FROM
`user`
WHERE `id` = #{id} ;
</delete>
</mapper>
UserDaoCRUD Test .java
public class UserDaoTest {
@Test
public void testQueryUserById() {
//得到sqlSession
SqlSession sqlSession = Utils.getSqlSessionFactory().openSession();
//在底层生成接口的代理实现类
UserDao userDao = sqlSession.getMapper(UserDao.class);
//执行查询
User user = userDao.queryUserById(30);
System.out.println(user);
sqlSession.close();
}
@Test
public void testQueryUserByUsername() {
//得到sqlSession
SqlSession sqlSession = Utils.getSqlSessionFactory().openSession();
//在底层生成接口的代理实现类
UserDao userDao = sqlSession.getMapper(UserDao.class);
//执行查询
List<User> list = userDao.queryUserByUsername("李");
for (User user : list) {
System.out.println(user);
}
sqlSession.close();
}
@Test
public void testInsertUser() {
//得到sqlSession
SqlSession sqlSession = Utils.getSqlSessionFactory().openSession(true);
//在底层生成接口的代理实现类
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user = new User();
user.setUsername("李5");
user.setSex("1");
user.setBirthday(new Date());
user.setAddress("西安");
//执行查询
userDao.insertUser(user);
System.out.println(user);
sqlSession.close();
}
@Test
public void testDeleteUser() {
//得到sqlSession
SqlSession sqlSession = Utils.getSqlSessionFactory().openSession(true);
//在底层生成接口的代理实现类
UserDao userDao = sqlSession.getMapper(UserDao.class);
//执行
userDao.deleteUser(40);
sqlSession.close();
}
@Test
public void testUpdateUser() {
//得到sqlSession
SqlSession sqlSession = Utils.getSqlSessionFactory().openSession(true);
//在底层生成接口的代理实现类
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user = new User();
user.setId(27);
user.setUsername("李1");
user.setSex("1");
user.setBirthday(new Date());
user.setAddress("西安");
//执行查询
userDao.updateUser(user);
sqlSession.close();
}
}
factory抽取工具类
/**
* SqlSessionFactory工具类
* @author 一万年行不行
*/
public class Utils {
/**
* 单例SqlSessionFactory
*/
private static SqlSessionFactory sqlSessionFactory;
static {
// 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sfb = new SqlSessionFactoryBuilder();
try {
// 查找配置文件创建输入流
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 加载配置文件,创建SqlSessionFactory对象
sqlSessionFactory = sfb.build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取单例SqlSessionFactory
* @return
*/
public static SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
}
Interface UserDao
/**
* 接口
* @author 一万年行不行
*
*/
public interface UserDao {
/**
* 根据id查询user
* @param id
* @return
*/
User queryUserById(int id);
/**
* 模糊查询 根据用户名
* @param username
* @return
*/
List<User> queryUserByUsername(String username);
/**
* 增添用户
* @param user
*/
void insertUser(User user);
/**
* 删除用户
* @param i
*/
void deleteUser(int i);
/**
* 修改用户
* @param user
*/
void updateUser(User user);
}
log4j.properties
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# 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
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=****