阶段环境初始配置
操作:windows
开发工具:eclipse+maven
数据库管理系统(DBMS):mysql
创建新工作区:CGBWORKSPACE1808+UTF-8编码
画图工具应用:FastStone Capture
数据库初始化:(准备工作)
登录 mysql (使用mysql自带客户端)
设置mysql客户端的编码: set names utf8;
执行source指令(用于执行sql文件)
例如: source d:/project.sql
基本原理
基本的处理流程
- 根据配置文件创建session工厂sessionFactory;
- 由SeesionFactory产生数据库会话session;
- 通过数据库会话session完成数据库具体的操作,增改查删和事务管理;
- 处理完后关闭会话session
MyBatis功能架构
- API接口:由session会话暴露出具体的增改查删和事务管理操作接口;
- 数据处理:主要包括SQL查找,SQL解析,SQL执行和结果映射等;
底层支持:主要包括数据库连接管理,事务管理,配置资源加载解析和缓存机制等
1.创建maven项目
然后这里我们开始创建一个maven项目,有简单maven和复杂,勾选简单就行了,这里,需要去设置一下maven项目的结构:
步骤:
**项目名->右键->properties->java build path->source->add
按照如图所示的项目基本结构进行创建,并应用保存,之后每次创建简单项目时,项目会自动创建基本结构。
可以通过order and export调整包结构顺序。
2.添加依赖和配置文件
1.这一步开始之前,首先要确认一下你的eclips的maven插件的配置文件有没有配置好下载仓库和阿里云:
配置仓库的绝对路径
<localRepository>D:\software\repository</localRepository>
配置阿里云服务器
<mirror>
<id>nexus-aliyun</id>
<name>Nexus aliyun</name>
<mirrorOf>*</mirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
2.之后我们就可以对项目进行依赖的配置,在maven 项目里的pom.xml中添加代码:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.pt</groupId>
<artifactId>CGB-MYBATIS-01</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 添加jar包依赖 -->
<dependencies>
<!-- 添加mysql驱动程序依赖(为访问数据库提供服务) -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<!-- 添加mybatis依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!-- 添加junit依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- 添加log4j日志依赖 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
</project>
在java/main/resource里创建一个mabatis-config.xml(核心配置文件),之后创建configs.properties文件,最后创建mapper文件夹,然后创建一个映射文件:
核心配置文件<mabatis-config.xml>这里主要负责配置一些需要使用到的环境和配置,使用了DTD的xml文本限制
<?xml version="1.0" encoding="UTF-8"?>
<!-- 配置文件 -->
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="configs.properties"></properties>
<!-- 配置日志文件 -->
<settings>
<!-- 其中name属性的值为固定写法,value的值要依托于使用的日志处理库. -->
<setting name="logImpl" value="log4j"/>
</settings>
<!-- 配置初始化环境
default设置默认值
environment中的id和default匹配连接在一起
可以选择测试和开发环境,分开配置-->
<environments default="development">
<environment id="development">
<!-- MyBatis使用jdbc的事务管理器
事务就是提交了才会有响应,一个是提交,一个是回滚 -->
<transactionManager type="JDBC" />
<!-- 使用mabatis自带连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- 要想使用映射文件,要在这里先对映射文件进行添加,
并放在environments环境配置下面 -->
<mappers>
<mapper resource="mapper/MemberMapper.xml"/>
</mappers>
</configuration>
这里最后要做的是一个商城后台管理项目,因此,我创建了一个MemberMapper.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">
<!-- 映射文件 -->
<!-- mybatis中的映射文件:内部要定义sql映射 -->
<mapper namespace="com.pt.member.dao.MemberDao">
<!-- 查询会员信息:对于select元素而言,
必须指定resultType-->
<select id="findPageObjects"
resultType="com.pt.member.entity.Member">
select *
from t_members
limit #{startIndex},#{pageSize}
</select>
<!-- 底层会封装为一个MappedStatement对象 -->
<!-- 基于id删除会员信息 -->
<delete id="deleteObject"
parameterType="int">
delete from t_members
where id=#{id}
</delete>
<!-- 更新密码 -->
<update id="updatePassword">
update t_members
set password=#{array[0]}
where id=#{array[1]}
</update>
<!-- 定义insert元素,其中parameterType可以不写,
#{}表达式会调用参数对象的get方法 -->
<insert id="insertObject"
parameterType="com.pt.member.entity.Member">
insert into t_members
(nickname,password,realname,gender,rank,
email,mobile,safequestion,safeanswer,createdTime)
values
(#{nickname},#{password},#{realname},#{gender},#{rank},
#{email},#{mobile},#{safequestion},#{safeanswer},#{createdTime})
</insert>
<!-- 通过select元素定义查询语句 ,每一个映射
元素底层都会封装为一个MappedStatement对象-->
<select id="findObjects"
resultType="com.pt.member.entity.Member">
select *
from t_members
</select>
</mapper>
在此之前,我们可以先做好会员信息的类,Member会员类,用来封装会员信息(跟数据库中的会员信息保持一致),注意重写toString.
写到这里,我想到了几个问题,
问题1:当我类封装好后,底层怎么才能把数据库的东西通过反射找到,并且封装到Member会员类中。??
- 这里需要调用Debug模式去看底层代码
解决:https://blog.csdn.net/surpass0728/article/details/80696931
问题2:当使用动态代理#{}和${}之后,数据会有什么不同,以及各有什么优缺点。解决:https://blog.csdn.net/lohannes/article/details/79031435
dao层,面向接口编程
package com.pt.order.dao;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.pt.order.entity.Order;
import com.pt.order.vo.OrderVo;
import com.pt.order.vo.SqlOrderCommand;
public interface OrderDao {
/**
* 基于id删除订单信息
* @param id
* @return 删除的行数
*/
int deleteObject(Integer id);
/**
* 基于多个id执行订单的删除操作
* 应用说明:当方法中的参数应用在动态sql时
* 1) 方法中使用了@param("参数名")注解修饰,
* 则动态sql中#{参数名}
* 2) 方法中没有,则动态sql里可以使用array作为参数接收数据
* 错误说明:
* 1)当如下方法中参数为null,或者数组长度为0时,
* 直接在动态sql中使用ids可能会有问题。
* @param ids
* @return
*/
int deleteObjectByIds(
@Param("ids") String[] ids);
/**
* @param cmd
* @return
*/
List<OrderVo> findPageObjects(
@Param("cmd") SqlOrderCommand cmd);
/**
* 将订单的详细信息写入到数据库(对象持久化)
* @param entity (封装了订单信息的对象)
* @return (写入数据的行数)
*/
int insertObject(Order entity);
}
dao层接口的编程可以使代码更加简单,可以减少编程过程中字符串的拼接,减少错误。并可以增强代码的复用性。
- 写到这里,还有一个问题,数据库中会有联动查询,当通过订单信息去查询的会员信息的时候,就需要用到。解决:用vo(Value Object)值对象去关联量行数据。
package com.pt.order.vo;
import java.io.Serializable;
import java.util.Date;
import com.pt.member.entity.Member;
/**
* VO:用于封装订单以及订单相关的会员信息
* @author Administrator
*/
public class OrderVo implements Serializable{
private static final long serialVersionUID = 2586258704975775437L;
private Integer id;
/**订单编码*/
private String code;
/**商品id*/
private Integer goodsId;
/**订单总价*/
private Float totalprice;
/**订单状态*/
private Integer status;
/**订单备注*/
private String remark;
/**订单创建时间*/
private Date createdTime;
/**借助此属性封装会员信息*/
private Member member;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Integer getGoodsId() {
return goodsId;
}
public void setGoodsId(Integer goodsId) {
this.goodsId = goodsId;
}
public Float getTotalprice() {
return totalprice;
}
public void setTotalprice(Float totalprice) {
this.totalprice = totalprice;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Date getCreatedTime() {
return createdTime;
}
public void setCreatedTime(Date createdTime) {
this.createdTime = createdTime;
}
public Member getMember() {
return member;
}
public void setMember(Member member) {
this.member = member;
}
@Override
public String toString() {
return "OrderVo [id=" + id + ", code=" + code + ", goodsId=" + goodsId + ", totalprice=" + totalprice
+ ", status=" + status + ", remark=" + remark + ", createdTime=" + createdTime + ", member=" + member
+ "]";
}
}
先写到这里。。。。未完待续。。。