Mybatis学习(1)

一、原生态jdbc程序存在的问题:

mybatis框架原理、执行过程:

 

二、入门程序

完成入门程序的以下需求:

1.根据用户id(主键)查询用户信息:
2.根据用户名称模糊查询用户信息:
3.添加用户
4.根据id删除用户:
5.根据id更新用户:

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
View Code

/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实体类

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 }
Juit测试代码

 

入门程序总结:

1.parameterType和resultType:

parameterType:在映射文件中通过parameterType指定输入 参数的类型。

resultType:在映射文件中通过resultType指定输出结果的类型。

2.#{}和${}:

#{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojo、hashmap。
如果接收简单类型,#{}中可以写成value或其它名称。
#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
 
${}表示一个拼接符号,会引用sql注入,所以不建议使用${}。
${}接收输入参数,类型可以是简单类型,pojo、hashmap。
如果接收简单类型,${}中只能写成value。
${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
 
3.selectOne和selectList:

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语句不要有分号结尾;

 

 

posted on 2017-01-10 23:34  有点懒惰的大青年  阅读(248)  评论(0编辑  收藏  举报