服务器之家

服务器之家 > 正文

在Java的MyBatis框架中建立接口进行CRUD操作的方法

时间:2020-04-15 11:45     来源/作者:红烧狮子头

以接口操作的方式编程
一般来讲,我们建立映射SQL接口的类时通常会这样:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public static void testBasicQuery(int id) {
   SqlSession session = MybatisUtils.getSqlSession();
   try {
     /*
      * 此处的david.mybatis.demo.IVisitorOperation.basicQuery必须和下图中配置里面的namespace对应
      */
     Visitor visitor = (Visitor) session.selectOne("david.mybatis.demo.IVisitorOperation.basicQuery", id);
     MybatisUtils.closeSession(session);
     System.out.println(visitor);
   } catch (Exception e) {
     // TODO: handle exception
   }
 }
?
1
2
3
4
5
6
7
8
<!-- 此处namespace对应的就是你所传的String参数 -->
<mapper namespace="david.mybatis.demo.IVisitorOperation">
<!-- 此处的resultType就是对应刚刚你在typeAlias节点里面规定的别名 -->
  <select id="basicQuery" parameterType="int" resultType="Visitor">
    select * from visitor where id=#{id} and
    Status>0 order by Id
  </select>
</mapper>

这样其实在真正的开发过程中如果两边的名字一不小心没有对应上,就会出现异常。为了避免这样的情况我们可以采取接口的方式来进行相应的操作,下面我们来修改这段东西。

首先我们在包名为david.mybatis.demo的下面新建一个IVisitOperation类,表示今后将要操作数据库所有方法的接口,如下所示:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package david.mybatis.demo;
 
import java.util.List;
 
import david.mybatis.model.PagenateArgs;
import david.mybatis.model.Visitor;
 
public interface IVisitorOperation { 
  /*
   * 基础查询
   */
  public Visitor basicQuery(int id);
}
 
  public static void testBasicQueryByInterfaceWay(int id) {
    SqlSession session = MybatisUtils.getSqlSession();
    try {
      IVisitorOperation vOperation = session.getMapper(IVisitorOperation.class);
      Visitor visitor = vOperation.basicQuery(id);
      MybatisUtils.closeSession(session);
      System.out.println(visitor);
    } catch (Exception e) {
      // TODO: handle exception
    }
  }

这样就大功告成了,这样我们就不必为手动书写方法名可能导致的不匹配而烦恼了。

CRUD操作
下面将讲解创建基于单表操作的CRUD与GetList操作,为了创建一点测试数据我们先弄个Add方法吧

继续在上次的IVisitorOperation接口类中添加add,delete,update,query与getList接口方法,如下所示:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
 * 基础查询
 */
public Visitor basicQuery(int id);
 
/*
 * 添加访问者
 */
public int add(Visitor visitor);
 
/*
 * 删除访问者
 */
public int delete(int id);
 
/*
 * 更新访问者
 */
public int update(Visitor visitor);
 
/*
 * 查询访问者
 */
public Visitor query(int id);
 
/*
 * 查询访问者List
 */
public List<Visitor> getList();

对于相应的CRUD操作,在VisitorMapper.xml的<mapper>节点下分别对应insert,update,delete,select节点,具体配置详情参数说明课参照官网 http://mybatis.github.io/mybatis-3/sqlmap-xml.html
这个示例中要的配置如下,传递的参数用#{parameter_name},当然也可直接用${parameter_name},

前者的方式,Mybatis会把它转化为参数化的形式例如 insert into table (name) values (#{name}) => insert into table (name) values ( ? ) (Mysql情况下)

后者的方式,Mybatis会原封不动的不做任何操作把参数传过来,例如  insert into table (name) values (${name}) => insert into table (name) values ( [你所传的值] ),传aa,这里就是aa,传'aa'这里就是'aa'。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?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="david.mybatis.demo.IVisitorOperation">
  <!--
    useGeneratedKeys="true"代表是否使用自增长序列,
    keyProperty="Id"指定自增长列是哪一列,
    parameterType="Visitor"指定IVisitorOperation接口类中定义中所传的相应类型
    resultType 表示返回的类型,例如query中的visitor
    resultMap 自定义的返回类型,是返回复杂类型是的最佳首选,也是mybatis里最强大的武器
   -->
  <insert id="add" parameterType="Visitor" useGeneratedKeys="true"
    keyProperty="Id">
    insert into Visitor (Name, Email, Status, CreateTime)
    values (#{name}, #{email}, #{status}, #{createTime})
  </insert>
  <delete id="delete" parameterType="int">
    delete from Visitor where
    status>0 and id = #{id}
  </delete>
  <update id="update" parameterType="Visitor">
    update Visitor set Name =
    #{name}, Email=#{email}, Status=#{status} where id=#{id} and Status>0;
  </update>
  <select id="query" parameterType="int" resultType="Visitor">
    select Id,
    Name, Email, Status, CreateTime from visitor where id=#{id} and
    Status>0 order by Id
  </select>
  <select id="basicQuery" parameterType="int" resultType="Visitor">
    select * from visitor where id=#{id} and
    Status>0 order by Id
  </select>
  <select id="getList" resultMap="visitorRs">
    <include refid="getListSql" />
  </select>
  <resultMap type="Visitor" id="visitorRs">
    <id column="Id" property="id" />
    <result column="Name" property="name" />
    <result column="Email" property="email" />
    <result column="Status" property="status" />
    <result column="CreateTime" property="createTime" />
  </resultMap>
  <sql id="getListSql">
    select * from Visitor where
    status>0
  </sql>
</mapper>

此处注意的一点是:操作节点中的ID要对应接口定义中的接口名字,参数类型也要相应对应,例如接口里是add(Visitor visitor),那么在配置insert节点的时候id="add",parameterType="Visitor"

否则会报相应的异常,例如id节点不对应接口名称会出现如下异常:

在Java的MyBatis框架中建立接口进行CRUD操作的方法

大家可以注意到在VisitorMapper.xml这个配置文件中在获取list的时候,使用的是resultMap,使用resultMap的情况下你可以指定你自己的sql语句与哪些字段相映射,因为有时候你可以不需要那么多列,那你在配置映射的时候也不需要配置那么多映射,或者说你的列有起过别名,那么就不能直接使用resultType="Visitor"的方式进行映射,因为Mybatis默认映射方式是通过Javabean的属性名与表的字段是否一致来匹配的,也可以通过配置<configuration>节点下的<settings>属性值来控制是否映射的时候以Javabean中的驼峰命名方式配置如下。

?
1
2
3
<settings>
  <setting name="mapUnderscoreToCamelCase" value="false" />
</settings>

具体其他修改Mapper的其他配置可以通过 http://mybatis.github.io/mybatis-3/configuration.html#settings 查看。
对于Visitor的Mapper类如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<mapper namespace="david.mybatis.demo.IVisitorOperation">
  <sql id="getListSql">
    select id as visitor_id, name, email, status, createtime from Visitor where
    status>0
  </sql>
  <select id="getList" resultMap="visitorRs">
    <include refid="getListSql" />
  </select>
  <!--
    这里指的注意的地方是property属性,里面的字段一定要和你在实体里面定义的属性一样,此处区分大小写
    否则会出现默认setter为属性赋值的时候找不到相应属性的异常,大家可以试下
    column属性对应于查询语句返回结果集的名字,如果有为相应字段起过别名例如吧id变为了visitor_id
    那么相应的column名字也要对应上
  -->
  <resultMap type="Visitor" id="visitorRs">
    <id column="visitor_id" property="id" />
    <result column="Name" property="name" />
    <result column="Email" property="email" />
    <result column="Status" property="status" />
    <result column="CreateTime" property="createTime" />
  </resultMap>
</mapper>

这里要大家还会注意到有一个节点<sql>节点,这个的用处就是提取公用的sql语句或者说字段,以便其他地方复用,其他详细说明用法可以参照 http://mybatis.github.io/mybatis-3/sqlmap-xml.html。
剩下的就是和刚刚一样的操作了,大家可以在demo程序里建立一个DemoRun的类存放各类测试方法,如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package david.mybatis.demo;
 
import java.util.Arrays;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import david.mybatis.model.BasicQueryArgs;
import david.mybatis.model.CRUD_Enum;
import david.mybatis.model.Channel;
import david.mybatis.model.PagenateArgs;
import david.mybatis.model.Visitor;
import david.mybatis.model.Website;
 
public class DemoRun {
 
  public static void testBasicQuery(int id) {
    SqlSession session = MybatisUtils.getSqlSession();
    try {
      /*
       * 此处的david.mybatis.demo.IVisitorOperation.basicQuery必须和下图中配置里面的namespace对应
       */
      Visitor visitor = (Visitor) session.selectOne("david.mybatis.demo.IVisitorOperation.basicQuery", id);
      MybatisUtils.closeSession(session);
      System.out.println(visitor);
    } catch (Exception e) {
      // TODO: handle exception
      e.printStackTrace();
    }
  }
  
  public static void testBasicQueryByInterfaceWay(int id) {
    SqlSession session = MybatisUtils.getSqlSession();
    try {
      IVisitorOperation vOperation = session.getMapper(IVisitorOperation.class);
      Visitor visitor = vOperation.basicQuery(id);
      MybatisUtils.closeSession(session);
      System.out.println(visitor);
    } catch (Exception e) {
      // TODO: handle exception
      e.printStackTrace();
    }
  }
 
  /*
   * 批量添加访问者记录
   */
  public static void addVisitors() {
    SqlSession session = MybatisUtils.getSqlSession();
    List<Visitor> visitors = Arrays.asList(new Visitor[] { new Visitor("mongodb", "mongodb@gmail.com"),
        new Visitor("redis", "redis@gmail.com"), new Visitor("memcached", "memcached@gmail.com"),
        new Visitor("CouchDB", "CouchDB@gmail.com"), new Visitor("HBase", "HBase@gmail.com"),
        new Visitor("Bigtable", "Bigtable@gmail.com"), new Visitor("Hive", "Hive@gmail.com"),
        new Visitor("MapReduce", "MapReduce@gmail.com"), });
 
    for (Visitor visitor : visitors) {
      addVisitor(visitor, session);
    }
    MybatisUtils.closeSession(session);
    MybatisUtils.showMessages(CRUD_Enum.List, visitors.size());
  }
 
  /*
   * 添加访问者信息
   */
  @SuppressWarnings("unused")
  private static void addVisitor(Visitor visitor, SqlSession session) {
    if (session == null)
      session = MybatisUtils.getSqlSession();
    IVisitorOperation vOperation = session.getMapper(IVisitorOperation.class);
    int recordCount = vOperation.add(visitor);
    session.commit();
    if (session == null)
      MybatisUtils.closeSession(session);
    MybatisUtils.showMessages(CRUD_Enum.Add, recordCount);
  }
 
  /*
   * 重载添加访问者
   */
  public static void addVisitor(Visitor visitor) {
    addVisitor(visitor, null);
  }
 
  /*
   * 删除访问者信息
   */
  public static void deleteVisitor(int id) {
    SqlSession session = MybatisUtils.getSqlSession();
    IVisitorOperation vOperation = session.getMapper(IVisitorOperation.class);
    int recordCount = vOperation.delete(id);
    session.commit();
    MybatisUtils.closeSession(session);
    MybatisUtils.showMessages(CRUD_Enum.Delete, recordCount);
  }
 
  /*
   * 更新访问者信息
   */
  public static void updateVisitor(int id) {
    SqlSession session = MybatisUtils.getSqlSession();
    IVisitorOperation vOperation = session.getMapper(IVisitorOperation.class);
    Visitor visitor = vOperation.query(id);
    System.out.println("原始对象:" + visitor);
    String name = visitor.getName();
    if (name.contains("updated")) {
      visitor.setName(name.substring(0, name.indexOf("updated")));
    } else {
      visitor.setName(name + "updated");
    }
    int recordCount = vOperation.update(visitor);
    session.commit();
    MybatisUtils.closeSession(session);
    MybatisUtils.showMessages(CRUD_Enum.Update, recordCount);
    System.out.println("更新后对象:" + visitor);
  }
 
  /*
   * 查询访问者信息
   */
  public static void queryVisitor(int id) {
    SqlSession session = MybatisUtils.getSqlSession();
    IVisitorOperation vOperation = session.getMapper(IVisitorOperation.class);
    Visitor visitor = vOperation.query(id);
    MybatisUtils.closeSession(session);
    MybatisUtils.showMessages(CRUD_Enum.Query, 1);
    System.out.println(visitor);
  }
 
  /*
   * 查询访问者列表
   */
  public static void queryVisitorList() {
    SqlSession session = MybatisUtils.getSqlSession();
    IVisitorOperation vOperation = session.getMapper(IVisitorOperation.class);
    List<Visitor> visitors = vOperation.getList();
    for (Visitor visitor : visitors) {
      System.out.println(visitor);
    }
    MybatisUtils.closeSession(session);
    MybatisUtils.showMessages(CRUD_Enum.List, visitors.size());
  
}

DemoRun类
运行一下后一个简单的基于单表CRUD,DEMO就完成啦

在Java的MyBatis框架中建立接口进行CRUD操作的方法

标签:

相关文章

热门资讯

沙雕群名称大全2019精选 今年最火的微信群名沙雕有创意
沙雕群名称大全2019精选 今年最火的微信群名沙雕有创意 2019-07-07
玄元剑仙肉身有什么用 玄元剑仙肉身境界等级划分
玄元剑仙肉身有什么用 玄元剑仙肉身境界等级划分 2019-06-21
男生常说24816是什么意思?女生说13579是什么意思?
男生常说24816是什么意思?女生说13579是什么意思? 2019-09-17
超A是什么意思 你好a表达的是什么
超A是什么意思 你好a表达的是什么 2019-06-06
华为nova5pro和p30pro哪个好 华为nova5pro和华为p30pro对比详情
华为nova5pro和p30pro哪个好 华为nova5pro和华为p30pro对比详情 2019-06-22
返回顶部