javaweb实战之商城项目开发(三)
作者:茶饮月 发布时间:2023-04-15 14:27:34
接着上一篇《javaweb实战之商城项目开发(二)》这一篇主要实现通用的BaseDao.java和使用resultMap映射关联对象
一.通用的BaseDao.java
既然要大家都能用,所以使用了泛型.其中要注意的问题就是类似User.getClass().getName()这样的代码是需要修改的.修改方法就是使用参数Class tc传递过来,然后在使用tc.getName()即可.
完整代码:
package com.dao;
import com.model.Pager;
import com.util.SessionUtil;
import com.util.SystemContext;
import org.apache.ibatis.session.SqlSession;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by nl101 on 2016/2/23.
*/
public class BaseDao<T> {
/**
* 根据id取出一个T类型
* @param id 要取出T类型的id
* @return
*/
public T load(Class<T> tc,int id){
SqlSession session = SessionUtil.getSession();
T t = null;
try {
t = session.selectOne(tc.getName()+".load",id);
} finally {
SessionUtil.closeSession(session);
}
return t;
}
/**
* 添加一个T类型
* @param t 要添加的T类型
* @return true成功
*/
public boolean add(T t){
int isAdd = 0;
SqlSession session = SessionUtil.getSession();
try {
isAdd = session.insert(t.getClass().getName()+".add",t);
session.commit();//提交
} catch (Exception e) {
session.rollback();//提交失败则回滚
}finally {
SessionUtil.closeSession(session);
}
return isAdd>0;
}
/**
*根据id删除T类型
* @param id 要删除T的id
* @return true成功
*/
public boolean delete(Class<T> t,int id){
int isDelete = 0;
SqlSession session = SessionUtil.getSession();
try {
isDelete = session.delete(t.getName()+".delete",id);
session.commit();
} catch (Exception e) {
session.rollback();//失败返回
System.out.println("删除用户失败");
e.printStackTrace();
}finally {
SessionUtil.closeSession(session);
}
return isDelete>0;
}
/**
*更新T类型
* @param t 要更新的用户
* @return true成功
*/
public boolean update(T t){
int isUpdate = 0;
SqlSession session = SessionUtil.getSession();
try {
isUpdate = session.delete(t.getClass().getName()+".update",t);
session.commit();
} catch (Exception e) {
session.rollback();//失败返回
System.out.println("更新用户失败");
e.printStackTrace();
}finally {
SessionUtil.closeSession(session);
}
return isUpdate>0;
}
/**
* 根据指定条件分页查询
* @param maps 指定条件集合
* @return
*/
public Pager<T> find(Class<T> t,Map<String,Object> maps){
int pageStart = SystemContext.getPageStart();//分页起始
int pageSize = SystemContext.getPageSize();//分页大小
Pager<T> pagers = new Pager<>();
maps.put("pageStart",pageStart);
maps.put("pageSize",pageSize);
SqlSession session = SessionUtil.getSession();
List<T> datas = null;
try {
datas = session.selectList(t.getName()+".find",maps);//获取记录
pagers.setDatas(datas);
pagers.setPageSize(pageSize);
pagers.setPageStart(pageStart);
int totalRecord = session.selectOne(t.getName()+".findcount",maps);//获取记录总数
pagers.setTotalRecord(totalRecord);
pagers.setPageIndex(pageStart/pageSize+1);
} finally {
SessionUtil.closeSession(session);
}
return pagers;
}
/**
* 根据指定条件取出部分数据
* @param maps 指定条件集合
* @return
*/
public Pager<T> list(Class<T> t,Map<String,Object> maps){
Pager<T> pagers = new Pager<>();
SqlSession session = SessionUtil.getSession();
List<T> datas = null;
try {
datas = session.selectList(t.getName()+".list",maps);//获取记录
pagers.setDatas(datas);
pagers.setTotalRecord(datas.size());
} finally {
SessionUtil.closeSession(session);
}
return pagers;
}
}
同样的UserDao.java也需要相应的修改
public class UserDao extends BaseDao<User>{
/**
* 根据id取出一个用户
* @param id 要取出用户的id
* @return
*/
public User load(int id){
return super.load(User.class,id);
}
/* 其他函数就不一一贴出来了,都是类似的写法*/
}
二.resultMap的映射
简单来说当数据库中的字段信息和对象的属性不一致时需要通过resultMap来映射.
举个例子:Address属性中有一个User的实体类,如下
public class Address {
private int id;
private String name;
private String phone;
private String postcode;
//直接给user对象,来代替user_id
private User user;
`````````
}
那么我们想取出来一个Address的同时也取出其对应的user,然而这是两个对象,且两者都有id属性,所以对于mybatis在调用set方法设置属性时就会混乱而使用resultMap的目的就是消除这种混乱.
编写load的sql
<!--加载一个地址-->
<!--这里需要表连接,取出User,又连接保证取出的地址不为空,并且为重复属性id取别名-->
<select id="load" parameterType="int" resultMap="addressMap">
select *,t1.id AS 'a_id' from address t1 RIGHT JOIN user t2 ON
(t1.user_id = t2.id) WHERE t1.id=#{id};
</select>
这里就使用的resultMap来映射,这个resultMap的名字叫做addressMap.
addressMap
<resultMap id="addressMap" type="Address" autoMapping="true">
<!--把结果中的a_id映射为id,其他的autoMapping = true会自动匹配-->
<id column="a_id" property="id"/>
<!--取出关联属性-->
<association property="user" javaType="User" >
<!--把user_id映射为user的id-->
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="nickname" property="nickname"/>
<result column="type" property="type"/>
</association>
</resultMap>
type 代表其类型,不包括关联属性
autoMapping true表示消除冲突后,剩下的属性会自动匹配
id和result id 和 result 都映射一个单独列的值到简单数据类型,不同是 id 表示的结果将是当比较对象实例时用到的标识属性,一般是主键
association 代表关联属性,这里设置的是User,对于关联映射,其里面想要显示的属性必须要手动指定property,不然会无法映射
上面配置完,当搜索出来的时候,mybatis就会自动调用其相应的set方法,把属性设置到实体类中.
测试
package com.dao;
import com.model.Address;
public class AddressDao extends BaseDao<Address> {
public static void main(String[] args) {
AddressDao addressDao = new AddressDao();
Address address = addressDao.load(1);
System.out.println(address.toString());
}
/**
* 加载一个地址
* @param id 要加载地址的id
* @return 返回要加载的地址,null则加载失败
*/
public Address load(int id){
return super.load(Address.class,id);
}
}
效果图可以看出来,只要是映射的关联属性都取出来了,没映射的都为null
按照这样的想法把其他函数补全
xml代码:
<?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.model.Address">
<!--当数据库中的字段信息和对象的属性不一致时需要通过resultMap来映射 -->
<resultMap id="addressMap" type="Address" autoMapping="true">
<!--把结果中的a_id映射为id,其他的autoMapping = true会自动匹配-->
<id column="a_id" property="id"/>
<!--取出关联属性-->
<association property="user" javaType="User" >
<!--把user_id映射为user的id-->
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="nickname" property="nickname"/>
<result column="type" property="type"/>
</association>
</resultMap>
<!--加载一个地址-->
<!--这里需要表连接,取出User,又连接保证取出的地址不为空,并且为重复属性id取别名-->
<select id="load" parameterType="int" resultMap="addressMap">
select *,t1.id AS 'a_id' from address t1 RIGHT JOIN user t2 ON (t1.user_id = t2.id) WHERE t1.id=#{id};
</select>
<!--增加一个地址-->
<insert id="add" parameterType="Address">
insert into address values (null,#{name},#{phone},#{postcode},${user_id})
</insert>
<!--删除一个地址-->
<delete id="delete" parameterType="int">
DELETE FROM address WHERE id=#{id}
</delete>
<!--修改一个地址-->
<update id="update" parameterType="Address">
UPDATE address SET name=#{name},phone=#{phone},postcode=#{postcode} where id=#{id}
</update>
<!--找出指定用户所有的地址-->
<select id="list" parameterType="Map" resultMap="addressMap">
SELECT *,t1.id AS 'a_id' FROM address t1 RIGHT JOIN user t2 ON (t1.user_id=t2.id) WHERE t1.user_id=#{user_id}
</select>
</mapper>
java代码:
package com.dao;
import com.model.Address;
import com.model.Pager;
import java.util.HashMap;
import java.util.Map;
/**
* Created by nl101 on 2016/2/23.
*/
public class AddressDao extends BaseDao<Address> {
public static void main(String[] args) {
AddressDao addressDao = new AddressDao();
Pager<Address> pagers = addressDao.list(1);
System.out.println(pagers.getDatas().size());
}
/**
* 加载一个地址
* @param id 要加载地址的id
* @return 返回要加载的地址,null则加载失败
*/
public Address load(int id){
return super.load(Address.class,id);
}
/**
* 添加一个地址
* @param address 要添加的地址
* @param user_id 要添加的地址对应的user_id
* @return true成功
*/
public boolean add(Address address,int user_id){
UserDao userDao = new UserDao();
if (userDao.load(user_id)==null){
return false;
}
return super.add(address);
}
/**
* 删除一个地址
* @param id 要删除地址对应的id
* @return true删除成功
*/
public boolean delete(int id){
return super.delete(Address.class,id);
}
/**
* 更新一个地址
* @param address 要更新的地址
* @return true更新成功
*/
public boolean update(Address address){
return super.update(address);
}
/**
* 根据用户id取出该用户所有地址
* @param user_id
* @return
*/
public Pager<Address> list(int user_id){
Map<String,Object> maps = new HashMap<>();
maps.put("user_id",user_id);
return super.list(Address.class,maps);
}
}
ADO层按照这样写,就没问题了。


猜你喜欢
- 1.简介学了几周的Java,闲来无事,写个乞丐版的扫雷,加强一下Java基础知识。2.编写过程编写这个游戏,一共经历了三个阶段,编写了三个版
- 我们先要记住三者的特征:String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线
- 这篇文章主要介绍了Springboot整合Shiro的代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,
- 我相信现在绝大部分App几乎避免不了消息推送,其实原理还是使用了长连接,通过服务端将消息推给客户端。市面上也有不少三方库,例如极光、友盟、个
- 尽管我们通常认为通过JAVA的反射机制来访问其它类的私有字段和私有方法是可行的,其实并没有那么困难。 注释:只有在单独的JAVA程序中运行该
- 一.代码实现1. “Activity_11\src\yan\activity_11\MainActivity.java”pack
- 一篇小白也能看懂的查找游戏物体的方式解析 – Unity 之 查找物体的几种方式。本文通过实际测试得出使用结论,大家进行简单记录,在使用时想
- 目前的应用市场上,使用毛玻璃效果的APP随处可见,比如用过微信语音聊天的人可以发现,语音聊天页面就使用了高斯模糊效果。先看下效果图:&nbs
- 由于众所周知的原因,maven的库在中国大陆非常慢。我在百度上搜到的大部分文章都是直接在~/.m2/settings.xml 加入以下内容&
- ListView是开发中最常用的控件了,但是总是会写重复的代码,浪费时间又没有意义。最近参考一些资料,发现一个万能ListView适配器,代
- Java程序设计 图形用户界面 【十】复选框复选框JCheckBoxJCheckBox类方法作用public JCheckBox(Icon
- 异常算术异常类:ArithmeticExecption空指针异常类:NullPointerException类型强制转换异常:ClassCa
- 本文实例讲述了C#数据结构之堆栈(Stack)。分享给大家供大家参考,具体如下:堆栈(Stack)最明显的特征就是“先进后出”,本质上讲堆栈
- strings.xml 有很多需要注意的地方和一些小技巧,知道了这些可以让你的 Android 应用更加规范易用,感兴趣的小伙伴们可以参考一
- 1、for循环虽然所有循环结构都可以用 while 或者 do…while来表示,但 for 循环的出现,可使一些循环
- Maven 错误找不到符号问题,通常有三种原因: 1. 可能项目编码格式不统一。 2. 可能项目编码使用的JDK版本不统一。 3
- 本文实例讲述了C#实现String类型和json之间的相互转换功能。分享给大家供大家参考,具体如下:////Donet2.0 需要添加引用/
- 前言最近在逛博客的时候看到了有关Redis方面的面试题,其中提到了Redis在内存达到最大限制的时候会使用LRU等淘汰机制,然后找了这方面的
- 元注解是负责对其它注解进行说明的注解,自定义注解时可以使用元注解。Java 5 定义了 4 个注解,分别是 @Documented、@Tar
- webflux介绍Spring Boot 2.0spring.io 官网有句醒目的话是:BUILD ANYTHING WITH SPRING