这几天在做一个前后端分离的一个项目,采用的是 MVC 模式,对于 MVC 网上的教程杂乱无章,也没有写的较详细的,所以写了此文,本文作为一个分享文,分享本人在学习中遇到的问题以及一些自个认为好用的小技巧。
目录
目录下的结构
配置文件
Dao 层
Service 层
Control 层
Model 层
lib 导包
web.xml 配置
目录下的结构
config
jdbc.properties
src
com.xxx
user(一般与项目名挂钩)
control
UserServlet.java
dao
impl
UserDao.java
IUserDao.java
model
User.java
service
impl
UserService.java
IUserService.java
util
JdbcUtil.java
web
web-inf
web.xml
lib
xxx.jar
xxx.jsp
配置文件
jdbc.properties : 开发中获得连接的4个参数(驱动、URL、用户名、密码)通常都存在配置文件中,方便后期维护,程序如果需要更换数据库,只需要修改配置文件即可。
oracle 版
username=itxzw
password=123456
driver=oracle.jdbc.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:orcl
mysql 版
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/db1?serverTimezone=Hongkong&useUnicode=true&characterEncoding=utf8&useSSL=false
或
url=jdbc:mysql://localhost/db1?useSSL=false&CharacterEncoding=UTF-8&server=TUC
user=root
password=123456
JdbcUtil.java
里面存放的是对连接 DB 的一些配置文件,可以减少代码量
public class JdbcUtil {
public static String username;
public static String password;
public static String driver;
public static String url;
static {
// -1.读取配置文件
InputStream is = JdbcUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties pro = new Properties();
try {
pro.load(is);
username = pro.getProperty("username");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
url = pro.getProperty("url");
// 0.加载驱动
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection(){
// 1.连接数据库
Connection conn = null;
try {
conn = DriverManager.getConnection(url, username, password);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return conn;
}
public static void close(ResultSet rs, Statement stmt,Connection conn){
// 5.关闭连接
try {
if(rs!=null){
rs.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
try {
if (stmt!=null){
stmt.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
try {
if (conn!=null){
conn.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
}
Dao 层
dao 里面存放的是对 DB 进行操作的一些代码
IUserDao.java 里面存放的是对 DB 进行操作的一些代码的接口
public interface IUserDao {
// 添加用户
public boolean add(User user);
// 查询
public User query(User user);
// 根据名字查询
public User queryUserByName(String name);
// 根据ID_NUMBER查
public User queryUserByNumber(String number);
}
UserDao.java 里面的就是实现 IUserDao.java 的代码,对 DB 进行操作
public class UserDao implements IUserDao {
@Override
public boolean add(User user) {
…………
return user;
}
@Override
public User query(User user) {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
User loginuser = null;
try {
// 1.连接数据库
conn = JdbcUtil.getConnection();
// 2.获取Statement对象:将sql语句传给数据库服务器执行
String sql = "select * from T_USER where USERNAME = ? and PASSWORD = ?";
stmt = conn.prepareStatement(sql);
// 2.5.注入参数
stmt.setString(1,user.getUsername());
stmt.setString(2,user.getPassword());
// 3.执行sql,获取返回结果
rs = stmt.executeQuery();
// 4.处理结果集
if(rs.next()){
Integer id = rs.getBigDecimal("id")==null?null:rs.getBigDecimal("id").intValue();
String un = rs.getString("username");
String password = rs.getString("password");
Integer sex = rs.getString("sex")==null?null:rs.getBigDecimal("sex").intValue();
String idNumber = rs.getString("ID_NUMBER");
String tel = rs.getString("tel");
String addr = rs.getString("addr");
Integer type = rs.getString("type")==null?null:rs.getBigDecimal("type").intValue();
loginuser = new User(id,un,password,sex,idNumber,tel,addr,type);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JdbcUtil.close(rs,stmt,conn);
}
return loginuser;
}
@Override
public User queryUserByName(String name) {
…………
return user;
}
@Override
public User queryUserByNumber(String number) {
…………
return user;
}
}
里面就是对 DB 进行增删改查等操作
Service 层
IUserService.java 里面存放的是实现 UserService.java 里面的接口
public interface IUserService {
// 添加用户
public boolean register(User user);
// 登录
public User login(User user);
// 根据名字查询
public User queryUserByName(String name);
// 根据ID_NUMBER查
public User queryUserByNumber(String number);
}
UserService.java 里面存放的是实现 IUserService.java 接口里面的方法,申明一个 Dao 的成员,然后使用该 Dao 成员调用 Dao 里面的方法。
public class UserService implements IUserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public UserDao getUserDao() {
return userDao;
}
@Override
public boolean register(User user) {
User user1 = userDao.queryUserByName(user.getUsername());
if (user1!=null) return false;
User user2 = userDao.queryUserByNumber(user.getIdNumber());
if (user2!=null) return false;
return userDao.add(user);
}
@Override
public User login(User user) {
return userDao.query(user);
}
@Override
public User queryUserByName(String name) {
return userDao.queryUserByName(name);
}
@Override
public User queryUserByNumber(String number) {
return userDao.queryUserByNumber(number);
}
}
Control 层
control 里面存放的是 Servlet,与界面(view)、service进行交互。
public class UserServlet extends HttpServlet {
private UserService userService;
@Override
public void init() throws ServletException {
userService = new UserService();
UserDao userDao = new UserDao();
userService.setUserDao(userDao);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String action = request.getParameter("action");
if("LOGIN".equalsIgnoreCase(action)){
login(request,response);
}else if ("REGISTER".equalsIgnoreCase(action)){
register(request,response);
}else{
response.sendRedirect("/a1/day02/fade.jsp");
}
}
public void login(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
String username = request.getParameter("username");
String password = request.getParameter("password");
User u = new User();
u.setUsername(username);
u.setPassword(password);
User loginuser = userService.login(u);
if(loginuser!=null){
response.sendRedirect("/a1/day02/success.jsp");
}else{
response.sendRedirect("/a1/day02/login.jsp");
}
}
public void register(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
String[] hobbys = request.getParameterValues("hobby");
String un = request.getParameter("username");
String password = request.getParameter("password");
String usersex = request.getParameter("sex");
Integer sex = usersex==null?null:Integer.parseInt(usersex);
String idNumber = request.getParameter("id_number");
String tel = request.getParameter("tel");
String addr = request.getParameter("addr");
String usertype = request.getParameter("type");
Integer type = usertype==null?null:Integer.parseInt(usertype);
response.setContentType("text/html;charset=UTF-8");
response.getWriter().println("哈哈");
}
}
Servlet生命周期 init 只会执行一次,申明 Service 层的对象一般只申明一次,以后项目上云了,如果有成千上万的人来访问你的网页,执行一次就创建一个 Service ,非常的浪费,所以为了减少内存的使用就把 Service 放入到 init 里面。
Model 层
里面存放的是实体类,对成员的 getter 与 setter 方法,有参无参的构造函数,重写toString等方法。
public class User {
private int id;
private String username;
private String password;
private int sex;
private String id_number;
private String tel;
private String addr;
private int type;
public User() {
}
public User(int id, String username, String password, int sex, String id_number, String tel, String addr, int type) {
this.id = id;
this.username = username;
this.password = password;
this.sex = sex;
this.id_number = id_number;
this.tel = tel;
this.addr = addr;
this.type = type;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public String getId_number() {
return id_number;
}
public void setId_number(String id_number) {
this.id_number = id_number;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", sex=" + sex +
", id_number='" + id_number + '\'' +
", tel='" + tel + '\'' +
", addr='" + addr + '\'' +
", type=" + type +
'}';
}
}
或者用 lombok.jar 就可以不用写getter 与 setter 方法,有参无参的构造函数,重写toString等方法。
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {
private Integer id;
private String username;
private String password;
private Integer sex;
private String idNumber;
private String tel;
private String addr;
private Integer type;
}
lib 导包
lib 里面存放的是导入的一些 .jar 包。
xxx.jsp
这个不用多讲,有一点需要注意的是,from 的 action 的位置与你的 web.xml 文件对应的。
web.xml 配置
web.xml文件是用来初始化配置信息:比如Welcome页面、servlet、servlet-mapping、filter、listener、启动加载级别等。 每个xml文件都有定义它书写规则的Schema文件,也就是说javaEE的定义web.xml所对应的xml Schema文件中定义了多少种标签元素,web.xml中就可以出现它所定义的标签元素,也就具备哪些特定的功能。
<servlet>
<servlet-name>UserServlet</servlet-name>
<servlet-class>com.itxzw.user.control.UserServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserServlet</servlet-name>
<url-pattern>/userServlet</url-pattern>
</servlet-mapping>
servlet-mapping
servlet映射 端口映射过程就如同:你家在一个小区里B栋2410室,你朋友来找你,找到小区门口,不知道你住哪层哪号?就问守门的保安,保安很客气的告诉了他你家详细门牌,所以你朋友很轻松的找到了你家。
url-pattern
其实 url-pattern 就是说的 url 模式,就是容器在查找时根据这个模式来找到具体的servlet来执行。
servlet-name
Servlet程序起一个别名,一般是类名,作用是告诉服务器,当前配置的地址给哪个Servlet程序使用
servlet-class
java web开发中请求转发的类,就是你的类在你包下的地址。
不积跬步无以至千里,趁年轻,使劲拼,给未来的自己一个交代!向着明天更好的自己前进吧!