mybatis 详解(二)------入门实例(基于XML)
通过上一小节,mybatis 和 jdbc 的区别:http://www.cnblogs.com/ysocean/p/7271600.html,我们对 mybatis有了一个大致的了解,下面我们通过一个入门实例来对mybatis有更近一步的了解。
我们用 mybatis 来对 user 表进行增删改查操作。
ps:本篇博客源代码链接:http://pan.baidu.com/s/1eSEfc8i密码:j480
1、创建MySQL数据库:mybatisDemo和表:user
这里我们就不写脚本创建了,创建完成后,再向其中插入几条数据即可。
user 表字段如下:


2、建立一个Java工程,并导入相应的jar包,具体目录如下
注意:log4j和Junit不是必须的,但是我们为了查看日志以及便于测试,加入了这两个jar包

3、在 MyBatisTest 工程中添加数据库配置文件 mybatis-configuration.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> <!-- 注意:environments标签,当mybatis和spring整合之后,这个标签是不用配置的 --> <!-- 可以配置多个运行环境,但是每个 SqlSessionFactory 实例只能选择一个运行环境
一、development:开发模式
二、work:工作模式-->
<environments default="development">
<!--id属性必须和上面的default一样 -->
<environment id="development">
<!--事务管理器
一、JDBC:这个配置直接简单使用了 JDBC 的提交和回滚设置。它依赖于从数据源得到的连接来管理事务范围
二、MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接。而它会让容器来管理事务的整个生命周期
比如 spring 或 JEE 应用服务器的上下文,默认情况下,它会关闭连接。然而一些容器并不希望这样,
因此如果你需要从连接中停止它,就可以将 closeConnection 属性设置为 false,比如:
<transactionManager type="MANAGED">
<property name="closeConnection" value="false"/>
</transactionManager>
-->
<transactionManager type="JDBC"/>
<!--dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象源 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatisdemo"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments> </configuration>
4、定义表所对应的实体类

package com.ys.po;
import java.util.Date;
public class User {
private int id;
private String username;
private String sex;
private Date birthday;
private String address;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", sex=" + sex
+ ", birthday=" + birthday + ", address=" + address + "]";
}
}
5、定义操作 user 表的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 namespace="com.ys.po.userMapper"> <!-- 根据 id 查询 user 表中的数据
id:唯一标识符,此文件中的id值不能重复
resultType:返回值类型,一条数据库记录也就对应实体类的一个对象
parameterType:参数类型,也就是查询条件的类型
-->
<select id="selectUserById"
resultType="com.ys.po.User" parameterType="int">
<!-- 这里和普通的sql 查询语句差不多,对于只有一个参数,后面的 #{id}表示占位符,里面不一定要写id,写啥都可以,但是不要空着,如果有多个参数则必须写pojo类里面的属性 -->
select * from user where id = #{id}
</select> <!-- 查询 user 表的所有数据
注意:因为是查询所有数据,所以返回的应该是一个集合,这个集合里面每个元素都是User类型
-->
<select id="selectUserAll" resultType="com.ys.po.User">
select * from user
</select> <!-- 模糊查询:根据 user 表的username字段
下面两种写法都可以,但是要注意
1、${value}里面必须要写value,不然会报错
2、${}表示拼接 sql 字符串,将接收到的参数不加任何修饰拼接在sql语句中
3、使用${}会造成 sql 注入
-->
<select id="selectLikeUserName" resultType="com.ys.po.User" parameterType="String">
select * from user where username like '%${value}%'
<!-- select * from user where username like #{username} -->
</select> <!-- 向 user 表插入一条数据 -->
<insert id="insertUser" parameterType="com.ys.po.User">
insert into user(id,username,sex,birthday,address)
value(#{id},#{username},#{sex},#{birthday},#{address})
</insert> <!-- 根据 id 更新 user 表的数据 -->
<update id="updateUserById" parameterType="com.ys.po.User">
update user set username=#{username} where id=#{id}
</update> <!-- 根据 id 删除 user 表的数据 -->
<delete id="deleteUserById" parameterType="int">
delete from user where id=#{id}
</delete>
</mapper>
6、向 mybatis-configuration.xml 配置文件中注册 userMapper.xml 文件

<mappers>
<!-- 注册userMapper.xml文件,
userMapper.xml位于com.ys.mapper这个包下,所以resource写成com/ys/mapper/userMapper.xml-->
<mapper resource="com/ys/mapper/userMapper.xml"/>
</mappers>
7、创建测试类
package com.ys.test; import java.io.InputStream;
import java.util.List; import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test; import com.ys.po.User; public class CRUDTest {
//定义 SqlSession
SqlSession session =null; @Before
public void init(){
//定义mybatis全局配置文件
String resource = "mybatis-configuration.xml";
//加载 mybatis 全局配置文件
InputStream inputStream = CRUDTest.class.getClassLoader()
.getResourceAsStream(resource);
//构建sqlSession的工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//根据 sqlSessionFactory 产生 session
session = sessionFactory.openSession();
} //根据id查询user表数据
@Test
public void testSelectUserById(){
/*这个字符串由 userMapper.xml 文件中 两个部分构成
<mapper namespace="com.ys.po.userMapper"> 的 namespace 的值
<select id="selectUserById" > id 值*/
String statement = "com.ys.po.userMapper.selectUserById";
User user = session.selectOne(statement, 1);
System.out.println(user);
session.close();
} //查询所有user表所有数据
@Test
public void testSelectUserAll(){
String statement = "com.ys.po.userMapper.selectUserAll";
List<User> listUser = session.selectList(statement);
for(User user : listUser){
System.out.println(user);
}
session.close();
} //模糊查询:根据 user 表的username字段
@Test
public void testSelectLikeUserName(){
String statement = "com.ys.po.userMapper.selectLikeUserName";
List<User> listUser = session.selectList(statement, "%t%");
for(User user : listUser){
System.out.println(user);
}
session.close(); }
//向 user 表中插入一条数据
@Test
public void testInsertUser(){
String statement = "com.ys.po.userMapper.insertUser";
User user = new User();
user.setUsername("Bob");
user.setSex("女");
session.insert(statement, user);
//提交插入的数据
session.commit();
session.close();
} //根据 id 更新 user 表的数据
@Test
public void testUpdateUserById(){
String statement = "com.ys.po.userMapper.updateUserById";
//如果设置的 id不存在,那么数据库没有数据更改
User user = new User();
user.setId(4);
user.setUsername("jim");
session.update(statement, user);
session.commit();
session.close();
} //根据 id 删除 user 表的数据
@Test
public void testDeleteUserById(){
String statement = "com.ys.po.userMapper.deleteUserById";
session.delete(statement,4);
session.commit();
session.close();
}
}
补充:如何得到插入数据之后的主键值?
第一种:数据库设置主键自增机制
userMapper.xml 文件中定义:
<!-- 向 user 表插入一条数据 -->
<insert id="insertUser" parameterType="com.ys.po.User">
<!-- 将插入的数据主键返回到 user 对象中
keyProperty:将查询到的主键设置到parameterType 指定到对象的那个属性
select LAST_INSERT_ID():查询上一次执行insert 操作返回的主键id值,只适用于自增主键
resultType:指定 select LAST_INSERT_ID() 的结果类型
order:AFTER,相对于 select LAST_INSERT_ID()操作的顺序
-->
<selectKey keyProperty="id" resultType="int" order="AFTER">
select LAST_INSERT_ID()
</selectKey>
insert into user(username,sex,birthday,address)
value(#{username},#{sex},#{birthday},#{address})
</insert>
测试:
//向 user 表中插入一条数据并获取主键值
@Test
public void testInsertUser(){
String statement = "com.ys.po.userMapper.insertUser";
User user = new User();
user.setUsername("Bob");
user.setSex("女");
session.insert(statement, user);
//提交插入的数据
session.commit();
//打印主键值
System.out.println(user.getId());
session.close();
}
第二种:非自增主键机制
<!-- 向 user 表插入一条数据 -->
<insert id="insertUser" parameterType="com.ys.po.User">
<!-- 将插入的数据主键返回到 user 对象中
流程是:首先通过 select UUID()得到主键值,然后设置到 user 对象的id中,在进行 insert 操作
keyProperty:将查询到的主键设置到parameterType 指定到对象的那个属性
select UUID():得到主键的id值,注意这里是字符串
resultType:指定 select UUID() 的结果类型
order:BEFORE,相对于 select UUID()操作的顺序
-->
<selectKey keyProperty="id" resultType="String" order="BEFORE">
select UUID()
</selectKey>
insert into user(id,username,sex,birthday,address)
value(#{id},#{username},#{sex},#{birthday},#{address})
</insert>
总结:
①、parameterType:指定输入参数的类型
②、resultType:指定输出结果的类型,在select中如果查询结果是集合,那么也表示集合中每个元素的类型
③、#{}:表示占位符,用来接收输入参数,类型可以是简单类型,pojo,HashMap等等
如果接收简单类型,#{}可以写成 value 或者其他名称
如果接收 pojo 对象值,通过 OGNL 读取对象中的属性值,即属性.属性.属性...的方式获取属性值
④、${}:表示一个拼接符,会引起 sql 注入,不建议使用
用来接收输入参数,类型可以是简单类型,pojo,HashMap等等
如果接收简单类型,${}里面只能是 value
如果接收 pojo 对象值,通过 OGNL 读取对象中的属性值,即属性.属性.属性...的方式获取属性值
mybatis 详解(二)------入门实例(基于XML)的更多相关文章
- Mybatis详解(二) sqlsession的创建过程
我们处于的位置 我们要清楚现在的情况. 现在我们已经调用了SqlSessionFactoryBuilder的build方法生成了SqlSessionFactory 对象. 但是如标题所说,要想生成sq ...
- MyBatis 详解(一对一,一对多,多对多)
1.什么是MyBatis? MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且 ...
- mybatis 详解(三)------入门实例(基于注解)
1.创建MySQL数据库:mybatisDemo和表:user 详情参考:mybatis 详解(二)------入门实例(基于XML) 一致 2.建立一个Java工程,并导入相应的jar包,具体目录如 ...
- 爬虫入门之urllib库详解(二)
爬虫入门之urllib库详解(二) 1 urllib模块 urllib模块是一个运用于URL的包 urllib.request用于访问和读取URLS urllib.error包括了所有urllib.r ...
- Shiro 安全框架详解二(概念+权限案例实现)
Shiro 安全框架详解二 总结内容 一.登录认证 二.Shiro 授权 1. 概念 2. 授权流程图 三.基于 ini 的授权认证案例实现 1. 实现原理图 2. 实现代码 2.1 添加 maven ...
- mybatis 详解------动态SQL
mybatis 详解------动态SQL 目录 1.动态SQL:if 语句 2.动态SQL:if+where 语句 3.动态SQL:if+set 语句 4.动态SQL:choose(when,o ...
- logback -- 配置详解 -- 二 -- <appender>
附: logback.xml实例 logback -- 配置详解 -- 一 -- <configuration>及子节点 logback -- 配置详解 -- 二 -- <appen ...
- SpringMVC入门(基于XML方式实现)
----------------------siwuxie095 SpringMVC 入门(基于 XML 方式实现) (一)搭建 SpringMVC 环境 1.先下载相关库文件,下载链接: (1)ht ...
- Python基础知识详解 从入门到精通(七)类与对象
本篇主要是介绍python,内容可先看目录其他基础知识详解,欢迎查看本人的其他文章Python基础知识详解 从入门到精通(一)介绍Python基础知识详解 从入门到精通(二)基础Python基础知识详 ...
- [原创]mybatis详解说明
mybatis详解 2017-01-05MyBatis之代理开发模式1 mybatis-Dao的代理开发模式 Dao:数据访问对象 原来:定义dao接口,在定义dao的实现类 dao的代理开发模式 只 ...
随机推荐
- Java NIO学习笔记七 Non-blocking Server
Java NIO:Non-blocking Server 即使你了解了Java NIO非阻塞功能的工作(怎么样Selector,Channel, Buffer等等),设计一个无阻塞服务器仍然很难.非阻 ...
- An express train to reveries
An express train to reveries time limit per test 1 second memory limit per test 256 megabytes input ...
- Spring+TaskExecutor实例
1 taskExcutor package com.test; import org.springframework.core.task.TaskExecutor; public class Main ...
- 解决安卓手机input获取焦点时会将底部固定定位按钮顶起的问题
一个页面上有个固定在底部的按钮,页面中有个input框,点击input框获取焦点时,在苹果手机上没事,但在安卓手机上弹出的键盘会将按钮顶起来,这就很不好看了,想了个办法解决一下.之前一直觉得用inpu ...
- 类型转换之 PropertyEditorSupport类
这个类可以用于自定义的类型转换, 子类继承这个类之后可以重写子类的方法 ,其中比较重要的是setAsText和setValue方法,setAsText 子自己的方式处理转换,setValue将转换的结 ...
- 《HelloGitHub》第 15 期
公告 这段时间没怎么写文章,跑去写 https://hellogithub.com 这个网站了,现在已经顺利上线,功能后面会持续迭代. 最后,这个 https://hellogithub.com 网站 ...
- fastJson将json字符串转换为map
public class JsonUtil { /** * 将json转化成map * @param jsonStr * @return */ public static Map<String, ...
- grub2详解(翻译和整理官方手册)
翻译了grub2官方手册的绝大部分内容,然后自己整理了一下.因为内容有点杂,所以章节安排上可能不是太合理,敬请谅解. 本文目录: 1.1 基础内容 1.2 安装grub2 1.3 grub2配置文件 ...
- php后台数组foreach嵌套循环
<?php foreach($list as $key=>$val){ ?> <tr class="over_odd"> <td align=& ...
- Generic(泛型)
什么是泛型:"通过参数化类型来实现在同一份代码上操作多种数据类型.利用"参数化类型"将类型抽象化,从而实现灵活的复用". 简单来说泛型就是为了使一些代码能够重复 ...