myBatis数据层实现,利用SpringMVC其实就是编制三种文件。这三种文件是:
1、对象的实体类:编制之后存放在com.jiahe.rest.demo2.models中,或者com.jiahe.rest.demo2.vo
2、编制myBatis的SQL映射文件:编制之后存放在com.jiahe.rest.demo2.dao中
3、编制dao的接口文件:编制之后存放在com.jiahe.rest.demo2.dao中
这三种文件,每种文件都有一定的要求:
1、对象的实体类:
A、继承于Serializable,可序列化
B、所有数据类型都用结构的,如各种32位以下的整数都弄成Integer,64位的整数为Long,double为Double,string为String
C、日期类型的,都改成String。目前主要用Json通信,日期没有统一的序列化标准,多平台使用就乱了,所以统一成String格式。
D、实体类名和实体的各个字段,可以和数据库不一致,写成通信中需求的。不一致,通过myBatis的SQL映射文件来协调。
2、编制myBatis的SQL映射文件
A、每个映射文件,都是xml文件
B、映射文件添加Mapper的识别符,如实体Student,我们把映射文件写成StudentMapper.xml
C、其它要求,以下例子说明
3、dao的接口文件
A、每一个接口文件,我们都名称成xxxMapper.java(当然可以自己喜欢的xxxxDao.java之类的)
B、接口中的每个方法,都对应myBatis的SQL映射文件中定义的一个sql的id。方法可以比myBatis的SQL映射文件中的sql少,多了大家都知道,会错的
下面,直接代码说明
一、数据库准备
在前面 的配置文件中,我们已经配置成mysql,下面所有的数据库操作都是mysql.
1、建立数据库 restdb -->CREATE DATABASE `restdb`CHARACTER SET utf8 COLLATE utf8_general_ci;
2、建立表 cy_dishes_cook
CREATE TABLE `cy_dishes_cook` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`merchant_id` int(11) NOT NULL COMMENT '商家id',
`name` varchar(50) DEFAULT NULL COMMENT '名称',
`sort_no` int(11) DEFAULT '999' COMMENT '排序值',
`cooking_type_id` varchar(36) NOT NULL COMMENT '烹饪方式id',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1142 DEFAULT CHARSET=utf8 COMMENT='商家菜品烹饪方式表'
表的要求,
A、第一个下划线之前是表的前缀,用于识别、区分、分类等。
B、表名中所有字符都是小写
C、字段要求,每个单词之间下划线分割
D、字段名称中所有字符都是小写
二、model编写
public class DishesCook implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String cookingTypeId;
private Long merchantId;
private String name;
private int sortNo;
...ToAdd get/set 利用Eclipse生产各个属性的get\set
...ToAdd toString() 利用Eclipse生产实例的字符串转换
...ToAdd Constructors from super 利用Eclipse生产默认构造函数
...ToAdd Constructor use fields 利用Eclipse生产全字段的构造函数
}
说明:
1、类名,数据库表名去前缀后采用Pascial方式命名。
2、属性,数据库字段采用Camel方式命名。
3、我们使用的JSON解析器要用到“全字段的构造函数”,所以model一定要按照上面例子书写.
三、myBatis的SQL映射文件
<?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="com.jiahe.rest.demo2.dao.DishesCookMapper"> 这个和我们的dao接口类的名称相同
<resultMap type="DishesCook" id="mDishesCook">
type是model中编写的实体对象名称,加上前缀之后可以是任意的如:com.jiahe.rest.demo2.vo.XXXX
id是区分别的resultMap,保持唯一,在下面的查询中需要用到
<id column="id" property="id"/> column 数据库中的字段;property 对象中德属性
<result column="merchant_id" property="merchantId"/>
<result column="name" property="name"/>
<result column="sort_no" property="sortNo"/>
<result column="cooking_type_id" property="cookingTypeId"/>
</resultMap>
<!-- insert 增加-->
1、insert的sql语句用<insert/>标签;2、parameterType为实体对象名称,表示接受一个对象
2、自增长字段处理,把最后的字增id赋值给keyProperty指定的字段,然后返回给接受的对象
<insert id="insert" parameterType="DishesCook">
insert into restdb.cy_dishes_cook(merchant_id,name,sort_no,cooking_type_id)
values(#{merchantId},#{name},#{sortNo},#{cookingTypeId})
<!-- 自增长字段-->
<selectKey keyProperty="id" resultType="long" order="AFTER">
select LAST_INSERT_ID() AS id
</selectKey>
</insert>
<!-- update 修改-->
1、update的sql语句用<update/>标签;2、parameterType为实体对象名称,表示接受一个对象
2、<set/>标签,用于去掉多余的逗号
3、<if test=“”/〉标签,用于判断检查
<update id="update" parameterType="DishesCook">
update restdb.cy_dishes_cook
<set>
<if test="merchantId != null and merchantId != 0">merchant_id=#{merchantId},</if>
<if test="name != null and name != ''">name=#{name},</if>
<if test="sortNo != null and sortNo != ''">sort_no=#{sortNo},</if>
<if test="cookingTypeId != null and cookingTypeId != ''">cooking_type_id=#{cookingTypeId},</if>
</set>
where id= #{id}
</update>
<!-- deleteByCondition 条件删除-->
1、delete的sql语句用<delete/>标签;2、parameterType为实体对象名称,表示接受一个对象
<delete id="deleteByCondition" parameterType="DishesCook" >
delete from restdb.cy_dishes_cook
<include refid="ifWhere"/>
</delete>
<!-- deleteByID 删除-->
<delete id="deleteByID" parameterType="DishesCook" >
delete from restdb.cy_dishes_cook
where id=#{id}
</delete>
<!-- findByID 主键查询-->
<select id="findByID" resultMap="mDishesCook" parameterType="DishesCook">
select * from restdb.cy_dishes_cook
where id= #{id}
</select>
<!-- findByCondition 条件查询-->
<select id="findByCondition" resultMap="mDishesCook" parameterType="DishesCook">
select * from restdb.cy_dishes_cook
<include refid="ifWhere"/>
order by sort_no
</select>
<!-- findCountByCondition 条件的数量-->
<select id="findCountByCondition" parameterType="DishesCook" resultType="long">
select count(*) from restdb.cy_dishes_cook
where id= #{id}
</select>
1、公共sql语句定义,用<sql/>标签
2、<where/>标签,用于去掉多余的and,例如错误的sql select * from restdb.cy_dishes_cook where and merchant_id=1 多了and
<sql id="ifWhere">
<where>
<if test="merchantId != null and merchantId != 0">and merchant_id=#{merchantId}</if>
<if test="cookingTypeId != null and cookingTypeId != ''">and cooking_type_id=#{cookingTypeId}</if>
<if test="id!=null and id!=0">and id=#{id}</if>
</where>
</sql>
仔细领会上面的,注意以下几个方面
1、命名空间指向dao中的接口类
2、对象和数据库字段的对应,可以这样理解;但也不能这样理解,应该理解为select所选择的字段
3、对象和字段的映射,可以根据需要定义多个,由<select>标签的resultMap指定
4、公共语句,可以用<sql>单独定义
5、update语句中不确定字段修改所使用的<set/>标签
6、where 语句中不确定的条件所使用的<where/>标签
7、输入、输出参数的注意
8、我们会发现这个映射文件非常的有规律,当然就可以用代码生成机制进行处理了
去掉红色字,是完整的一个映射文件,就可以实际使用
三、dao的接口文件
在com.jiahe.rest.demo2.dao下,新建一个接口类DishesCookMapper.java
public interface DishesCookMapper {
public int insert(DishesCook dishesCook);
public int update(DishesCook dishesCook);
public int deleteByCondition(DishesCook dishesCook);
public int deleteByID(DishesCook dishesCook);
public List<DishesCook> findByCondition(DishesCook dishesCook);
public DishesCook findByID(DishesCook dishesCook);
public Long findCountByCondition(DishesCook dishesCook);
}
这个接口类中的每个方法都和映射文件一一对应
至此,myBatis数据层实现就完成了,只要注意几点非常容易。