这是个MVC项目,我不一定可以完整的实现这个项目,但力求把这个复现出来,尽量的复现细节。
第一步:创建数据库 表
创建表如下:
我们使用 int 是为了方便 然后采用 demcial,精确度较高
添加两个用户
然后开始构建Web项目
然后完善 依赖
加上 mysql mybatis log4j servlet的依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.10</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.31</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
然后配置 mybatis.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value=""/>
<property name="url" value=""/>
<property name="username" value=""/>
<property name="password" value=""/>
</dataSource>
</environment>
</environments>
<mappers>
</mappers>
</configuration>
我们如果将数据库的配置信息直接写到里面的话会导致后期修改过于麻烦,因此我们可以写到xx.properties中,后期修改方便
主要是使用 ${}里面填写相应的名字,就可以获取到db.properties的数据了,写法如下:
<configuration>
<properties resource="database.properties" ></properties>
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<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>
<mappers>
</mappers>
</configuration>
db的内容如下:
driver = com.mysql.cj.jdbc.Driver
url = jdbc:mysql://localhost:3306/prostudydb
username =
password =
然后我们先来写个简单的查询语句测试一下,看是否可以获得对应的数据,是否数据库部分配置好。
那么我们就需要先粗步的完善项目构造,首先需要一个pojo类,或者叫做entiry类
public class account {
private Integer id;
private Integer actno;
private Long balance;
public account(){}
public account(Integer id, Integer actno, Long balance) {
this.id = id;
this.actno = actno;
this.balance = balance;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getActno() {
return actno;
}
public void setActno(Integer actno) {
this.actno = actno;
}
public Long getBalance() {
return balance;
}
public void setBalance(Long balance) {
this.balance = balance;
}
@Override
public String toString() {
return "account{" +
"id=" + id +
", actno=" + actno +
", balance=" + balance +
'}';
}
}
完成有参 无参 get set tostring的方法,然后我们需要创建util层,提供一个静态的工具类,提供我们需要的sqlsession 。
然后是utils类,请注意,utils类中需要使用静态方法,因为工具类我们只需要使用就可以了,不需要实例化对象,因此在类加载的时候编译一次即可
public class sqlSession {
// 一个静态的 SqlSessionFactory ,我们需要它在opensession中使用,因此需要声明一下
private static SqlSessionFactory sqlSessionFactory;
static {
try {
// 类加载的时候初始化sqlsessionfactory
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));
} catch (IOException e) {
throw new RuntimeException("在utils下的sqlsessionfactorybuilder中出现的异常"+ e);
}
}
// 返回sqlsession的方法 返回需要的sqlsession
public static SqlSession openSession (){
return sqlSessionFactory.openSession();
}
// 执行selectone的方法
/**
* int id
* sqlsession sqlsession
* 因为要返回pojo对象,所以我们需要返回account ,通过传入id + 一个session,我们就可以得到需要的数据
* */
public static account getOneAccount(SqlSession sqlSession,Integer id ){
account account = new account();
account = sqlSession.selectOne("account.selectById",id);
return account;
}
}
然后我们看一下测试方法
public void get(){
// 调用静态方法获取对象
SqlSession sqlsession = sqlSession.openSession();
System.out.println(sqlsession);
// 得到值
account a = sqlSession.getOneAccount(sqlsession,1);
System.out.println(a);
}
}
看一下xxxmapper的内容
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="account">
<select id="selectById" resultType="pojo.account">
select * from try where id = #{id}
</select>
</mapper>
成功获取到数据,证明数据库和后端交流通常
然后我们来完成简单的前端部分和tomcat的配置
首先是一个简单的inex.html 一个web.xml请注意web.xml的版本尽可能高,最好是4
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>账户尝试</title>
</head>
<body>
<h1>阿达是大大大是</h1>
</body>
</html>
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
id="WebApp_ID" version="4.0">
</web-app>
配置好tomcat后运行一下发现ok,接下来就是完善表格 获取http传来的会话
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>账户尝试</title>
</head>
<body>
<h1>阿达是大大大是</h1>
<form action="/tranfser" method="post">
<span>账号1</span> <input type="text" name="shuzhi1" >
<br>
<span>账户2</span> <input type="text" name="shuzhi2" >
<input type="submit" value="提交" >
</form>
</body>
</html>
请在这里暂停,捋一下思路。
前端发送数据 通过 transfer 转交json数据给后端,我们可以通过req.getParmare通过name获得数据,那么我们就需要重写HttpServlet。
我们需要在controller中获取前端传来的数据,然后包装在一个新的account对象中。
并且通过方法完成字符串的转变为int long的转变
@WebServlet("/tranfser")
public class transeferOnetoAnother extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String shuzhi = req.getParameter("shuzhi2");
Long shuzhi1 = Long.parseLong(req.getParameter("shuzhi1"));
System.out.println(shuzhi1);
System.out.println("3333333333333333333333333333");
// 通过parseLong将字符串转变为long
Long shuzhi2 = Long.parseLong(shuzhi);
account account01 = new account();
account01.setBalance(shuzhi1);
account01.setId(1);
account account02 = new account();
account02.setBalance(shuzhi2);
account02.setId(2);
然后我们就要调用service中处理转账的方法,我们就可以传递两个account对象。
请注意service中我们要先写接口,在实现方法,通过接口命名方法有好处如下:方便设计和沟通,我们可以由一个人设计出接口,分给每个人实现,这样可以提高效率并且控制。2.可以解耦合,实现更高的耦合度,需要增加功能的话,我们不需要改动原来的代码,只需要正在接口中增加一个新的抽象方法,然后在用一个新的实现类实现它,保障原代码的安全性。
public interface transfer {
// 通过返回int看是否成功,我们可以通过两个实体类,然后查看它的值,来判断是否转账
int transferOneToAnother(account account1, account account2);
}
public class transferImpl implements transfer {
@Override
public int transferOneToAnother(account account1, account account2) {
// 第一步,将后端的两个数据查询出来
// 我们需要查询所有,通过list来获取,完善select
/** 第一步 在accountMapper中完善Select语句,填写好id selectAll
* 第二步 前往utils中,编写查询所有的方法 输入 sqlsession 返回list集合,
* 第三步 回到这里 完善业务处理方法
*
* **/
SqlSession sqls = sqlSession.openSession();
/* 请注意,我们这里是静态方法,必须调用类,我们通过调用静态方法获得session 在传值,这样是不是多次一举呢?
* 事实上,mybatis默认在数据库连接池中维护了10个数据库连接,我们需要保证每次获取的session相同,这点我也不清楚,QAQ
* **/
List<account> list = sqlSession.getAll(sqls);
account a01 = list.get(0);
account a02 = list.get(1);
// 比较数值 假如是从 1 转账给 2 那我们怎么知道是从 1 转账给 2 呢??
/*
* 模拟的话就是只要其中一个有数字 ,那么加 另一个减少只实现一个加的功能不提供减的
* */
/*
*
* 请注意这里 account1 和 a01 的区别,一个是我们从前端传递后来包装的 一个是从数据库中包装的
* */
if (account1.getBalance() > a01.getBalance() ){
System.out.println("钱不够");
}else {
// 那么账户1需要更新,然后我们需要调用更新语句 更新数据库的值
// 返回到mapper完善更新语句 sqlsession完善更新需要的方法
/*
* 更新语句 需要 sqlSession id balance 通过返回int值看是否成功 int <1 则是失败
* */
if ((sqlSession.updateOne(sqls,a01.getId(), a01.getBalance()-account1.getBalance()) < 1)){
System.out.println("更新语句失败");
}else{
// session提交 session关闭
sqls.commit();
sqls.close();
}
}
return 0;
}
}
同时,我们需要在service的实现类中调用实现好的Select 和 update方法,实现查找和更改
public static int updateOne( SqlSession sqlSession, int id,Long balance ){
account account = new account();
account.setId(id);
account.setBalance(balance);
int count = sqlSession.update("updatesOne",account);
return count;
}
最主要的就是形式参数的确定和一致
我们给出更新语句
<update id="updatesOne"> update try set balance = #{balance} where id = #{id} </update>
请注意 务必封装成一个完整的account类,我们才能调用session.update方法进行自动匹配传递值。
然后基本上就实现了更改。