MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,而且更名为MyBatis 。html
2013年11月迁移到Github。MyBatis是一个优秀的持久层框架,它对jdbc的操做数据库的过程进行封装,使开发者只须要关注 SQL 自己,而不须要花费精力去处理例如注册驱动、建立connection、建立statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。Mybatis经过xml或注解的方式将要执行的各类statement(statement、preparedStatemnt、CallableStatement)配置起来,并经过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。java
框架介绍mysql
一、 mybatis配置sql
SqlMapConfig.xml,此文件做为mybatis的全局配置文件,配置了mybatis的运行环境等信息。数据库
mapper.xml文件即sql映射文件,文件中配置了操做数据库的sql语句。此文件须要在SqlMapConfig.xml中加载。apache
二、 经过mybatis环境等配置信息构造SqlSessionFactory即会话工厂编程
三、 由会话工厂建立sqlSession即会话,操做数据库须要经过sqlSession进行。缓存
四、 mybatis底层自定义了Executor执行器接口操做数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。session
五、 Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id便是Mapped statement的id。mybatis
六、 Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor经过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
七、 Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor经过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程至关于jdbc编程中对结果的解析处理过程。
<packaging>jar</packaging> <dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.5</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.12</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> </dependencies>
public class User implements Serializable { 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 + "]"; } }
在resources文件夹中,建立Mybatis的主配置文件SqlMapConfig.xml。它是mybatis核
心配置文件,配置文件内容为数据源、事务管理。
配置环境:
- 配置mysql的环境:
- 配置事务的类型;
- 配置链接池:配置链接数据库的4个基本信息;
- 指定映射配置文件的位置:
代码以下:
<?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 default="mysql"> <!--配置mysql的环境--> <environment id="mysql"> <!--配置事务的类型--> <transactionManager type="JDBC"></transactionManager> <!--配置链接池--> <dataSource type="POOLED"> <!--配置链接数据库的4个基本信息--> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://192.168.214.128:3306/mybatis"/> <property name="username" value="root"/> <property name="password" value="ben123"/> </dataSource> </environment> </environments> <!--指定映射配置文件的位置,映射配置文件指的是每一个dao独立的配置文件--> <mappers> <mapper resource="com/ben/dao/IUserDao.xml"/> </mappers> </configuration>
# Set root category priority to INFO and its only appender to CONSOLE. #log4j.rootCategory=INFO, CONSOLE debug info warn error fatal log4j.rootCategory=debug, CONSOLE, LOGFILE # Set the enterprise logger category to FATAL and its only appender to CONSOLE. log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE # CONSOLE is set to be a ConsoleAppender using a PatternLayout. log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n # LOGFILE is set to be a File appender using a PatternLayout. log4j.appender.LOGFILE=org.apache.log4j.FileAppender log4j.appender.LOGFILE.File=d:\axis.log log4j.appender.LOGFILE.Append=true log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
<?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:命名空间,用于隔离sql,还有一个很重要的做用,后面会讲 --> <mapper namespace="test"> </mapper>
<!--指定映射配置文件的位置--> <mappers> <mapper resource="sqlmao/User.xml"/> </mappers>
1. 加载核心配置文件SqlMapConfig.xml 2. 建立SqlSessionFactoryBuilder对象 3. 建立SqlSessionFactory对象(2,3能够写一块儿) 4. 建立SqlSession对象 5. 执行SqlSession对象执行查询,获取结果User 6. 打印结果 7. 释放资源
代码以下:
package com.ben.test; import com.ben.domain.User; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.Date; import java.util.List; /** * @ClassName: MybatisTest * @author: benjamin * @version: 1.0 * @description: TODO * @createTime: 2019/07/13/11:50 */ public class MybatisTest { public static void main(String[] args) { } //经过Id查询一个用户 @Test public void testSearchById() throws IOException { //1.读取配置文件 InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.建立SqlSessionFactory工厂 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in); //3.使用工厂生产SqlSession对象 SqlSession session = sqlSessionFactory.openSession(); //4.执行Sql语句 User user = session.selectOne("test.findUserById", 10); //5. 打印结果 System.out.println(user); //6.释放资源 session.close(); in.close(); } //根据用户名模糊查询用户列表 @Test public void testFindUserByUsername() throws IOException { //1.读取配置文件 InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.建立SqlSessionFactory工厂 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in); //3.使用工厂生产SqlSession对象 SqlSession session = sqlSessionFactory.openSession(); //4.执行Sql语句 List<User> list = session.selectList("test.findUserByUsername", "王"); //5. 打印结果 for (User user:list) { System.out.println(user); } //6.释放资源 session.close(); in.close(); } //添加用户 @Test public void testInsertUser() throws IOException { //1.读取配置文件 InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.建立SqlSessionFactory工厂 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in); //3.使用工厂生产SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //4.执行Sql语句 User user = new User(); user.setUsername("小强"); user.setBirthday(new Date()); user.setAddress("sadfsafsafs"); user.setSex("2"); int i = sqlSession.insert("test.insertUser", user); sqlSession.commit(); //5. 打印结果 // 刚保存用户,此时用户ID须要返回。执行完上面insert程序后,此时就能知道用户的ID是多少 // 须要在User.xml文件中配置 System.out.println("插入id:"+user.getId());//插入id:30 //6.释放资源 sqlSession.close(); in.close(); } //更新用户 @Test public void testUpdateUserById() throws IOException { //1.读取配置文件 InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.建立SqlSessionFactory工厂 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in); //3.使用工厂生产SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //4.执行Sql语句 User user = new User(); user.setId(27); user.setUsername("小小"); user.setBirthday(new Date()); user.setAddress("西安市"); user.setSex("1"); int i = sqlSession.insert("test.updateUserById", user); sqlSession.commit(); //5. 打印结果 System.out.println(user.getId()); //6.释放资源 sqlSession.close(); in.close(); } //删除用户 @Test public void testDeleteUserById() throws IOException { //1.读取配置文件 InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.建立SqlSessionFactory工厂 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in); //3.使用工厂生产SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //4.执行Sql语句 int i = sqlSession.insert("test.deleteUserById", 32); sqlSession.commit(); //5. 打印结果 System.out.println(i); //6.释放资源 sqlSession.close(); in.close(); } }
<?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 namespace="test"> <!-- 经过Id查询一个用户 --> <select id="findUserById" parameterType="Integer" resultType="com.ben.domain.User"> select * from user where id = #{v} </select> <!-- 根据用户名模糊查询用户列表 --> <!-- select * from user where username like '%${value}%'--> <!-- select * from user where username like "%"#{value}"%"--> <select id="findUserByUsername" parameterType="String" resultType="com.ben.domain.User"> select * from user where username like #{username} </select> <!-- 添加用户 --> <insert id="insertUser" parameterType="com.ben.domain.User"> <selectKey keyProperty="id" resultType="Integer" order="AFTER"> select LAST_INSERT_ID() </selectKey> insert into user (username,birthday,address,sex) values(#{username},#{birthday},#{address},#{sex}) </insert> <!-- 更新用户 --> <update id="updateUserById" parameterType="com.ben.domain.User"> update user set username = #{username},sex = #{sex},birthday = #{birthday},address = #{address} where id = #{id} </update> <!-- 删除用户 --> <delete id="deleteUserById" parameterType="Integer"> delete from user where id = #{vvvvv} </delete> </mapper>
namespace:用来区别不一样的类的名字 id:标识映射文件中的sql,称为statement的id将sql语句封装到mappedStatement对象中,因此将id称为statement的id parameterType:指定输入参数的类型. resultType:指定输出结果类型。mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。若是有多条数据,则分别进行映射,并把对象放到容器List中
#{}:一个占位符。preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}能够有效防止sql注入。 #{}能够接收简单类型值或pojo属性值。 若是parameterType传输单个简单类型值,#{}括号中能够是value或其它名称。 ${}:表示拼接sql串,经过${}能够将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换,${}能够接收简单类型值或pojo属性值,若是parameterType传输单个简单类型值,${}括号中只能是value。
这一部分参考mybatis官网。详情点击http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html
<select id="findUserById" parameterType="Integer" resultType="com.ben.domain.User"> select * from user where id = #{v} </select>
这个语句被称做findUserById, 接受一个Integer类型的参数,返回一个User对象。#{V} 告诉mybatis建立一个预处理语句参数,在JDBC中,这个的一个参数在Sql中会由一个“ ?”表示,并被传递到新的预处理语句中,如:
//近似的JDBC代码,并不是Mybatis代码 String findUserById = "select * from user where id = ?"; PreparedStatement ps = conn.prepareStatement(findUserById); ps.setInt(1,id);
使用 JDBC 意味着须要更多的代码来提取结果并将它们映射到对象实例中,而这就是 MyBatis 节省你时间的地方.
1.测试类中这样写: List<User> list = session.selectList("test.findUserByUsername", "王"); 在User.xml中写: select * from user where username like '%${value}%' 其对应的实际sql操做语句:select * from user where username like'%五%' 也能够这样写: select * from user where username like "%"#{value}"%" # value 能够换成haha 其对应的sql查询语句是:select * from user where username like"%"'五'"%" 2.若是测试类中这样写: List<User> list = session.selectList("test.findUserByUsername", "%王%"); User.xml这样写 select * from user where username like #{username} 其中username能够换成haha等其余名称。
<selectKey keyProperty="id" resultType="Integer" order="AFTER"> select LAST_INSERT_ID() </selectKey>