1 MyBatis
MyBatis是一个基于Java的持久层框架,说到框架,国内Java开发用得比较多的框架有:Spring、SpringMVC、SpringJDBC、SpringDataJPA;还有一些权限框架:shiro、Spring security;还有一些前端比较好用的框架如:easyui、boorstrap等等。
1.1 什么是框架
(1) 框架是一种半成品,它已经帮我们完成了一部分功能,我们只需要在上面进行开发,开发出自己想要的产品。它可以提高开发效率,让开发更加简单。
(2) 框架一般都会提供大量接口、方法或者类,也就是一系列的jar包,需要我们导包才能够使用。
(3) 框架一般是完成一些公共的功能, 具备一些特性:可复用,可扩展,可维护。
(4)它是为了解决某一个领域的问题而产生
1.2 什么是MyBatis
MyBatis是Java的持久化框架,它是ORM(Object Relational Mapping,简称ORM)即对象关系映射的框架。
MyBatis是一个支撑框架,它以映射sql语句ORM方式来进行数据库持久化操作。
1.3 为什么要使用MyBatis
说到为什么要使用MyBatis,那不得不说一说它的优点,下面我用原生jdbc来与MyBatis做对比进行比较。
----JDBC特点:
(1)重复性代码较多,开发工作量较大
(2)封装对象比较麻烦
(3)没有性能控制,如果要提高效率需要自己写缓存,而且还需要配置后才能使用
----MyBatis特点:
(1) mybatis使用已有的连接池管理,避免浪费资源,提高程序可靠性。
(2) mybatis提供插件自动生成DAO层代码,提高编码效率和准确性。
(3) mybatis 提供了一级和二级缓存,提高了程序性能。
(4) mybatis使用动态SQL语句,提高了SQL维护。(此优势是基于XML配置)
(5) mybatis对数据库操作结果进行自动映射
2 MyBatis的使用
这里只是用于实现普通的CRUD功能,不考虑与其他框架集成。
2.1 导包
使用任何框架都离不开一件事,那就是导包。我们要想完成基本CRUD功能需要导入一下jar包,可以在网上搜索下载(我们这里没有创建Maven项目,所以需要手动导包)

在项目下新建一个lib文件夹,将这些jar包拷贝到里面,然后右键lib文件夹选中Add as Library,然后点击OK即导包成功。
2.2 编写配置文件
首先在项目下新建resources文件夹,然后将其变为资源文件夹,右键选中Mark Directory as 然后再选中Resources Root即可。

之后再在配置文件中编写配置文件(MyBatis-Config.xml 、jdbc.properties )。
MyBatis-Config.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>
<!--引入jdbc.propeties文件-->
<properties resource="jdbc.properties" />
<typeAliases>
<package name="cn.itsource.domain"></package>
<package name="cn.itsource.query"></package>
</typeAliases>
<!-- 环境们 (很多环境的意思)
default:默认使用哪一个环境(必需对应一个环境的id)
-->
<environments default="development">
<!--
一个环境 id:为这个环境取唯一一个id名称
-->
<environment id="development">
<!--
事务管理 type:JDBC(支持事务)/MANAGED(什么都不做)
-->
<transactionManager type="JDBC" />
<!-- 数据源, 连接池 type(POOLED):MyBatis自带的连接池 -->
<dataSource type="POOLED">
<!-- 连接数据库的参数 -->
<property name="driver" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!-- 这个mappers代表的是相应的ORM映射文件 -->
<mappers>
<mapper resource="cn/itsource/domain/UserMapper.xml" />
</mappers>
</configuration>
还需要准备jdbc.properties:
jdbc.username=root
jdbc.password=123456
jdbc.url=jdbc:mysql:///mybatis
jdbc.driverClassName=com.mysql.jdbc.Driver
这里的jdbc.username,jdbc.password填自己数据库的登陆信息。不多提。
3 使用MyBatis完成CRUD
新增:
@Override
public void save(User user) throws IOException {
//调用mapper.xml的select方法
Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
//得到SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
//通过sqlSessionFactory得到sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//调用方法 namespace+id
sqlSession.insert("cn.itsource.dao.IUserDao.save", user);
//提交事务
sqlSession.commit();
}
修改:
@Override
public void update(User user) throws IOException {
//事务
//调用mapper.xml的select方法
Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
//得到SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
//通过sqlSessionFactory得到sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//调用方法 namespace+id
sqlSession.update("cn.itsource.dao.IUserDao.update", user);
sqlSession.commit();
}
删除:
@Override
public void delete(Long id) throws IOException {
//事务
//调用mapper.xml的select方法
Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
//得到SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
//通过sqlSessionFactory得到sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//调用方法 namespace+id
sqlSession.delete("cn.itsource.dao.IUserDao.delete", id);
sqlSession.commit();
}
查询一条:
@Override
public User findOne(Long id) throws IOException {
//调用mapper.xml的select方法
Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
//得到SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
//通过sqlSessionFactory得到sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//调用方法 namespace+id
User user = sqlSession.selectOne("cn.itsource.dao.IUserDao.queryOne", id);
return user;
}
查询所有:
@Override
public List<User> queryAll() throws IOException {
//调用mapper.xml的select方法
Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
//得到SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
//通过sqlSessionFactory得到sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//调用方法 namespace+id
List<User> users = sqlSession.selectList("cn.itsource.dao.IUserDao.queryAll");
return users;
}
以上的代码都与UserMapper.xml里面的sql语句对应:
UserMapper.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">
<!--
这个Mapper的主要功能就是写sql
mapper:根
namespace:命令空间 (用来确定唯一) 以前这个是可以不加的,现在必需加
namespace的值,规则的:映射文件XxxMapper.xml所在的包+domain类名+Mapper
-->
<mapper namespace="cn.itsource.domain.UserMapper">
<!--
select : 这里面写查询语句
id:用来确定这条sql语句的唯一
以后我们确定唯一,也就是找sql语句 : namespace +.+ id
例: cn.itsource.mybatis.day1._1_hello.ProductMapper.get
parameterType : 传入的参数类型 long:大Long _long:小long (具体的对应请参见文档)
resultType : 结果类型(第一条数据返回的对象类型) 自己的对象一定是全限定类名
-->
<select id="findAll" resultType="User">
select * from user
</select>
<select id="findOne" parameterType="long" resultType="User">
SELECT * FROM user WHERE id=#{id}
</select>
<insert id="save" parameterType="User" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
INSERT INTO user(name) VALUES(#{name})
</insert>
<update id="update" parameterType="User">
UPDATE user SET name=#{name} WHERE id=#{id}
</update>
<delete id="delete" parameterType="long">
DELETE FROM user WHERE id=#{id}
</delete>
4 抽取工具类
根据上面的CRUD代码,其实可以发现有很多重复的代码,因此我们需要进行抽取。
4.1 工具类的抽取方法
工具类的抽取方法分为:
(1)单例模式:一个类保证只有一个实例
包含懒汉模式、饿汉模式、枚举等。
(2)静态方法
4.2 工具类代码
下面就是用枚举的方法来抽取的工具类:
public enum MyBatisUtils {
INSTANCE;
private static SqlSessionFactory sqlSessionFactory;
static {
Reader reader = null;
try {
reader = Resources.getResourceAsReader("MyBatis-Config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
}
}
public SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
5 MyBatis需要注意的细节
5.1 主键
有时候,我们保存一个数据,需要拿到主键,然后做一些后续操作,就需要在save中的sql加上这三个属性:
<insert id="save" parameterType="cn.itsource.domain.User"
useGeneratedKeys="true" keyColumn="id" keyProperty="id">
insert into t_user(name) values(#{name})
</insert>
这样,我们就能够拿到它的主键了。
5.2 使用log4j让控制台打印日志
有时候我们需要让控制台打印出日志信息,方便排错查看,那么怎么做呢?
第一步:导包,上面已经导过了。
第二步:在resources里写一个配置log4j.properties
具体代码如下:
# 日志输出级别 输出到控制
log4j.rootLogger=ERROR, stdout
#log4j.rootLogger=NONE
log4j.logger.cn.itsource=TRACE
# 输出到控制台的配置信息
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
# 输出到控制台的 格式类
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
OFF(什么都不输出关闭日志信息)<FATAL<ERROR<WARN<INFO<DEBUG<TRACE < ALL (最低级别 什么信息都要输出)
第三步:写测试类进行测试
5.3 MyBatis中的别名
别名就是为类取得小名,以后可以使用小名代表真实名称,在Mybatis中,别名分为内置别名和自定义别名。
5.3.1 内置别名

5.3.2 自定义别名
<typeAliases>
<!-- 单个配置-->
<typeAlias type="cn.itsource.mybatis.a_crud.Dept" alias="Dept" />
<!-- 包的配置:项目,添加了包之后,类名就是别名 -->
<package name="cn.itsource.domain.User" />
</typeAliases>
5.4 #与$的区别
#{OGNL表达式}
MyBatis会把这个表达式使用?(占位符)替换,作为一个sql参数使用:推荐使用这种方式
比如name的值为:
定义SQL: select * from t_user where name = #{name}
最终SQL: select * from t_user where name = ?
¥{OGNL表达式} 的区别
MyBatis会把这个表达式的值替换到sql中,作为sql的组成部分; 把获取到值直接拼接SQL
该方式主要用于程序拼接SQL;
如果sql中使用${OGNL},并且参数的类型是(integer,string…)那么OGNL表达式可以写成任意东西;
${OGNL}表达式的应用场景:不能用在登陆,会出现sql注入;一般用在order by + limit的场景,除了这个情况,其余都推荐用#{OGNL}表达式。
6 批量操作
批量删除
<!--批量删除-->
<delete id="deleteBatch" parameterType="list">
DELETE FROM user WHERE id IN
<foreach collection="list" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
批量新增
<!--批量新增-->
<insert id="saveBatch" parameterType="list">
INSERT INTO user(name) VALUES
<foreach collection="list" item="user" separator=",">
(#{user.name})
</foreach>
</insert>
批量修改
<!--批量修改-->
<update id="updateBatch" parameterType="list">
UPDATE user SET name="bobo" WHERE id IN
<foreach collection="list" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</update>
7 Mybatis的动态sql
高级查询:
<sql id="querySql">
<where>
<if test="name!=null">
AND name LIKE #{name}
</if>
<if test="age!=null">
AND age=#{age}
</if>
</where>
</sql>
<!--高级查询-->
<select id="findByQuery" parameterType="UserQuery" resultType="User">
SELECT * FROM user
<include refid="querySql"></include>
</select>

被折叠的 条评论
为什么被折叠?



