MyBatis基础-1
1.Mybatis简介
2.Mybatis环境搭建
3.Mybatis的开发方式
一.什么框架
框架其本质是半成品程序,提供相关规范,并且提供大量可重用的组件。
目的:让开发者开发出结构比较良好,可读性较强,扩展性和可维护性较好的工程。
第三阶段常见的框架:Mybatis,hibernate,spring,springmvc,struts2,webservice,activiti...
二.Mybatis简介
1.简介
1.MyBatis Apache基金会下的开源框架,是持久层框架(Data Access Objects:DAO),对JDBC轻量级的封装,前身为IBatis.
2.下载
https://github.com/mybatis/mybatis-3/releases
3.Mybatis特点
1.简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易
于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
2.灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优
化。通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多。
3.解除sql与程序代码的耦合:通过提供DAL层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易
维护,更易单元测试。sql和代码的分离,提高了可维护性。
4.提供映射标签,支持对象与数据库的orm字段关系映射
5.提供对象关系映射标签,支持对象关系组建维护
6.提供xml标签,支持编写动态sql
4.功能架构
Mybatis的功能架构分为三层:
1.API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求
就会调用数据处理层来完成具体的数据处理。
2.数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的
请求完成一次数据库操作。
3.基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东
西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。
5.执行流程及原理
总体执行流程:
1. 加载配置并初始化
加载配置文件,将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语
句、结果映射配置),存储在内存中。
2. 接收调用请求
调用Mybatis提供的API(SqlSession的CURD操作),传入Sql的相应ID和参数对象,将请求传递给下层的请求处理层进
行处理。
3.处理相应的操作请求
(A)根据SQL的ID查找对应的MappedStatement对象。
(B)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。
(C)获取数据库连接,根据得到的最终SQL语句和传入参数到数据库执行,并得到执行结果。
(D)根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。
(E)释放连接资源
三.Mybatis开发环境搭建
1.开发步骤
1.配置sqlMapConfig.xml(习惯命名mybatis-config.xml)
配置数据库连接信息
2.使用SqlSessionFactoryBulider解析sqlMapConfig.xml文件,获取会话对像SqlSession对像
3.编写Dao代码并配置Mapper.xml文件
该Mapper.xml用来编写sql语句,并对数据库表和Java对像,字段和Java对像属性建立映射关系。
4.使用SqlSession中的API进行CURD操作即可。
步骤一:新建Maven工程
步骤二:在pom.xml文件中引入jar包依赖
<dependencies>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<!--log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
步骤三:在resources目录下,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>
<!-- 读取数据库连接信息 -->
<properties resource="db.properties"></properties>
<!-- 数据连接环境 -->
<environments default="development">
<environment id="development">
<!-- 使用JDBC事务进行事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据源配置:POOLED表示使用连接池来管理连接对像 -->
<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>
<!-- 加载mapper文件 -->
<mappers>
<mapper resource="dao/UserMapper.xml"/>
</mappers>
</configuration>
log4j.properties日志文件:
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration...
#log4j.logger.org.mybatis.example.BlogMapper=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
db.properties数据库连接
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///javaee
jdbc.username=root
jdbc.password=tiger
步骤四:在dao层创建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表示命名空间,用来标识该Mapper文件-->
<mapper namespace="dao.UserMapper">
<!--id为该Sql语句的唯一标识,resultType表示查询出的结果要封装成的java类型-->
<select id="selectAll" resultType="model.User">
select * from USER
</select>
</mapper>
步骤五:使用mybatis的API进行CRUD操作
public class MyBatisSession {
public static void main(String[] args) throws IOException {
//1.解析mybatis-config.xml文件
String resource = "mybatis-config.xml";
//2.获取输入流
InputStream inputStream = Resources.getResourceAsStream(resource);
//3.SqlSessionFactory工厂
SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);
//4.创建sqlSession
SqlSession session = sqlSessionFactory.openSession();
//namespace.sqlId=statementId
List<User> list = session.selectList("dao.UserMapper.selectAll");
for(User user:list){
System.out.println(user.getId()+","+user.getUsername()+","+user.getPassword());
}
//5.关闭资源
session.close();
}
}
四.Mybatis相关类的生命周期
1.SqlSessionFactoryBuilder
这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。因此
SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。你可以重用
SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但是最好还是不要让其一直存在以保证所有的
XML 解析资源开放给更重要的事情
2.SqlSessionFactory
SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。使用
SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代
码“坏味道(bad smell)”。因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的
就是使用单例模式或者静态单例模式。
3.SqlSession
每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的
最佳的作用域是请求或方法作用域。绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量
也不行。也绝不能将 SqlSession 实例的引用放在任何类型的管理作用域中,比如 Servlet 架构中的
HttpSession。如果你现在正在使用一种 Web 框架,要考虑 SqlSession 放在一个和 HTTP 请求对象相似的作用域
中。换句话说,每次收到的 HTTP 请求,就可以打开一个 SqlSession,返回一个响应,就关闭它。这个关闭操作是很
重要的,你应该把这个关闭操作放到 finally 块中以确保每次都能执行关闭
五.Mybatis工具类
public class MybatisUtil {
static SqlSessionFactory sqlSessionFactory;
static {
String resource = "mybatis-config.xml";
InputStream inputStream;
try {
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 该方法调用必须在应用程序的成员方法中调用
* @return
*/
public static SqlSession findSqlSession(){
return sqlSessionFactory.openSession();
}
}
六.Mybatis的开发方式(Mybatis与数据库交互方式)
1.传统方式进行CRUD操作
通过调用MyBatis中SqlSession对象的方法从而达到与数据库交互的方式,有一些类似DBUtils的操作!
下面是使用MyBatis的方法,是创建一个和数据库打交道的SqlSession对象,然后根据StatementId 和参数来操作
数据库。如图所示 :
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">
<mapper namespace="dao.UserMapper">
<select id="selectAll" resultType="model.User">
select * from USER
</select>
<!-- OGNL表达式
1.简单类型参数,#{}中参数的命名可以自定义
2.POJO参数,#{}中参数的命名必须是POJO对像中get方法的后缀(首字母小写)一致。
-->
<select id="selectById" resultType="model.User">
select * from USER where id = #{id}
</select>
<select id="selectByItem" resultType="model.User" parameterType="model.User">
select * from USER where username=#{username} and password=#{password}
</select>
<insert id="insert" parameterType="model.User">
insert into USER(username,password) values(#{username},#{password})
</insert>
<delete id="delete" parameterType="model.User">
delete from USER where id = #{id}
</delete>
<update id="update" parameterType="model.User">
update USER set username=#{username},password=#{password} where id = #{id}
</update>
</mapper>
dao层代码
public class UserDao {
public void insert(User user) {
SqlSession session = MybatisUtil.findSqlSession();
try {
session.insert("dao.UserMapper.insert", user);
// 提交事务
session.commit();
} catch (Exception e) {
e.printStackTrace();
session.rollback();
} finally {
session.close();
}
}
public void delete(User user) {
SqlSession session = MybatisUtil.findSqlSession();
try {
session.delete("dao.UserMapper.delete", user);
// 提交事务
session.commit();
} catch (Exception e) {
e.printStackTrace();
session.rollback();
} finally {
session.close();
}
}
public void update(User user) {
SqlSession session = MybatisUtil.findSqlSession();
try {
session.update("dao.UserMapper.update", user);
// 提交事务
session.commit();
} catch (Exception e) {
e.printStackTrace();
session.rollback();
} finally {
session.close();
}
}
public User selectById(int id) {
SqlSession session = MybatisUtil.findSqlSession();
User user = null;
try {
user = session.selectOne("dao.UserMapper.selectById", id);
} catch (Exception e) {
e.printStackTrace();
} finally {
session.close();
}
return user;
}
public List<User> selectAll() {
SqlSession session = MybatisUtil.findSqlSession();
List<User> users = null;
try {
users = session.selectList("dao.UserMapper.selectAll");
} catch (Exception e) {
e.printStackTrace();
} finally {
session.close();
}
return users;
}
public User selectByItem(User user) {
SqlSession session = MybatisUtil.findSqlSession();
try {
user = session.selectOne("dao.UserMapper.selectByItem", user);
} catch (Exception e) {
e.printStackTrace();
} finally {
session.close();
}
return user;
}
}
service层代码
public class UserService {
UserDao dao = new UserDao();
public void save(User user) {
dao.insert(user);
}
public void remove(User user) {
dao.delete(user);
}
public void modify(User user) {
dao.update(user);
}
public User findById(int id) {
return dao.selectById(id);
}
public List<User> findAll() {
return dao.selectAll();
}
public User findByItem(User user) {
return dao.selectByItem(user);
}
}
单元测试类
public class CRUDTest {
UserService ser;
@Before
public void init(){
ser = new UserService();
}
@Test
public void testSave(){
User user = new User();
user.setUsername("张三");
user.setPassword("1234");
ser.save(user);
}
@Test
public void testModify(){
User user = new User();
user.setId(3);
//user.setUsername("张三");
user.setPassword("0000");
ser.modify(user);
}
@Test
public void testRemove(){
User user = new User();
user.setId(3);
ser.remove(user);
}
@Test
public void testFindById(){
User user = ser.findById(1);
System.out.println(user.getId()+","+user.getUsername());
}
@Test
public void testFindByItem(){
User user = new User();
user.setUsername("admin");
user.setPassword("admin");
User findUser = ser.findByItem(user);
System.out.println(findUser.getId()+","+findUser.getUsername()+","+findUser.getPassword());
}
}
2.面向接口方式编程
原理
MyBatis将核心配置文件中的每一个节点抽象为一个 Mapper 接口,而这个接口中声明的方法和跟节点中的
<select|update|delete|insert>节点项对应,即<select|update|delete|insert> 节点的id值为Mapper接口中的
方法名称,parameterType值表示Mapper对应方法的入参类型,而resultMap 值则对应了Mapper接口表示的返
回值类型或者返回结果集的元素类型。
根据MyBatis的配置规范配置好后,通过SqlSession.getMapper(XXXMapper.class) 方法,MyBatis会根据相应的
接口声明的方法信息,通过动态代理机制生成一个Mapper实例,我们使用Mapper接口的某一个方法时,MyBatis会根据
这个方法的方法名和参数类型,确定Statement Id,底层还是通过
SqlSession.select("statementId",parameterObject);
或者
SqlSession.update("statementId",parameterObject);
等等来实现对数据库的操作,
MyBatis引用Mapper接口这种调用方式,纯粹是为了满足面向接口编程的需要。(其实还有一个原因是在于,面
向接口的编程,使得用户在接口上可以使用注解来配置SQL语句,这样就可以脱离XML配置文件,实现“0配置”)
开发规范
面向接口编程,必须遵守一定开发规范,如下:
1.接口和mapper必须同包放置
2.接口的类名必须和mapper的名称一致
3.接口方法名称必须和mapper中Sql的Id一致
4.mapper文件的namespace必须和接口的完全限定名一致
5.mapper接口的方法参数只能有一个,且类型要和mapper映射文件中statement的parameterType的值保持一致。
6.mapper接口的返回值类型要和mapper映射文件中statement的resultType值或resultMap中的type值保持一致。
7.接口中方法不允许重载。
8.如果传入多个参数,请把参数封装到POJO或Map集合中(也可以使用注解方式).
mapper接口
public interface UserMapper {
public void insert(User user);
public void delete(User user);
public void update(User user);
public User selectById(User user);
public List<User> selectAll();
//注解方式支持多参传入
public List<User> selectByPage(@Param(value="firstIndex")int firstIndex,@Param(value="maxResult")int maxResult);
//????
public List<User> selectByPage2(int firstIndex,int maxResult);
//多参传值时,一般封装成map或POJO进行处理
public List<User> selectByPage3(Map<String,Integer> map);
public List<User> selectByLike(User user);
}
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">
<mapper namespace="crud2.mapper.UserMapper">
<select id="selectAll" resultType="model.User">
select * from USER
</select>
<!-- OGNL表达式
1.简单类型参数,#{}中参数的命名可以自定义
2.POJO参数,#{}中参数的命名必须是POJO对像中get方法的后缀(首字母小写)一致。
-->
<select id="selectById" resultType="model.User" parameterType="model.User">
select * from USER where id = #{id}
</select>
<!--多参传值时,#{}中参数名和接口中@Param()中的值一致-->
<select id="selectByPage" resultType="model.User">
select * from USER limit #{firstIndex},#{maxResult}
</select>
<!--????-->
<select id="selectByPage2" resultType="model.User">
select * from USER limit #{0},#{1}
</select>
<!--接收参数为map类型-->
<select id="selectByPage3" resultType="model.User" parameterType="java.util.Map">
select * from USER limit #{firstIndex},#{maxResult}
</select>
<!--不要使用EL${}取值,使用函数处理-->
<select id="selectByLike" resultType="model.User" parameterType="model.User">
select * from USER where username like concat('%',#{username},'%');
</select>
<insert id="insert" parameterType="model.User">
insert into USER(username,password) values(#{username},#{password})
</insert>
<delete id="delete" parameterType="model.User">
delete from USER where id = #{id}
</delete>
<update id="update" parameterType="model.User">
update USER set username=#{username},password=#{password} where id = #{id}
</update>
</mapper>
service代码
public class UserService implements IUserService {
@Override
public void save(User user) {
SqlSession session = MybatisUtil.findSqlSession();
// 代理对像
UserMapper mapper = session.getMapper(UserMapper.class);
try {
mapper.insert(user);
session.commit();
} catch (Exception e) {
session.rollback();
} finally {
session.close();
}
}
@Override
public void remove(User user) {
SqlSession session = MybatisUtil.findSqlSession();
// 代理对像
UserMapper mapper = session.getMapper(UserMapper.class);
try {
mapper.delete(user);
session.commit();
} catch (Exception e) {
session.rollback();
} finally {
session.close();
}
}
@Override
public void modify(User user) {
SqlSession session = MybatisUtil.findSqlSession();
// 代理对像
UserMapper mapper = session.getMapper(UserMapper.class);
try {
mapper.update(user);
session.commit();
} catch (Exception e) {
session.rollback();
} finally {
session.close();
}
}
@Override
public User findById(User user) {
SqlSession session = MybatisUtil.findSqlSession();
// 代理对像
UserMapper mapper = session.getMapper(UserMapper.class);
return mapper.selectById(user);
}
@Override
public List<User> findAll() {
SqlSession session = MybatisUtil.findSqlSession();
// 代理对像
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> list = mapper.selectAll();
session.close();
return list;
}
@Override
public List<User> findByPage(int firstIndex,int maxResult) {
SqlSession session = MybatisUtil.findSqlSession();
// 代理对像
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> list = mapper.selectByPage(firstIndex,maxResult);
session.close();
return list;
}
@Override
public List<User> findByPage2(int firstIndex,int maxResult) {
SqlSession session = MybatisUtil.findSqlSession();
// 代理对像
UserMapper mapper = session.getMapper(UserMapper.class);
session.close();
return mapper.selectByPage2(firstIndex,maxResult);
}
}
MyBatis基础-1的更多相关文章
- myBatis 基础测试 表关联关系配置 集合 测试
myBatis 基础测试 表关联关系配置 集合 测试 测试myelipse项目源码 sql 下载 http://download.csdn.net/detail/liangrui1988/599388 ...
- JAVA之Mybatis基础入门--框架搭建与简单查询
JAVA中,操作数据库有JDBC.hibernate.Mybatis等技术,今天整理了下,来讲一讲下Mybatis.也为自己整理下文档: hibernate是一个完全的ORM框架,是完全面向对象的.但 ...
- MyBatis基础入门《二十》动态SQL(foreach)
MyBatis基础入门<二十>动态SQL(foreach) 1. 迭代一个集合,通常用于in条件 2. 属性 > item > index > collection : ...
- mybatis基础系列(四)——关联查询、延迟加载、一级缓存与二级缓存
关本文是Mybatis基础系列的第四篇文章,点击下面链接可以查看前面的文章: mybatis基础系列(三)——动态sql mybatis基础系列(二)——基础语法.别名.输入映射.输出映射 mybat ...
- mybatis基础系列(三)——动态sql
本文是Mybatis基础系列的第三篇文章,点击下面链接可以查看前面的文章: mybatis基础系列(二)--基础语法.别名.输入映射.输出映射 mybatis基础系列(一)--mybatis入门 动态 ...
- mybatis基础系列(二)——基础语法、别名、输入映射、输出映射
增删改查 mapper根节点及其子节点 mybatis框架需要读取映射文件创建会话工厂,映射文件是以<mapper>作为根节点,在根节点中支持9个元素,分别为insert.update.d ...
- mybatis基础系列(一)——mybatis入门
好久不发博客了,写博文的一个好处是能让心静下来,整理下之前学习过的一些知识一起分享,大神路过~ mybatis简介 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射. ...
- MyBatis基础入门《十九》动态SQL(set,trim)
MyBatis基础入门<十九>动态SQL(set,trim) 描述: 1. 问题 : 更新用户表数据时,若某个参数为null时,会导致更新错误 2. 分析: 正确结果: 若某个参数为nul ...
- MyBatis基础入门《十八》动态SQL(if-where)
MyBatis基础入门<十八>动态SQL(if-where) 描述: 代码是在<MyBatis基础入门<十七>动态SQL>基础上进行改造的,不再贴所有代码,仅贴改动 ...
- MyBatis基础入门《十七》动态SQL
MyBatis基础入门<十七>动态SQL 描述: >> 完成多条件查询等逻辑实现 >> 用于实现动态SQL的元素主要有: > if > trim > ...
随机推荐
- 【Laravel】 常用的artisan命令【原创】
全局篇 查看artisan命令 php artisan php artisan list 查看某个帮助命令 php artisan help make:model 查看laravel版本 ...
- 开始创作自己的VR作品——VR故事叙述终极指南
转自:http://www.52vr.com/article-1870-1.html 在8月份,YouTube Space LA开展了“VR Creator Lab”的活动,为期三个月.参 ...
- linux驱动开发—基于Device tree机制的驱动编写
前言Device Tree是一种用来描述硬件的数据结构,类似板级描述语言,起源于OpenFirmware(OF).在目前广泛使用的Linux kernel 2.6.x版本中,对于不同平台.不同硬件,往 ...
- Ext.net combobox 的disabled
C#:禁用combobox this.ComboBox7.Disabled =true; C#:隐藏 <ext:RadioGroup ID="RadioG_sfzg" run ...
- USACO 2008 Running(贝茜的晨练)
[题解] 动态规划,dp[i][j]表示第i分钟疲劳度为j的最长距离. [代码] #include <iostream> #include <cstdlib> #include ...
- 常见的web安全及防护原理
1.0 sql注入 sql注入原理:就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令. sql注入防护: 1.永远不要信任用户的输入,要 ...
- Visual Studio 20年
这是一个暴露年龄的话题,如果一个程序员从第一个版本开始使用Visual Studio的话,现在应该是40多岁的中年大叔了.我的程序员生涯是从Visual basic 6.0 (vb6)开始的,一晃就过 ...
- Solr高效利用:Solr实现SQL的查询与统计
1.如何高效使用Solr查询功能 ?2.单个字段分组统计如何实现? 3.IN条件查询有几种方式? 4.多个字段分组统计是否只支持count? Cloudera公司已经推出了基于Hadoop平台的查询统 ...
- JS中 == ,===, !=, !==的区别
一个等号是赋值操作,==先转换类型再比较,===先判断类型,如果不是同一类型直接为false. === 判断规则 如果类型不同,就[不相等] 如果两个都是数值,并且是同一个值,那么[相等]:(!例外 ...
- windows 下安装 docker
1. 使用阿里云的镜像进行安装: http://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/ 2. 安装完成后点击图标 “Dock ...