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,写啥都可以,但是不要空着 -->
    	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 读取对象中的属性值,即属性.属性.属性...的方式获取属性值

时间: 2024-08-27 15:46:57

mybatis 详解(二)------入门实例(基于XML)的相关文章

Mybatis详解二

SqlSession(SqlSessionDaoSupport类) SqlSessionDaoSupportSqlSessionDaoSupport是一个抽象的支持类,用来为你提供SqlSession.调用getSqlSession()方法你会得到一个SqlSessionTemplate,这然后可以用于执行SQL方法,就像下面这样:Java代码 public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao{ pu

MyBatis系列教程(二)--模拟实现基于XML和Annotation的小型Mybatis(Simulation)

http://blog.csdn.net/asmcos/article/details/46676101 http://blog.csdn.net/asmcos/article/details/46676087 http://blog.csdn.net/asmcos/article/details/46676073 http://blog.csdn.net/asmcos/article/details/46676053 http://blog.csdn.net/asmcos/article/de

MyBatis 详解(一对一,一对多,多对多)

1.什么是MyBatis? MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis .2013年11月迁移到Github. iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架.iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO). MyBatis 是支持普通 SQL查

mybatis 详解(三)------入门实例(基于注解)

1.创建MySQL数据库:mybatisDemo和表:user 详情参考:mybatis 详解(二)------入门实例(基于XML) 一致 2.建立一个Java工程,并导入相应的jar包,具体目录如下 详情参考:mybatis 详解(二)------入门实例(基于XML) 一致 3.在 MyBatisTest 工程中添加数据库配置文件 mybatis-configuration.xml 详情参考:mybatis 详解(二)------入门实例(基于XML) 一致 4.定义表所对应的实体类 详情

php学习之道:WSDL详解(二)

3.定义服务使用的逻辑消息 当服务的操作被调用时,服务被定义为消息交换.在wsdl文档中,这些消息被定义message元素.这些消息由称之为part元素的部分组成. 一个服务的操作,通过指定逻辑消息的方式来定义.当操作被调用时,逻辑消息被交换.(也就是说,逻辑消息代表了服务的操作)这些逻辑消息,将在网络上传输的数据定义为xml文档.他包含了所有的参数,这些参数是方法调用的一部分.(也就是说,逻辑消息里的参数,是操作对应方法的参数集合) 消息和参数列表:每一个被服务暴露的操作能且仅能有一个输入消息

Python基础知识详解 从入门到精通(七)类与对象

本篇主要是介绍python,内容可先看目录其他基础知识详解,欢迎查看本人的其他文章Python基础知识详解 从入门到精通(一)介绍Python基础知识详解 从入门到精通(二)基础Python基础知识详解 从入门到精通(三)语法与函数Python基础知识详解 从入门到精通(四)列表.元组.字典.集合Python基础知识详解 从入门到精通(五)模块管理Python基础知识详解 从入门到精通(六)文件操作PS:很多人在学习Python的过程中,往往因为遇问题解决不了或者没好的教程从而导致自己放弃,为此

Linux I/O 重定向详解及应用实例

简解 > 输出 < 输入 >> 追加 & [> | < | >>]之前:输入输出; ls /dev &>filename #"&"在这里代表标准输出和标准错误,这里无论是正常输出还是错误信息都写到filename中了. [> | < | >>]之后:重定义文件标志符 echo 123 1>&tmp #相当于 echo 123 : echo 123 > tmp. &q

Android 布局学习之——Layout(布局)详解二(常见布局和布局参数)

[Android布局学习系列]   1.Android 布局学习之——Layout(布局)详解一   2.Android 布局学习之——Layout(布局)详解二(常见布局和布局参数)   3.Android 布局学习之——LinearLayout的layout_weight属性   4.Android 布局学习之——LinearLayout属性baselineAligned的作用及baseline    Layout Parameters(布局参数): 在XML文件中,我们经常看到类似与lay

CSS3中的弹性流体盒模型技术详解(二)

在上一篇文章<CSS3中的弹性流体盒模型技术详解(一)>里,我给大家列出了,从css1到css3各版本中盒子模型的基本元素.本篇我会把余下的属性进行详细讲解. box-pack 作用:用来规定子元素在盒子内的水平空间分配方式 box-pack 语法:box-pack: start | end | center | justify; start 对于正常方向的框,首个子元素的左边缘吸附在盒子的左边框显示 对于相反方向的框,最后子元素的右边缘吸附在盒子的右边框显示 end 对于正常方向的框,最后子

LinearLayout详解二:从其父类View说起

这个View类说来就话长了,但我们又不得不说,要说呢,就得说的彻底,要让大家看得一清二楚,明明白白.所以我们就从源代码角度来看一个view是如何被加载的吧. 如果大家不知道怎么下载android的源代码,或者说懒得去下载(因为源代码确实比较大,大概有10G)的话,教大家几个取巧的办法: 1.直接在google中输入"android view.java"即可.这种方法成功率非常高,一般android的比较重要的类都能搜到. 2.给大家提供一个人家用于放源码的的git:[email pro