一、原生态jdbc程序存在的问题:
mybatis框架原理、执行过程:
二、入门程序
完成入门程序的以下需求:
1)环境搭建:
mybatis下载地址:https://github.com/mybatis/
导入jar包,工程结构:
关于配置文件的配置:
/mybatis/config/log4j.properties:开发环境设置成debug:
1 # Global logging configuration 2 log4j.rootLogger=DEBUG, stdout 3 # Console output... 4 log4j.appender.stdout=org.apache.log4j.ConsoleAppender 5 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 6 log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
/mybatis/config/db.properties:
1 jdbc.driver=com.mysql.jdbc.Driver 2 jdbc.url=jdbc:mysql://localhost:3306/mybatis 3 jdbc.username=root 4 jdbc.password=root
/mybatis/config/SqlMapConfig.xml:mybatis配置文件
这里的是mybatis独立运行的配置,并没有整合:
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 5 <configuration> 6 7 <!-- 加载属性文件 --> 8 <properties resource="db.properties"> 9 <!--properties中还可以配置一些属性名和属性值 --> 10 <!-- <property name="jdbc.driver" value=""/> --> 11 </properties> 12 13 <!-- 和spring整合后 environments配置将废除--> 14 <environments default="development"> 15 <environment id="development"> 16 <!-- 使用jdbc事务管理,事务控制由mybatis--> 17 <transactionManager type="JDBC" /> 18 <!-- 数据库连接池,由mybatis管理--> 19 <dataSource type="POOLED"> 20 <property name="driver" value="${jdbc.driver}" /> 21 <property name="url" value="${jdbc.url}" /> 22 <property name="username" value="${jdbc.username}" /> 23 <property name="password" value="${jdbc.password}" /> 24 </dataSource> 25 </environment> 26 </environments> 27 28 <!-- 加载 映射文件 --> 29 <mappers> 30 <mapper resource="sqlmap/User.xml"/> 31 </mappers> 32 </configuration>
POJO类:/mybatis/src/com/cy/po/User.java:
1 package com.cy.po; 2 3 import java.util.Date; 4 5 public class User { 6 //属性名和数据库表的字段对应 7 private int id; 8 private String username;// 用户姓名 9 private String sex;// 性别 10 private Date birthday;// 生日 11 private String address;// 地址 12 public int getId() { 13 return id; 14 } 15 public void setId(int id) { 16 this.id = id; 17 } 18 public String getUsername() { 19 return username; 20 } 21 public void setUsername(String username) { 22 this.username = username; 23 } 24 public String getSex() { 25 return sex; 26 } 27 public void setSex(String sex) { 28 this.sex = sex; 29 } 30 public Date getBirthday() { 31 return birthday; 32 } 33 public void setBirthday(Date birthday) { 34 this.birthday = birthday; 35 } 36 public String getAddress() { 37 return address; 38 } 39 public void setAddress(String address) { 40 this.address = address; 41 } 42 @Override 43 public String toString() { 44 return "------->> User [id=" + id + ", username=" + username + ", sex=" + sex 45 + ", birthday=" + birthday + ", address=" + address + "]"; 46 } 47 }
User.xmlp配置statement:增、删、改、查
/mybatis/config/sqlmap/User.xml:
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 6 <!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离 7 注意:使用mapper代理方法开发,namespace有特殊重要的作用 8 --> 9 <mapper namespace="test"> 10 <!-- =============================================================================== --> 11 <!-- 在 映射文件中配置很多sql语句 --> 12 <!-- 需求:通过id查询用户表的记录 --> 13 <!-- 通过 select执行数据库查询 14 id:标识 映射文件中的 sql 15 将sql语句封装到mappedStatement对象中,所以将id称为statement的id 16 parameterType:指定输入 参数的类型,这里指定int型 17 #{}表示一个占位符号 18 #{id}:其中的id表示接收输入 的参数,参数名称就是id,如果输入 参数是简单类型,#{}中的参数名可以任意,可以value或其它名称 19 20 resultType:指定sql输出结果 的所映射的java对象类型,select指定resultType表示将单条记录映射成的java对象。 21 --> 22 <select id="findUserById" parameterType="int" resultType="com.cy.po.User"> 23 SELECT * FROM USER WHERE id=#{value} 24 </select> 25 26 <!-- =============================================================================== --> 27 <!-- 根据用户名称模糊查询用户信息,可能返回多条 28 resultType:指定就是单条记录所映射的java对象 类型 29 ${}:表示拼接sql串,将接收到参数的内容不加任何修饰拼接在sql中。 30 使用${}拼接sql,引起 sql注入 31 ${value}:接收输入 参数的内容,如果传入类型是简单类型,${}中只能使用value 32 --> 33 <select id="findUserByName" parameterType="java.lang.String" resultType="com.cy.po.User"> 34 SELECT * FROM USER WHERE username LIKE '%${value}%' 35 </select> 36 37 <!-- =============================================================================== --> 38 <!-- 添加用户 39 parameterType:指定输入 参数类型是pojo(包括 用户信息) 40 #{}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过OGNL获取对象的属性值 41 --> 42 <insert id="insertUser" parameterType="com.cy.po.User"> 43 <!-- 44 自增主键的返回: 45 将插入数据的主键返回,返回到user对象中 46 SELECT LAST_INSERT_ID():得到刚insert进去记录的主键值,只适用与自增主键 47 keyProperty:将查询到主键值设置到parameterType指定的对象的哪个属性 48 order:SELECT LAST_INSERT_ID()执行顺序,相对于insert语句来说它的执行顺序 49 resultType:指定SELECT LAST_INSERT_ID()的结果类型 50 --> 51 <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> 52 SELECT LAST_INSERT_ID() 53 </selectKey> 54 55 <!-- 56 非自增主键返回(使用UUID()) 57 使用mysql的uuid()生成主键 (需要修改表中id字段类型为String,长度设置成35位) 58 执行思路: 59 首先通过uuid()得到主键,将主键输入到sql语句中。 60 执行uuid()语句顺序相对于insert语句之前执行。 61 --> 62 <!-- <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String"> 63 SELECT uuid() 64 </selectKey> 65 insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address}) --> 66 67 <!--通过oracle的序列,生成主键:--> 68 <!-- <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String"> 69 SELECT 序列名.nextval() 70 </selectKey> 71 insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address}) --> 72 73 insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address}) 74 </insert> 75 76 <!-- =============================================================================== --> 77 <!-- 根据id删除 用户,需要输入 id值--> 78 <delete id="deleteUser" parameterType="java.lang.Integer"> 79 delete from user where id=#{id} 80 </delete> 81 82 <!-- =============================================================================== --> 83 <!-- 根据id更新用户 84 分析: 85 需要传入用户的id 86 需要传入用户的更新信息 87 parameterType指定user对象,包括 id和更新信息,注意:id必须存在 88 #{id}:从输入 user对象中获取id属性值 89 --> 90 <update id="updateUser" parameterType="com.cy.po.User"> 91 update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} 92 where id=#{id} 93 </update> 94 </mapper>
测试增删改查的Test代码:
1 package com.cy.first; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.util.Date; 6 import java.util.List; 7 8 import org.apache.ibatis.io.Resources; 9 import org.apache.ibatis.session.SqlSession; 10 import org.apache.ibatis.session.SqlSessionFactory; 11 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 12 import org.junit.Test; 13 14 import com.cy.po.User; 15 16 public class MybatisFirst { 17 18 /* ---------------------------------------------------------------------------------*/ 19 // 根据id查询用户信息,得到一条记录结果 20 @Test 21 public void findUserByIdTest() throws IOException { 22 // mybatis配置文件 23 String resource = "SqlMapConfig.xml"; 24 // 得到配置文件流 25 InputStream inputStream = Resources.getResourceAsStream(resource); 26 27 // 创建会话工厂,传入mybatis的配置文件信息 28 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 29 30 // 通过工厂得到SqlSession 31 SqlSession sqlSession = sqlSessionFactory.openSession(); 32 33 // 通过SqlSession操作数据库 34 // 第一个参数:映射文件中statement的id,等于=namespace+"."+statement的id 35 // 第二个参数:指定和映射文件中所匹配的parameterType类型的参数 36 // sqlSession.selectOne结果 是与映射文件中所匹配的resultType类型的对象 37 // selectOne查询出一条记录 38 User user = sqlSession.selectOne("test.findUserById", 1); 39 40 System.out.println(user); 41 42 // 释放资源 43 sqlSession.close(); 44 45 } 46 47 /* ---------------------------------------------------------------------------------*/ 48 // 根据用户名称模糊查询用户列表 49 @Test 50 public void findUserByNameTest() throws IOException { 51 // mybatis配置文件 52 String resource = "SqlMapConfig.xml"; 53 // 得到配置文件流 54 InputStream inputStream = Resources.getResourceAsStream(resource); 55 56 // 创建会话工厂,传入mybatis的配置文件信息 57 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 58 59 // 通过工厂得到SqlSession 60 SqlSession sqlSession = sqlSessionFactory.openSession(); 61 // list中的user和映射文件中resultType所指定的类型一致 62 List<User> list = sqlSession.selectList("test.findUserByName", "小明"); 63 System.out.println(list); 64 sqlSession.close(); 65 } 66 67 /* ---------------------------------------------------------------------------------*/ 68 // 添加用户信息 69 @Test 70 public void insertUserTest() throws IOException { 71 String resource = "SqlMapConfig.xml"; 72 InputStream inputStream = Resources.getResourceAsStream(resource); 73 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 74 SqlSession sqlSession = sqlSessionFactory.openSession(); 75 // 插入用户对象 76 User user = new User(); 77 user.setUsername("王小军"); 78 user.setBirthday(new Date()); 79 user.setSex("1"); 80 user.setAddress("河南郑州"); 81 82 sqlSession.insert("test.insertUser", user); 83 84 // 提交事务 85 sqlSession.commit(); 86 87 // 获取用户信息主键 88 System.out.println("user id: " + user.getId()); 89 90 // 关闭会话 91 sqlSession.close(); 92 } 93 94 /* ---------------------------------------------------------------------------------*/ 95 // 根据id删除 用户信息 96 @Test 97 public void deleteUserTest() throws IOException { 98 String resource = "SqlMapConfig.xml"; 99 InputStream inputStream = Resources.getResourceAsStream(resource); 100 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 101 SqlSession sqlSession = sqlSessionFactory.openSession(); 102 103 // 传入id删除 用户 104 sqlSession.delete("test.deleteUser", 29); 105 106 sqlSession.commit(); 107 sqlSession.close(); 108 } 109 110 /* ---------------------------------------------------------------------------------*/ 111 // 根据id删除 用户信息 112 @Test 113 public void updateUserTest() throws IOException { 114 String resource = "SqlMapConfig.xml"; 115 InputStream inputStream = Resources.getResourceAsStream(resource); 116 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 117 SqlSession sqlSession = sqlSessionFactory.openSession(); 118 119 // 更新用户信息 120 User user = new User(); 121 //必须设置id 122 user.setId(28); 123 user.setUsername("王大军"); 124 user.setBirthday(new Date()); 125 user.setSex("2"); 126 user.setAddress("河南郑州"); 127 sqlSession.delete("test.updateUser", user); 128 129 sqlSession.commit(); 130 sqlSession.close(); 131 } 132 }
入门程序总结:
1.parameterType和resultType:
parameterType:在映射文件中通过parameterType指定输入 参数的类型。
resultType:在映射文件中通过resultType指定输出结果的类型。
2.#{}和${}:
selectOne表示查询出一条记录进行映射。如果使用selectOne可以实现使用selectList也可以实现(list中只有一个对象)。
selectList表示查询出一个列表(多条记录)进行映射。如果使用selectList查询多条记录,不能使用selectOne。
如果使用selectOne报错:
org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 4
注意点:
1.写xml映射文件,statement的sql insert。select之间的sql语句不要有分号结尾;