JSP 与 MyBatis 实现数据库读写分离示例
随着互联网技术的飞速发展,数据库读写分离已经成为提高系统性能、保证数据一致性的重要手段。JSP(Java Server Pages)作为Java Web开发的一种技术,与MyBatis作为持久层框架,结合使用可以实现数据库读写分离。本文将围绕这一主题,通过示例代码展示如何使用JSP和MyBatis实现数据库读写分离。
环境准备
在开始之前,我们需要准备以下环境:
1. JDK 1.8及以上版本
2. Tomcat 9.0及以上版本
3. MySQL 5.7及以上版本
4. Maven 3.6.3及以上版本
5. MyBatis 3.5.3及以上版本
项目结构
以下是项目的目录结构:
src/
|-- main/
| |-- java/
| | |-- com/
| | | |-- example/
| | | | |-- controller/
| | | | | |-- UserAction.java
| | | | |-- model/
| | | | | |-- User.java
| | | | |-- mapper/
| | | | | |-- UserMapper.java
| | | | |-- service/
| | | | | |-- UserService.java
| | | | |-- utils/
| | | | | |-- DataSourceUtil.java
| |-- resources/
| | |-- mybatis/
| | | |-- mapper/
| | | | |-- UserMapper.xml
| | |-- db.properties
| |-- web.xml
|-- test/
| |-- java/
| | |-- com/
| | | |-- example/
| | | | |-- UserMapperTest.java
|-- pom.xml
数据库配置
我们需要在`db.properties`文件中配置数据库连接信息:
properties
数据库连接信息
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC
jdbc.username=root
jdbc.password=root
MyBatis 配置
接下来,我们需要在`mybatis`目录下创建`UserMapper.xml`文件,定义SQL语句:
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.example.mapper.UserMapper">
<select id="selectById" resultType="com.example.model.User">
SELECT FROM user WHERE id = {id}
</select>
<insert id="insertUser" parameterType="com.example.model.User">
INSERT INTO user (name, age) VALUES ({name}, {age})
</insert>
<update id="updateUser" parameterType="com.example.model.User">
UPDATE user SET name = {name}, age = {age} WHERE id = {id}
</update>
<delete id="deleteUser" parameterType="int">
DELETE FROM user WHERE id = {id}
</delete>
</mapper>
数据源配置
在`utils/DataSourceUtil.java`文件中,我们使用MyBatis的`SqlSessionFactoryBuilder`来创建`SqlSessionFactory`,并配置数据源:
java
package com.example.utils;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import javax.sql.DataSource;
import java.io.InputStream;
public class DataSourceUtil {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
InputStream inputStream = DataSourceUtil.class.getClassLoader().getResourceAsStream("mybatis/mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (Exception e) {
e.printStackTrace();
}
}
public static SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
}
数据库读写分离配置
为了实现数据库读写分离,我们需要配置两个数据源:一个主库用于写操作,一个从库用于读操作。在`db.properties`文件中,我们可以配置两个数据源:
properties
主库连接信息
master.jdbc.driver=com.mysql.cj.jdbc.Driver
master.jdbc.url=jdbc:mysql://localhost:3306/mydb_master?useSSL=false&serverTimezone=UTC
master.jdbc.username=root
master.jdbc.password=root
从库连接信息
slave.jdbc.driver=com.mysql.cj.jdbc.Driver
slave.jdbc.url=jdbc:mysql://localhost:3306/mydb_slave?useSSL=false&serverTimezone=UTC
slave.jdbc.username=root
slave.jdbc.password=root
在`mybatis/mybatis-config.xml`文件中,我们可以配置数据源:
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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${master.jdbc.driver}"/>
<property name="url" value="${master.jdbc.url}"/>
<property name="username" value="${master.jdbc.username}"/>
<property name="password" value="${master.jdbc.password}"/>
</dataSource>
</environment>
<environment id="read">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${slave.jdbc.driver}"/>
<property name="url" value="${slave.jdbc.url}"/>
<property name="username" value="${slave.jdbc.username}"/>
<property name="password" value="${slave.jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mybatis/mapper/UserMapper.xml"/>
</mappers>
</configuration>
JSP 页面
在`controller/UserAction.java`文件中,我们定义一个`UserAction`类,用于处理用户请求:
java
package com.example.controller;
import com.example.model.User;
import com.example.service.UserService;
import com.example.utils.DataSourceUtil;
import org.apache.ibatis.session.SqlSession;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class UserAction extends HttpServlet {
private UserService userService = new UserService();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String action = request.getParameter("action");
if ("select".equals(action)) {
int id = Integer.parseInt(request.getParameter("id"));
User user = userService.selectById(id);
request.setAttribute("user", user);
request.getRequestDispatcher("/user.jsp").forward(request, response);
} else if ("insert".equals(action)) {
String name = request.getParameter("name");
int age = Integer.parseInt(request.getParameter("age"));
userService.insertUser(new User(name, age));
response.sendRedirect("user.jsp");
} else if ("update".equals(action)) {
int id = Integer.parseInt(request.getParameter("id"));
String name = request.getParameter("name");
int age = Integer.parseInt(request.getParameter("age"));
userService.updateUser(new User(id, name, age));
response.sendRedirect("user.jsp");
} else if ("delete".equals(action)) {
int id = Integer.parseInt(request.getParameter("id"));
userService.deleteUser(id);
response.sendRedirect("user.jsp");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
在`model/User.java`文件中,我们定义一个`User`类,用于表示用户信息:
java
package com.example.model;
public class User {
private int id;
private String name;
private int age;
// 省略getter和setter方法
}
在`service/UserService.java`文件中,我们定义一个`UserService`接口,以及其实现类`UserServiceImpl`:
java
package com.example.service;
import com.example.model.User;
public interface UserService {
User selectById(int id);
void insertUser(User user);
void updateUser(User user);
void deleteUser(int id);
}
package com.example.service.impl;
import com.example.mapper.UserMapper;
import com.example.model.User;
import com.example.utils.DataSourceUtil;
import org.apache.ibatis.session.SqlSession;
public class UserServiceImpl implements UserService {
private UserMapper userMapper;
public UserServiceImpl() {
SqlSession sqlSession = DataSourceUtil.getSqlSessionFactory().openSession();
userMapper = sqlSession.getMapper(UserMapper.class);
sqlSession.close();
}
@Override
public User selectById(int id) {
return userMapper.selectById(id);
}
@Override
public void insertUser(User user) {
SqlSession sqlSession = DataSourceUtil.getSqlSessionFactory().openSession();
userMapper.insertUser(user);
sqlSession.commit();
sqlSession.close();
}
@Override
public void updateUser(User user) {
SqlSession sqlSession = DataSourceUtil.getSqlSessionFactory().openSession();
userMapper.updateUser(user);
sqlSession.commit();
sqlSession.close();
}
@Override
public void deleteUser(int id) {
SqlSession sqlSession = DataSourceUtil.getSqlSessionFactory().openSession();
userMapper.deleteUser(id);
sqlSession.commit();
sqlSession.close();
}
}
在`user.jsp`文件中,我们定义一个简单的用户信息展示页面:
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>User Information</title>
</head>
<body>
<%
User user = (User) request.getAttribute("user");
if (user != null) {
%>
<h1>User Information</h1>
<p>ID: <%= user.getId() %></p>
<p>Name: <%= user.getName() %></p>
<p>Age: <%= user.getAge() %></p>
<%
} else {
%>
<h1>No User Found</h1>
<%
}
%>
</body>
</html>
总结
通过以上示例,我们展示了如何使用JSP和MyBatis实现数据库读写分离。在实际项目中,我们可以根据需求调整数据源配置、SQL语句以及业务逻辑。数据库读写分离可以提高系统性能,保证数据一致性,是Java Web开发中常用的一种技术。
Comments NOTHING