一、MyBatis是什么?
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis,实质上Mybatis对ibatis进行一些改进。
MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
二、基础操作
1.查询操作
(1)数据库准备
(2)实体类创建
public class User implements Serializable{ private int id; private String username;// 用户姓名 private String sex;// 性别 private Date birthday;// 生日 private String address;// 地址 //get、set.... }
(3)配置文件创建
User.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"> <!-- 命名空间,分类管理SQL语句 --> <!-- 注意:在mapper代理时,namespace具有特殊及重要的作用 --> <mapper namespace="test"> <!-- ===============根据ID查询用户信息=============== select: 表明一个MapppedStatement。 id: statement的id,要求在命名空间内唯一。 parameterType: 入参的java类型。 resultType: 查询出的单条结果集对应的java类型。 #{ }: 表示一个占位符。 #{id}: 表明该占位符接受的参数名称为id。注意:如果参数为简单类型#{}里面的参数名称可以是任意定义的。 --> <select id="findUserById" parameterType="int" resultType="com.kiwi.domain.User"> SELECT * FROM USER WHERE id = #{id} </select> </mapper>
SqlMapConfig.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> <!-- 配置mybatis的环境信息,与spring整合之后,该部分将由spring管理 --> <environments default="development"> <environment id="development"> <!-- 配置JDBC事务控制,由mybatis进行管理 --> <transactionManager type="JDBC"></transactionManager> <!-- 配置数据源,采用dbcp连接池 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8" /> <property name="username" value="root" /> <property name="password" value="123456" /> </dataSource> </environment> </environments> <!-- 加载Mapper --> <mappers> <mapper resource="sqlmap/User.xml"/> </mappers> </configuration>
(4)测试类
@Test public void testQuery() throws IOException{ //1.读取配置文件 String resource = "SqlMapConfig.xml"; InputStream is = Resources.getResourceAsStream(resource); //2.根据配置文件创建SqlSessionFactory SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory sqlSessionFactory = builder.build(is); //3.创建SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); /* * 4.SqlSession操作数据,执行增删改查 * 第一个参数: statement ID , namespace.statementID * 第二个参数: param */ User user = sqlSession.selectOne("test.findUserById",1); System.out.println(user); //5.关闭SqlSession sqlSession.close(); }结果:
User [id=1, username=王五, sex=2, birthday=Fri Jul 01 00:00:00 GMT+08:00 2016, address=北京市]
(5)根据名字模糊查询
User.xml
<!-- 根据用户名称模糊查询 ${}:表示一个拼接符 ${value}: ${}中的value表示输入参数的参数名称,注意:如果参数为简单类型${}里面的参数名称只能是value ${}存在SQL注入的风险,但是特殊情况必须使用${},比如order by 后面必须是${columnName} --> <select id="findUserByName" parameterType="java.lang.String" resultType="com.kiwi.domain.User"> SELECT * FROM USER WHERE username LIKE '%${value}%' </select>
Test.java
@Test public void testQueryName() throws IOException{ //1.读取配置文件 String resource = "SqlMapConfig.xml"; InputStream is = Resources.getResourceAsStream(resource); //2.根据配置文件创建SqlSessionFactory SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory sqlSessionFactory = builder.build(is); //3.创建SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); //4.SqlSession操作数据,执行增删改查 List<User> list = sqlSession.selectList("test.findUserByName","小明"); for(User user : list){ System.out.println(user); } //5.关闭SqlSession sqlSession.close(); }结果:
User [id=16, username=张小明, sex=1, birthday=Wed Jul 06 00:00:00 GMT+08:00 2016, address=吉林市]
User [id=22, username=陈小明, sex=1, birthday=Wed Jul 13 00:00:00 GMT+08:00 2016, address=吉林市]
User [id=25, username=陈小明, sex=1, birthday=Fri Jul 01 00:00:00 GMT+08:00 2016, address=长春市]
2.插入操作
(1)保存对象
User.xml
Test.java
结果:
(2)保存对象并返回其主键(自增主键)
User.xml
或者
Test.java
结果:
User [id=29, username=CCC, sex=1, birthday=Fri Jul 01 19:01:19 GMT+08:00 2016, address=北京市海淀区]
一般情况下获取刚插入的数据的id,使用select max(id) from table 是可以的。但在多线程情况下,就不行了。在多用户交替插入数据的情况下max(id)显然不能用。
这就该使用LAST_INSERT_ID了,因为LAST_INSERT_ID是基于Connection的,只要每个线程都使用独立的Connection对象,LAST_INSERT_ID函数将返回该Connection对AUTO_INCREMENT列最新的insert or update操作生成的第一个record的ID。这个值不能被其它客户端(Connection)影响,保证了你能够找回自己的 ID 而不用担心其它客户端的活动,而且不需要加锁。
3.删除操作
User.xml
Test.java
4.修改操作
User.xml
Test.java
结果: