背景
这段时间去另一个项目组做一个spring mvc + mybatis的项目,因为我以前从来没有接触过这方面的技术(T_T)所以刚开始遇到了一些困难,在此记录一下自己的错误,本人小白,说的错误的地方还请前辈指出
新奇点
使用xml配置数据库的DAO方法
以前我们用hibernate配置数据库的时候是使用注解的,增删改查放在DAO层,而在这个项目中的mybatis是使用xml写增删改查的方法的,挺像普通的sql语句。就是在xml文件中有select、insert、update和delete方法,举例来说吧
<?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是用来告诉entity有哪些DAO方法的一个接口,比如说我这里的Shop实体有insert方法,那么我在ShopMapper接口中就可以加入insert方法 -->
<mapper namespace="com.myProject.dao.ShopMapper">
<!-- 指明实体类是model目录下的Shop,和这个Shop有哪些所对应的字段,可能不全是Shop实体类中的属性哦,比如说pageSize就不必放在数据库表中 -->
<resultMap id="BaseResultMap" type="com.myProject.model.Shop">
<!-- 指定数据类型 -->
<id column="ID" property="id" jdbcType="INTEGER" />
<result column="shopAddr" property="shopAddr" jdbcType="VARCHAR" />
<result column="shopIcon" property="shopIcon" jdbcType="VARCHAR" />
<result column="shopName" property="shopName" jdbcType="VARCHAR" />
<result column="shopStatus" property="shopStatus" jdbcType="INTEGER" />
<result column="userId" property="userId" jdbcType="INTEGER" />
</resultMap>
<!-- 定义唯一标签???应该是在后面设置resultMap的时候快捷指定用的 -->
<sql id="Base_Column_List">
ID, shopAddr, shopIcon, shopName, shopStatus, userId
</sql>
<!-- -->
<select id="selectByPrimaryKey" resultMap="BaseResultMap"
parameterType="java.lang.Integer">
select
<include refid="Base_Column_List" />
from shop
where ID = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete from shop
where ID = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="com.myProject.model.Shop">
insert into shop (ID, shopAddr, shopIcon,
shopName, shopStatus, userId)
values (#{id,jdbcType=INTEGER}, #{shopAddr,jdbcType=VARCHAR},
#{shopIcon,jdbcType=VARCHAR},
#{shopName,jdbcType=VARCHAR}, #{shopStatus,jdbcType=INTEGER}, #{userId,jdbcType=INTEGER})
</insert>
<!-- 有选择性的插入数据 -->
<insert id="insertSelective" parameterType="com.myProject.model.Shop"
useGeneratedKeys="true" keyProperty="id">
insert into shop
<!-- prefix和suffix是在其前后添加括号,suffixOverrides是自动判断后置 -->
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
ID,
</if>
<if test="shopAddr != null">
shopAddr,
</if>
<if test="shopIcon != null">
shopIcon,
</if>
<if test="shopName != null">
shopName,
</if>
<if test="shopStatus != null">
shopStatus,
</if>
<if test="userId != null">
userId,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=INTEGER},
</if>
<if test="shopAddr != null">
#{shopAddr,jdbcType=VARCHAR},
</if>
<if test="shopName != null">
#{shopName,jdbcType=VARCHAR},
</if>
<if test="shopIcon != null">
#{shopIcon,jdbcType=VARCHAR},
</if>
<if test="shopStatus != null">
#{shopStatus,jdbcType=INTEGER},
</if>
<if test="userId != null">
#{userId,jdbcType=INTEGER},
</if>
</trim>
</insert>
<update id="updateByPrimarykey" parameterType="com.myProject.model.Shop">
update shop
set shopAddr = #{shopAddr,jdbcType=VARCHAR},
shopIcon = #{shopIcon,jdbcType=VARCHAR},
shopName = #{shopName,jdbcType=VARCHAR},
shopStatus = #{shopStatus,jdbcType=INTEGER},
where ID = #{id,jdbcType=INTEGER}
</update>
<select id="getShopList" parameterType="com.myProject.model.Shop"
resultMap="BaseResultMap">
select
s.ID, s.shopAddr, s.shopIcon, s.shopName, s.shopStatus
from shop s
<!-- 这里的1=1不懂是用来干嘛的,反正一直为true也起不到用作条件的作用 -->
where 1=1
<if test="shopAddr!=null and shopAddr!=''">
and s.shopAddr like '%${shopAddr}%'
</if>
<if test="shopName != null and shopAddr!=''">
and s.shopName = #{shopName,jdbcType=VARCHAR}
</if>
<if test="shopStatus != null and shopStatus != 0">
and s.shopStatus = #{shopStatus,jdbcType=INTEGER}
</if>
order by s.ID asc
<if test="pageIndex!=null">
limit #{pageIndex},#{pageSize}
</if>
</select>
</mapper>
这样就可以配置出一个实体类的相关DAO方法了,感觉比直接用Java代码写DAO要难,谁让我数据库学得不好呢~
@Autowired自动注入
举个例子,如果有一个商品列表控制器他需要对商品Comm和店铺Shop进行相关操作,那么我们就应该在这个控制器类加入这两个实体类的Service,按照我以前的方法可能就是用new ClassPathXmlApplicationContext(“beans.xml”).getBean(name)的方式去获取一个Service的bean,而在这里则是使用注解Autowired自动注入的,不需要new什么东西,所以这个商品列表控制器可以这样写
package com.myProject.controller;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.myProject.model.Comm;
import com.myProject.model.Shop;
import com.myProject.service.CommService;
import com.myProject.service.ShopService;
@Controller
@RequestMapping(value="/comm")
public class CommController {
@Autowired
private CommService commService;
@Autowired
private ShopService shopSerivce;
/**
* 获取指定店铺的商品列表
* @param request
* @return
*/
@RequestMapping(value="/system/getCommList.do")
/** 这里的参数也好神奇的,如果我在这个方法中需要new一个People,不需要在方法里面写new Person(),而是直接把People people这个形参当作方法的参数传递过去,直接就用这个people,不需要new **/
public @ResponseBody Map<String, Object> getCommList(HttpServletRequest request) {
String strIndex = request.getParameter("pageIndex");
String strSize = request.getParameter("pageSize");
Integer shopId = Integer.parseInt(request.getParameter("shopId"));
Shop shop = this.shopSerivce.selectByPrimaryKey(shopId);
int pageIndex = 0;
int pageSize = 10;
if(strIndex.isEmpty() || strIndex.equals("")) {} else {
try {
pageIndex = Integer.parseInt(strIndex);
} catch(ClassCastException e) {
}
}
if(strSize.isEmpty() || strSize.equals("")) {} else {
try {
pageSize = Integer.parseInt(strSize);
} catch(ClassCastException e) {
}
}
Comm comm = new Comm();
comm.setShopId(shopId);
comm.setPageIndex(pageIndex);
comm.setPageSize(pageSize);
List<Comm> comms = this.commService.getCommList(comm);
Map<String, Object> map = new HashMap<String, Object>();
map.put("shop", shop);
map.put("commlist", comms);
return map;
}
<!-- 只是用来插入数据的方法 -->
@RequestMapping(value="/system/initComm.do")
@Transactional(isolation = Isolation.READ_COMMITTED)
public @ResponseBody Map<String,Object> init() throws Exception {
Map<String, Object> map = new HashMap<String, Object>();
for(int i = 0; i < 20; i++) {
Comm comm = new Comm();
comm.setCommIcon("images/mobile/page/shaxianxiaochi.jpg");
comm.setCommName("商品"+i);
comm.setCommPrice(new BigDecimal(Math.random()*10.0));
comm.setCommStatus(1);
comm.setShopId(1);
this.commService.insert(comm);
}
return null;
}
}
一个完整的实体和相关功能
首先要有一个实体类,比如说Shop,在这个Shop实体类里面除了要写上ShopAddr、ShopName等属性还可以写上pageSize和pageIndex用来查询指定范围内的Shop列表,之后在xml配置出这个实体类的相关DAO方法,之后创建一个ShopMapper店铺映射接口,里面定义了ShopService的方法,之后再写一个也一个一模一样的ShopService接口,虽然我也不懂是用来干嘛的,再然后呢就创建一个ShopServiceImpl类去实现ShopService接口,在这个实现类里面要申明一个ShopMapper属性,之后就实现这接口的方法,方法的内容也只是this.shopMapper.methodName而已。一下是一个完整的例子
实体类
package com.myProject.model;
/**
* 店铺实体
* @author Slience
*
*/
public class Shop {
private Integer id;
private String shopAddr;
private String shopIcon;
private String shopName;
private Integer shopStatus;
private Integer userId;
private Integer pageSize;
private Integer pageIndex;
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getPageIndex() {
return pageIndex;
}
public void setPageIndex(Integer pageIndex) {
this.pageIndex = pageIndex;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getShopAddr() {
return shopAddr;
}
public void setShopAddr(String shopAddr) {
this.shopAddr = shopAddr;
}
public String getShopIcon() {
return shopIcon;
}
public void setShopIcon(String shopIcon) {
this.shopIcon = shopIcon;
}
public String getShopName() {
return shopName;
}
public void setShopName(String shopName) {
this.shopName = shopName;
}
public Integer getShopStatus() {
return shopStatus;
}
public void setShopStatus(Integer shopStatus) {
this.shopStatus = shopStatus;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
}
mybatis配置文件
<?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.myProject.dao.ShopMapper">
<resultMap id="BaseResultMap" type="com.myProject.model.Shop">
<id column="ID" property="id" jdbcType="INTEGER" />
<result column="shopAddr" property="shopAddr" jdbcType="VARCHAR" />
<result column="shopIcon" property="shopIcon" jdbcType="VARCHAR" />
<result column="shopName" property="shopName" jdbcType="VARCHAR" />
<result column="shopStatus" property="shopStatus" jdbcType="INTEGER" />
<result column="userId" property="userId" jdbcType="INTEGER" />
</resultMap>
<sql id="Base_Column_List">
ID, shopAddr, shopIcon, shopName, shopStatus, userId
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap"
parameterType="java.lang.Integer">
select
<include refid="Base_Column_List" />
from shop
where ID = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete from shop
where ID = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="com.myProject.model.Shop">
insert into shop (ID, shopAddr, shopIcon,
shopName, shopStatus, userId)
values (#{id,jdbcType=INTEGER}, #{shopAddr,jdbcType=VARCHAR},
#{shopIcon,jdbcType=VARCHAR},
#{shopName,jdbcType=VARCHAR}, #{shopStatus,jdbcType=INTEGER}, #{userId,jdbcType=INTEGER})
</insert>
<insert id="insertSelective" parameterType="com.myProject.model.Shop"
useGeneratedKeys="true" keyProperty="id">
insert into shop
<!-- prefix和suffix是在其前后添加括号,suffixOverrides是自动判断后置 -->
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
ID,
</if>
<if test="shopAddr != null">
shopAddr,
</if>
<if test="shopIcon != null">
shopIcon,
</if>
<if test="shopName != null">
shopName,
</if>
<if test="shopStatus != null">
shopStatus,
</if>
<if test="userId != null">
userId,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=INTEGER},
</if>
<if test="shopAddr != null">
#{shopAddr,jdbcType=VARCHAR},
</if>
<if test="shopName != null">
#{shopName,jdbcType=VARCHAR},
</if>
<if test="shopIcon != null">
#{shopIcon,jdbcType=VARCHAR},
</if>
<if test="shopStatus != null">
#{shopStatus,jdbcType=INTEGER},
</if>
<if test="userId != null">
#{userId,jdbcType=INTEGER},
</if>
</trim>
</insert>
<update id="updateByPrimarykey" parameterType="com.myProject.model.Shop">
update shop
set shopAddr = #{shopAddr,jdbcType=VARCHAR},
shopIcon = #{shopIcon,jdbcType=VARCHAR},
shopName = #{shopName,jdbcType=VARCHAR},
shopStatus = #{shopStatus,jdbcType=INTEGER},
where ID = #{id,jdbcType=INTEGER}
</update>
<select id="getShopList" parameterType="com.myProject.model.Shop"
resultMap="BaseResultMap">
select
s.ID, s.shopAddr, s.shopIcon, s.shopName, s.shopStatus
from shop s
where 1=1
<if test="shopAddr!=null and shopAddr!=''">
and s.shopAddr like '%${shopAddr}%'
</if>
<if test="shopName != null and shopAddr!=''">
and s.shopName = #{shopName,jdbcType=VARCHAR}
</if>
<if test="shopStatus != null and shopStatus != 0">
and s.shopStatus = #{shopStatus,jdbcType=INTEGER}
</if>
order by s.ID asc
<if test="pageIndex!=null">
limit #{pageIndex},#{pageSize}
</if>
</select>
</mapper>
Mapper接口
package com.myProject.dao;
import java.util.List;
import com.myProject.model.Shop;
public interface ShopMapper {
int deleteByPrimaryKey(Integer id);
int insert(Shop shop);
int insertSelective(Shop shop);
Shop selectByPrimaryKey(Integer id);
int updateByPrimarykey(Shop shop);
//获取指定菜单列表
public List<Shop> getShopList(Shop shop);
}
Service接口(和Mapper一模一样)
package com.dreamlife.service;
import java.util.List;
import com.dreamlife.model.Shop;
public interface ShopService {
int deleteByPrimaryKey(Integer id);
int insert(Shop shop);
int insertSelective(Shop shop);
Shop selectByPrimaryKey(Integer id);
int updateByPrimarykey(Shop shop);
//获取所有菜单列表
public List<Shop> getShopList(Shop shop);
}
接口实现类ServiceImpl
package com.dreamlife.serviceImpl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import com.dreamlife.dao.ShopMapper;
import com.dreamlife.model.Shop;
import com.dreamlife.service.ShopService;
public class ShopServiceImpl implements ShopService {
@Autowired
private ShopMapper shopMapper;
@Override
public int deleteByPrimaryKey(Integer id) {
// TODO Auto-generated method stub
return this.shopMapper.deleteByPrimaryKey(id);
}
@Override
public int insert(Shop shop) {
// TODO Auto-generated method stub
return this.shopMapper.insert(shop);
}
@Override
public Shop selectByPrimaryKey(Integer id) {
// TODO Auto-generated method stub
return this.shopMapper.selectByPrimaryKey(id);
}
@Override
public int updateByPrimarykey(Shop shop) {
// TODO Auto-generated method stub
return this.shopMapper.updateByPrimarykey(shop);
}
@Override
public List<Shop> getShopList(Shop shop) {
// TODO Auto-generated method stub
return this.shopMapper.getShopList(shop);
}
@Override
public int insertSelective(Shop shop) {
// TODO Auto-generated method stub
return this.shopMapper.insertSelective(shop);
}
}
Controller类
package com.myProject.controller;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.myProject.model.Shop;
import com.myProject.service.ShopService;
@Controller
@RequestMapping(value="/shop")
public class ShopController {
@Autowired
private ShopService shopService; // 注册service
@RequestMapping(value="/system/getShopList.do")
public @ResponseBody Map<String, Object> getShopList(HttpServletRequest request) {
Shop shop = new Shop();
shop.setPageSize(4);
shop.setPageIndex(1);
List<Shop> shops = this.shopService.getShopList(shop);
Map<String, Object>map = new HashMap<String, Object>();
map.put("message", "Success");
map.put("aaData", shops);
return map;
}
@RequestMapping(value="/system/addShop.do")
@Transactional(isolation = Isolation.READ_COMMITTED)
public @ResponseBody Map<String, Object> addShop(HttpServletRequest request,Shop shop) {
try {
request.setCharacterEncoding("utf-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String shopAddr = request.getParameter("shopAddr");
String shopIcon = request.getParameter("shopIcon");
String shopName = request.getParameter("shopName");
Integer shopStatus = Integer.parseInt(request.getParameter("shopStatus"));
Integer userId = Integer.parseInt(request.getParameter("userId"));
shop.setShopAddr(shopAddr);
shop.setShopIcon(shopIcon);
shop.setShopName(shopName);
shop.setShopStatus(shopStatus);
shop.setUserId(userId);
this.shopService.insertSelective(shop);
//不要学这个
return null;
}
}