MyBatis入门demo
来源:互联网 发布:caffe linux 安装 编辑:程序博客网 时间:2024/06/07 04:57
最近要学习使用MyBatis,参照网上的资料和官方的教程,根据自己的理解,记录一下。
MyBatisJar包下载地址:http://download.csdn.net/detail/jolingogo/5220163
官方教程:http://mybatis.github.com/mybatis-3/zh/index.htm
一.什么是MyBatis
MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除 了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJOs(Plan Old Java Objects,普通的 Java 对象)映射成数据库中的记录。
以前学习过Hibernate,在网上查了一下,说MyBatis是半自动化的,需要自己写SQL语句,这样就可以根据需要自己优化SQL了。
Hibernate可以根据配置文件或者注解自动生成表,省去了自己写建表语句,在网上找了一下,MyBatis好像不可以。Google提供了generator,可以根据表结构生成实体类和映射文件,试了一下,还不错,以后会写一下。
二.配置文件
这些框架什么的,基本上都需要配置文件。MyBatis的XML 配置文件包含对 MyBatis 系统的核心设置,包含获取数据库连接实例的数据源和 决定事务范围和控制的事务管理器。
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="config.properties"></properties>
- <!-- 环境配置 -->
- <environments default="development">
- <environment id="development">
- <transactionManager type="JDBC"/>
- <!-- 数据库连接相关配置 ,这里动态获取config.properties文件中的内容-->
- <dataSource type="POOLED">
- <property name="driver" value="${driver}"/>
- <property name="url" value="${url}"/>
- <property name="username" value="${username}"/>
- <property name="password" value="${password}"/>
- </dataSource>
- </environment>
- </environments>
- <!-- 映射文件 ,我们还没有,这里什么都不写-->
- <mappers>
- </mappers>
- </configuration>
三.从 XML 中构建 SqlSessionFactory
每 一 个 MyBatis 的 应 用 程 序 都 以 一 个 SqlSessionFactory 对 象 的 实 例 为 核 心 。 SqlSessionFactory 对 象 的 实 例 可 以 通 过 SqlSessionFactoryBuilder 对 象 来 获 得 。 SqlSessionFactoryBuilder 对象可以从 XML 配置文件,或从 Configuration 类的习惯准备的实 例中构建 SqlSessionFactory 对象。
这里的SqlSessionFactory和Hibernate中的SessionFactory是一样的,我们可以通过factory,获取session。
- package org.ygy.util;
- import java.io.IOException;
- import java.io.InputStream;
- import org.apache.ibatis.io.Resources;
- import org.apache.ibatis.session.SqlSession;
- import org.apache.ibatis.session.SqlSessionFactory;
- import org.apache.ibatis.session.SqlSessionFactoryBuilder;
- /**
- * MyBatis的工具类
- * @author yuguiyang
- *
- */
- public class MyBatisUtil {
- private static SqlSessionFactory sqlSessionFactory = null;
- /**
- * 初始化Session工厂
- * @throws IOException
- */
- private static void initialFactory() throws IOException {
- String resource = "mybatis-config.xml";
- InputStream inputStream = Resources.getResourceAsStream(resource);
- sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
- }
- /**
- * 获取Session
- * @return
- */
- public static SqlSession getSession() {
- if(sqlSessionFactory == null) {
- try {
- initialFactory();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return sqlSessionFactory.openSession();
- }
- }
接下来,我们测试一下,看看配置是否正确:
- package org.ygy.model;
- import static org.junit.Assert.*;
- import org.apache.ibatis.session.SqlSession;
- import org.junit.Test;
- import org.ygy.util.MyBatisUtil;
- public class ModelTest {
- @Test
- public void testGetSession() {
- SqlSession session = MyBatisUtil.getSession();
- assertNotNull(session);
- if(session != null) {
- session.close();
- session = null;
- }
- }
- }
貌似,想当然的悲剧了,这样测试好像不行,刚才忘记添加数据库驱动了,结果运行一样成功了,如果不执行SQL语句的话,MyBatis好像不会去连接数据库,测试还是等一下吧。
既然这样的话,我们就先写一个映射文件。
首先,我们要建一张表,就来一个用户表吧(t_user),我用的SqlServer,语句就省略了吧
然后,和表对应的实体类:
- package org.ygy.model;
- /**
- * 用户
- * @author yuguiyang
- *
- */
- public class User {
- private Integer id;//自动增长的ID
- private String name;//用户名
- private String password;//密码
- private String email;//邮箱
- private Integer age;//年龄
- private Integer gender;//性别,0-男 ; 1-女
- public Integer getId() {
- return id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getPassword() {
- return password;
- }
- public void setPassword(String password) {
- this.password = password;
- }
- public String getEmail() {
- return email;
- }
- public void setEmail(String email) {
- this.email = email;
- }
- public Integer getAge() {
- return age;
- }
- public void setAge(Integer age) {
- this.age = age;
- }
- public Integer getGender() {
- return gender;
- }
- public void setGender(Integer gender) {
- this.gender = gender;
- }
- @Override
- public String toString() {
- return "User [id=" + id + ", name=" + name + ", password=" + password
- + ", email=" + email + ", age=" + age + ", gender=" + gender
- + "]";
- }
- }
接下来,是映射文件: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="org.ygy.mapper.UserMapper">
- <insert id="insert" parameterType="org.ygy.model.User" useGeneratedKeys="true">
- insert into t_user(name , password , email , gender , age)
- values(#{name} , #{password} , #{email} , #{gender} , #{age})
- </insert>
- <select id="selectUser" resultType="org.ygy.model.User">
- select * from t_user
- </select>
- </mapper>
最后,在mybatis-config.xml配置文件中添加映射文件:
- <!-- 映射文件 -->
- <mappers>
- <mapper resource="org/ygy/mapper/UserMapper.xml"/>
- </mappers>
好了,这下,我们可以测试了:
- package org.ygy.model;
- import static org.junit.Assert.assertEquals;
- import static org.junit.Assert.assertNotNull;
- import java.util.List;
- import org.apache.ibatis.session.SqlSession;
- import org.junit.After;
- import org.junit.Before;
- import org.junit.Test;
- import org.ygy.util.MyBatisUtil;
- public class ModelTest {
- private SqlSession session = null;
- @Before
- public void before() {
- session = MyBatisUtil.getSession();
- }
- @After
- public void after() {
- session.commit();
- session.close();
- }
- @Test
- public void testGetSession() {
- assertNotNull(session);
- if(session != null) {
- session.close();
- session = null;
- }
- }
- @Test
- public void testSelectUser() {
- List<User> userList = session.selectList("org.ygy.mapper.UserMapper.selectUser");
- for(User each : userList) {
- System.out.println("each->" + each);
- }
- }
- @Test
- public void testInsert() {
- User user = new User();
- user.setName("路飞");
- user.setPassword("lufei");
- user.setEmail("lufei@op.com");
- user.setAge(23);
- user.setGender(0);
- int result = session.insert("org.ygy.mapper.UserMapper.insert" , user);
- assertEquals(1 , result);
- }
- }
,这样,一个入门的示例,就差不多了。
拓展:
1.别名
在mybatis-config.xml中可以配置别名 (typeAliases)
类型别名是为 Java 类型命名一个短的名字。它只和 XML 配置有关,只用来减少类完全限定名的多余部分。
看看上面UserMapper.xml中
只要在mybatis-config.xml中添加
- <!-- 配置别名 -->
- <typeAliases>
- <typeAlias type="org.ygy.model.User" alias="User"/>
- </typeAliases>
就可以了。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(2)
发现一个MyBatis博客,讲的挺好的:http://legend2011.blog.51cto.com/3018495/908956
官方教程:http://mybatis.github.com/mybatis-3/zh/sqlmap-xml.html
官方的教程是中文的,讲的很好,一定要看啊。
一.Mapper XML 文件
MyBatis 真正的力量是在映射语句中。这里是奇迹发生的地方。对于所有的力量,SQL映射的 XML 文件是相当的简单。当然如果你将它们和对等功能的 JDBC 代码来比较,你会发现映射文件节省了大约 95%的代码量。MyBatis 的构建就是聚焦于 SQL 的,使其远离于普通的方式。
SQL 映射文件有很少的几个顶级元素(按照它们应该被定义的顺序):
- cache – 配置给定命名空间的缓存。
- cache-ref – 从其他命名空间引用缓存配置。
- resultMap – 最复杂,也是最有力量的元素,用来描述如何从数据库结果集中来加载你的对象。
parameterMap– 已经被废弃了!老式风格的参数映射。内联参数是首选,这个元素可能在将来被移除。这里不会记录。- sql – 可以重用的 SQL 块,也可以被其他语句引用。
- insert – 映射插入语句
- update – 映射更新语句
- delete – 映射删除语句
- select – 映射查询语句
二.示例
这里就简单的实现以下增删改查:
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="org.ygy.mapper.UserMapper">
- <!-- 插入,参数是User对象,使用自动增长的ID -->
- <insert id="insert" parameterType="User" useGeneratedKeys="true" keyProperty="id">
- <!-- 就是普通的插入语句,这里使用#{xxx}的方式赋值,这里的xxx要和实体类中的属性对应 -->
- insert into t_user(name , password , email , gender , age)
- values(#{name} , #{password} , #{email} , #{gender} , #{age})
- </insert>
- <!-- 更新用户信息 -->
- <update id="update" parameterType="User">
- update t_user set
- name=#{name},password=#{password},email=#{email},gender=#{gender},age=#{age}
- where id=#{id}
- </update>
- <!-- 根据用户ID,删除一个用户 -->
- <delete id="delete" parameterType="int">
- delete from t_user where id=#{id}
- </delete>
- <!-- 查询所有用户 -->
- <select id="selectUser" resultType="User">
- select * from t_user
- </select>
- <!-- 根据用户ID,查询用户 -->
- <select id="queryById" parameterType="int" resultType="User">
- select * from t_user where id=#{id}
- </select>
- <!-- 根据用户名,查找用户 -->
- <select id="queryByName" parameterType="String" resultType="User">
- select *from t_user where name=#{name}
- </select>
- </mapper>
UserDao.java
- package org.ygy.dao;
- import java.util.List;
- import org.ygy.model.User;
- /**
- * User类Dao接口
- * @author yuguiyang
- *
- */
- public interface UserDao {
- /**
- * 添加一个用户
- * @param user
- * @return
- */
- public int insert(User user);
- /**
- * 修改用户信息
- * @param user
- * @return
- */
- public int update(User user);
- /**
- * 修改用户
- * @param id
- * @return
- */
- public int delete(int id);
- /**
- * 获取所有用户
- * @return
- */
- public List<User> selectUser();
- /**
- * 根据用户ID查找用户
- * @param id
- * @return
- */
- public User queryById(int id);
- /**
- * 根据用户名查找用户
- * @param name
- * @return
- */
- public User queryByName(String name);
- }
- package org.ygy.dao.impl;
- import java.util.List;
- import org.apache.ibatis.session.SqlSession;
- import org.ygy.dao.UserDao;
- import org.ygy.model.User;
- import org.ygy.util.MyBatisUtil;
- /**
- * User类Dao实现类
- * @author yuguiyang
- *
- */
- public class UserDaoImpl implements UserDao {
- @Override
- public int insert(User user) {
- //获取session
- SqlSession session = MyBatisUtil.getSession();
- //调用UserMapper.xml中的insert,并返回受影响的行数
- int affectedRows = session.insert("org.ygy.mapper.UserMapper.insert" , user);
- //提交事务,执行insert,update,delete时,一定要提交,不然数据库中不会修改
- session.commit();
- //关闭session
- session.close();
- return affectedRows;
- }
- @Override
- public int update(User user) {
- SqlSession session = MyBatisUtil.getSession();
- int affectedRows = session.update("org.ygy.mapper.UserMapper.update" , user);
- session.commit();
- session.close();
- return affectedRows;
- }
- @Override
- public int delete(int id) {
- SqlSession session = MyBatisUtil.getSession();
- int affectedRows = session.delete("org.ygy.mapper.UserMapper.delete" , id);
- session.commit();
- session.close();
- return affectedRows;
- }
- @Override
- public List<User> selectUser() {
- SqlSession session = MyBatisUtil.getSession();
- List<User> userList = session.selectList("org.ygy.mapper.UserMapper.selectUser");
- session.commit();
- session.close();
- return userList;
- }
- @Override
- public User queryById(int id) {
- SqlSession session = MyBatisUtil.getSession();
- User user = session.selectOne("org.ygy.mapper.UserMapper.queryById" , id);
- session.commit();
- session.close();
- return user;
- }
- @Override
- public User queryByName(String name) {
- SqlSession session = MyBatisUtil.getSession();
- User user = session.selectOne("org.ygy.mapper.UserMapper.queryByName" , name);
- session.commit();
- session.close();
- return user;
- }
- }
UserDaoTest.java
- package org.ygy.dao;
- import static org.junit.Assert.assertEquals;
- import java.util.List;
- import org.junit.Before;
- import org.junit.Test;
- import org.ygy.dao.impl.UserDaoImpl;
- import org.ygy.model.User;
- public class UserDaoTest {
- private UserDao userDao = null;
- @Before
- public void before() {
- userDao = new UserDaoImpl();
- }
- @Test
- public void testInsert() {
- User user = new User();
- user.setName("乔巴");
- user.setPassword("qiaoba");
- user.setAge(23);
- user.setGender(0);
- user.setEmail("qiaoba@op.com");
- assertEquals(1 , userDao.insert(user));
- }
- @Test
- public void testQueryByName() {
- User user = userDao.queryByName("乔巴");
- System.out.println("user->" + user);
- }
- @Test
- public void testQueryById() {
- User user = userDao.queryById(4);
- System.out.println("user->" + user);
- }
- @Test
- public void testUpdate() {
- User user = userDao.queryByName("乔巴");
- user.setName("七段变身-乔巴");
- userDao.update(user);
- }
- @Test
- public void testDelete() {
- assertEquals(1 , userDao.delete(3));
- }
- @Test
- public void testSelectUser() {
- List<User> userList = userDao.selectUser();
- for(User each : userList) {
- System.out.println("each->" + each);
- }
- }
- }
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
这里整理一下,使用MyBatis时遇到的一些问题:
1.主键
官方讲解:
首先,如果你的数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),那么你可以设置 useGeneratedKeys=”true”,而且设置 keyProperty 到你已经做好的目标属性上。例如,如果上面的 Author 表已经对 id 使用了自动生成的列类型,那么语句可以修改为:
- <insert id="insertAuthor" parameterType="domain.blog.Author" useGeneratedKeys="true"
- keyProperty="id">
- insert into Author (username,password,email,bio)
- values (#{username},#{password},#{email},#{bio})
- </insert>
MyBatis 有另外一种方法来处理数据库不支持自动生成类型,或者可能 JDBC 驱动不支持自动生成主键时的主键生成问题。
这里有一个简单(甚至很傻)的示例,它可以生成一个随机 ID(可能你不会这么做,但是这展示了 MyBatis 处理问题的灵活性,因为它并不真的关心 ID 的生成):
- <insert id="insertAuthor" parameterType="domain.blog.Author">
- <selectKey keyProperty="id" resultType="int" order="BEFORE">
- select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
- </selectKey>
- insert into Author
- (id, username, password, email,bio, favourite_section)
- values
- (#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR})
- </insert>
个人理解:在mapper.xml中,使用insert时,MySql和SqlServer都有主键自动增长的设置,我们可以这样配置
- <insert id="insert" parameterType="User" useGeneratedKeys="true" keyProperty="id">
- <!-- 就是普通的插入语句,这里使用#{xxx}的方式赋值,这里的xxx要和实体类中的属性对应 -->
- insert into t_user(name , password , email , gender , age)
- values(#{name} , #{password} , #{email} , #{gender} , #{age})
- </insert>
在Oracle中,自动增长的话,需要使用序列
- <insert id="insert" parameterType="User">
- <!-- 这里查询序列 -->
- <selectKey keyProperty="id" order="BEFORE" resultType="int">
- select s_demo_userId.nextval from dual
- </selectKey>
- insert into t_user(id , name , password , email , gender , age)
- values(#{id} , #{name} , #{password} , #{email} , #{gender} , #{age})
- </insert>
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
我们先来看一下,之前的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="org.ygy.mapper.UserMapper">
- <!-- 插入,参数是User对象,使用自动增长的ID -->
- <insert id="insert" parameterType="User" useGeneratedKeys="true" keyProperty="id">
- <!-- 就是普通的插入语句,这里使用#{xxx}的方式赋值,这里的xxx要和实体类中的属性对应 -->
- insert into t_user(name , password , email , gender , age)
- values(#{name} , #{password} , #{email} , #{gender} , #{age})
- </insert>
- <!-- 更新用户信息 -->
- <update id="update" parameterType="User">
- update t_user set
- name=#{name},password=#{password},email=#{email},gender=#{gender},age=#{age}
- where id=#{id}
- </update>
- <!-- 根据用户ID,删除一个用户 -->
- <delete id="delete" parameterType="int">
- delete from t_user where id=#{id}
- </delete>
- <!-- 查询所有用户 -->
- <select id="selectUser" resultType="User">
- select * from t_user
- </select>
- <!-- 根据用户ID,查询用户 -->
- <select id="queryById" parameterType="int" resultType="User">
- select * from t_user where id=#{id}
- </select>
- <!-- 根据用户名,查找用户 -->
- <select id="queryByName" parameterType="String" resultType="User">
- select *from t_user where name=#{name}
- </select>
- </mapper>
主要看一下,插入,和更新,可能会发现一些问题,例如:在插入的时候用户信息可能并不全,在更新的时候,我们并不像更新所有的信息。
其实,如果用查询来说明的话,会更好理解。
那该怎么办呢?
MyBatis提供了很方便的做法:
MyBatis 的一个强大的特性之一通常是它的动态 SQL 能力。如果你有使用 JDBC 或其他相似框架的经验,你就明白条件地串联 SQL 字符串在一起是多么的痛苦,确保不能忘了空格或在列表的最后省略逗号。动态 SQL 可以彻底处理这种痛苦。
通常使用动态 SQL 不可能是独立的一部分,MyBatis 当然使用一种强大的动态 SQL 语言来改进这种情形,这种语言可以被用在任意映射的 SQL 语句中。
动态 SQL 元素和使用 JSTL 或其他相似的基于 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多的元素需要来了解。MyBatis 3 大大提升了它们,现在用不到原先一半的元素就能工作了。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
- <!-- 更新用户信息 -->
- <update id="update" parameterType="User">
- update t_user
- <set>
- <if test="name != null">name=#{name},</if>
- <if test="password != null">password=#{password}</if>
- <if test="email != null">email=#{email}</if>
- <if test="age != null">age=#{age}</if>
- <if test="gender != null">gender=#{gender}</if>
- </set>
- where id=#{id}
- </update>
- MyBatis入门demo
- MyBatis入门demo
- Spring Boot+Mybatis 入门Demo
- Mybatis入门 操作MySQL DEMO
- Mybatis 3.2.7 简单入门Demo
- Mybatis 3.2.7 简单入门Demo
- 【web】mybatis入门详解,基础案例demo
- 一个简单的mybatis入门demo
- 一个简单的mybatis入门demo
- Maven+SpringMVC+Mybatis整合入门Demo
- 入门demo---Mybatis学习笔记(三)
- 入门demo---Mybatis学习笔记(三)
- Mybatis Demo
- Mybatis Demo
- MyBatis-Demo
- MyBatis一对一demo!!!
- MyBatis一对多demo!!!
- MyBatis dynamic sql demo!!!
- 中国城市经纬度表(精确到县区)Google地图用
- Linux下C开发环境的搭建过程
- 运动目标检测、阴影检测及目标跟踪中用得到的标准测试视频下载(大量IBM提供视频)
- 试图加载格式不正确的程序
- 为Zend Studio配置JRE
- MyBatis入门demo
- 黑马程序员--数组
- tcpcopy架构漫谈
- Android预定义样式
- 我读过的那些技术书籍(英文为主)
- Tutorials - kd-tree
- MySQL的mysqldump工具的基本用法
- iOS SDK:预览和打开文档
- oracle 如何获取表的主键列名,如何获取表的所有列名 .