简易的ORM框架

news/2024/5/19 2:10:19 标签: java, 数据库, mysql, jdbc

简易的对象映射框架

  • 在使用jdbc的时候,往往都需要对数据库进行一些列的增删改查操作,但是每次使用jdbc的时候,难免不能避免使用jdbc的六大步骤:
    • 1,加载驱动
    • 2,获取链接
    • 3,根据连接获取发送并执行SQL语句的statement对象
    • 4,执行SQL语句
    • 5,处理结果
    • 6,关闭资源
  • 因此,我们可以将CRUD中的公共部分拿出来,做一个简易的封装
java">public class DBUtils {

	/** 驱动类路径 */
	private static final String DRIVER_CLASS="com.mysql.jdbc.Driver";
	/** url地址 */
	private static final String URL="jdbc:mysql://127.0.0.1:3306/mydb2";
	/** 数据库服务器登录用户名 */
	private static final String USER="root";
	/** 数据库服务器登录密码 */
	private static String PASSWORD= "123456";
	
	static {
		try {
			//1.加载驱动
			Class.forName(DRIVER_CLASS);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} 
	}

	/**
	 * 2. 获取数据库连接对象
	 * 
	 * @return
	 */
	public static synchronized Connection getConn() {
		try {
			return DriverManager.getConnection(URL, USER, PASSWORD);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 6.关闭资源
	 * 
	 * @param rs
	 * @param stat
	 * @param conn
	 */
	public static void close(ResultSet rs, Statement stat, Connection conn) {
		try {
			if (rs != null)
				rs.close();
			if (stat != null)
				stat.close();
			if (conn != null)
				conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

  • 因为无论是执行 添加,修改,删除,还是查询,都会涉及到:加载驱动,获取链接以及关闭资源,所有我们将这三个步骤进行一个简易的封装,而且,在添加,修改,删除这几个步骤中,仅仅就是SQL语句的差别,所以,我们也可以进行简易的封装:
java">/**
	 * 封装通用的更新操作:INSERT UPDATE DELETE
	 * 
	 * @param sql
	 * @param params 等价于:Object[] params 
	 * @return
	 */
	public static boolean exeUpdate(String sql, Object... params) {
		// 获取连接
		Connection conn = getConn();
		PreparedStatement ps = null;
		try {
			ps = conn.prepareStatement(sql);
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					ps.setObject(i + 1, params[i]);
				}
			}
			return ps.executeUpdate() > 0;
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			close(null, ps, conn);
		}
		return false;
	}
  • 这个是对insert,delete,update的封装,在执行这些操作的时候,我们只需要传入一个SQL语句,以SQL语句中需要的参数就可以进行增,删,改操作,并返回一个Boolean类型的结果,相比于没有封装前,代码量减少了可不是一点点。
  • 然后就是DQL操作的封装了,查询的操作封装相对于前面的DML来说要复杂一些,因为我们在进行查询操作之后,会返回一个结果集,这个时候,我们就需要处理这个结果集。
    • 1,封装查询一条数据,并返回一个java对象(前提是必须要有一个javabean)
      在封装查询语句之前,将执行SQL语句之后获得的结果集为一个map集合,我们先通过反射定义一个方法将这个map集合转化为一个java对象:
java">**
     * 将Map集合转换为一个确定的类型
     *
     * @param <T>
     * @param map
     * @param t
     * @return
     */
    private static <T> T mapToBean(Map<String, Object> map, Class<T> t) {
//		T obj = null;
        try {
            // 根据提供的Class对象创建对应类型的Object
            T obj = t.newInstance();
            // 获取Class中的所有Field
//			Field[] fields = t.getDeclaredFields();
//			//遍历获取每一个属性对象
//			for (Field field : fields) {
//				//获取属性名
//				String fname = field.getName();
//				//获取属性值
//				Object value = map.get(fname);
//				if(Objects.nonNull(value)) {
//					//设置属性对象的可访问性
//					field.setAccessible(true);
//					//将从map中获取的值设置给属性  obj.name=XX
//					field.set(obj, value);
//				}
//			}
            map.forEach((k, v) -> {
                try {
                    // 根据Field名称获取字段对象
                    Field field = t.getDeclaredField(k);
                    // 设置字段的可访问性
                    field.setAccessible(true);
                    // 为字段设置值
                    field.set(obj, v);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            });
            return obj;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        // 返回对象
        return null;
    }
  • 然后进行查询一条语句的封装方法:
java">/**
     * 封装通用查询单条数据的方法
     *
     * JDBC,反射,集合框架,lambda表达式,新增Objects类
     *
     * @param <T>
     * @param t
     * @param sql
     * @param params
     * @return
     */
    public static <T> T queryOne(Class<T> t, String sql, Object... params) {
        // 获取查询到到数据集合
        List<Map<String, Object>> list = queryMaps(sql, params);
        if (list.size() > 0) {
            // 获取一个Map对象
            Map<String, Object> map = list.get(0);
            // 将map集合转换为Javabean并返回
            return mapToBean(map, t);
        }
        return null;
    }
  • 2,封装查询多条语句的查询语句,并返回一个Javabean的List集合,在这之前,我们先要将查询语句返回的结果集变为一个map集合的List集合,听起来有点绕口,通俗的来讲就是:将查询语句返回的多条数据用一个List集合装起来,而这个list集合中的元素是多个Map集合:
java"> /**
     * 执行相关查询并将结果返回为List<Map<String,Object>> 集合
     *
     * @param sql
     * @param params
     * @return
     */
    public static List<Map<String, Object>> queryMaps(String sql, Object... params) {
        // 声明动态数组用于存储每一个查询到的Map对象
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        // 获取连接
        Connection conn = getConn();
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            // 获取预处理sql命令的对象
            ps = conn.prepareStatement(sql);
            if (params != null) {
                for (int i = 0; i < params.length; i++) {
                    // 对指定位置的占位符填充值(预处理)
                    ps.setObject(i + 1, params[i]);
                }
            }
            // 执行查询获取结果集
            rs = ps.executeQuery();
            // 获取结果集的元数据对象ResultSetMetaData
            ResultSetMetaData rsmd = rs.getMetaData();
            // 获取总查询列数
            int columnCount = rsmd.getColumnCount();
            // 遍历结果集
            while (rs.next()) {
                // 声明map集合存储每一条数据(临时缓存)
                Map<String, Object> map = new HashMap<String, Object>();
                // 遍历获取每一列的信息
                for (int i = 1; i <= columnCount; i++) {
                    // 获取列名称(作为map集合的键)
                    String key = rsmd.getColumnName(i);
                    // 获取列标签
                    String label = rsmd.getColumnLabel(i);
                    // 获取列值(作为map集合的值)
                    Object value = rs.getObject(label);
                    if (Objects.nonNull(value)) {
                        // 将取到的每一列的列名与列值存储到map
                        map.put(key, value);
                    }
                }
                // 将map集合装入list
                list.add(map);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            close(rs, ps, conn);
        }
        return list;
    }
  • 然后在封装成为查询多条数据的方法:
  • 大致思路就是:先查询多条数据,将它用一个List集合装起来,list集合中的元素是Map集合,然后在遍历,将每一个map集合通过mapToBean方法转化为一个Javabean,最后放回的结果就是一个List集合,集合中的元素就是一个个Javabean。
java"> /**
     * 封装通用查询多条数据的方法
     *
     * @param <T>
     * @param t
     * @param sql
     * @param params
     * @return
     */
    public static <T> List<T> queryList(Class<T> t, String sql, Object... params) {
        List<T> list = new ArrayList<T>();
        // 获取所有查询的到的数据
        List<Map<String, Object>> maps = queryMaps(sql, params);
        // 遍历集合中每一条数据(map)
        maps.forEach(m -> {
            // 将map转换为Javabean
            T obj = mapToBean(m, t);
            // 将Javabean装入list
            list.add(obj);
        });
        return list;
    }
  • 3,多表联合查询方法的封装,因为多表联合查询的结果对应的Javabean在查询之前是不确定的,所以我们查询之后也就只能返回一个List集合,集合中的元素是一个个map集合,如果需要将其转换为一个Javabean,那么就需要自行先创建一个对应的Java类。
java">/**
     * 执行相关查询并将结果返回为List<Map<String,Object>> 集合
     *
     * @param sql
     * @param params
     * @return
     */
    public static List<Map<String, Object>> queryMaps(String sql, Object... params) {
        // 声明动态数组用于存储每一个查询到的Map对象
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        // 获取连接
        Connection conn = getConn();
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            // 获取预处理sql命令的对象
            ps = conn.prepareStatement(sql);
            if (params != null) {
                for (int i = 0; i < params.length; i++) {
                    // 对指定位置的占位符填充值(预处理)
                    ps.setObject(i + 1, params[i]);
                }
            }
            // 执行查询获取结果集
            rs = ps.executeQuery();
            // 获取结果集的元数据对象ResultSetMetaData
            ResultSetMetaData rsmd = rs.getMetaData();
            // 获取总查询列数
            int columnCount = rsmd.getColumnCount();
            // 遍历结果集
            while (rs.next()) {
                // 声明map集合存储每一条数据(临时缓存)
                Map<String, Object> map = new HashMap<String, Object>();
                // 遍历获取每一列的信息
                for (int i = 1; i <= columnCount; i++) {
                    // 获取列名称(作为map集合的键)
                    String key = rsmd.getColumnName(i);
                    // 获取列标签
                    String label = rsmd.getColumnLabel(i);
                    // 获取列值(作为map集合的值)
                    Object value = rs.getObject(label);
                    if (Objects.nonNull(value)) {
                        // 将取到的每一列的列名与列值存储到map
                        map.put(key, value);
                    }
                }
                // 将map集合装入list
                list.add(map);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            close(rs, ps, conn);
        }
        return list;
    }

jdbcCRUDjdbcjarjdbcORM_339">以上就是对jdbc中CRUD的简易封装了,不过还没有涉及到数据库连接池以及jdbc事务的内容,所以不需要借助第三方的jar包的导入以及配置文件的书写,但是对于一些平常的jdbc需求已经是可以满足了,那么下面我将完整的ORM封装书写下来:

java">package com.softeem.DButils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;

import com.alibaba.druid.pool.DruidDataSource;

/**
 * 封装增删改查操作:最终版
 * @author 黄小宝
 */
public class DButils {

    /** 驱动类路径 */
    private static String DRIVER_CLASS;
    /** url地址 */
    private static String URL;
    /** 数据库服务器登录用户名 */
    private static String USER;
    /** 数据库服务器登录密码 */
    private static String PASSWORD;

    /**最大活动链接数*/
    private static int MAX_ACTIVE;
    /**最长等待连接获取的时间*/
    private static long MAX_WAIT;
    /**初始链接数*/
    private static int INIT_SIZE;

    /**声明连接池引用*/
    private static DruidDataSource ds;

    static {
        try {
            //读取属性文件获取连接数据库相关的字符串
            //InputStream is = DButils.class.getResourceAsStream("src/jdbc.properties");
            InputStream is  = new FileInputStream(new File("C:\\Users\\黄小宝\\Desktop\\jdbc.txt"));
            //创建属性对象
            Properties p = new Properties();
            //加载包含属性信息的输入流
            System.out.println(is);
            p.load(is);

            //根据属性名获取属性值
            DRIVER_CLASS = p.getProperty("driver");
            URL = p.getProperty("url");
            USER = p.getProperty("user");
            PASSWORD = p.getProperty("password");

            //获取连接池相关配置
            MAX_ACTIVE = Integer.parseInt(p.getProperty("pool.maxActive"));
            INIT_SIZE = Integer.parseInt(p.getProperty("pool.initSize"));
            MAX_WAIT = Long.parseLong(p.getProperty("pool.maxWait"));

            //初始化连接池
           init();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化连接池
     */
    public static void init() {
        ds = new DruidDataSource();
        ds.setDriverClassName(DRIVER_CLASS);
        ds.setUrl(URL);
        ds.setUsername(USER);
        ds.setPassword(PASSWORD);
        ds.setMaxActive(MAX_ACTIVE);
        ds.setInitialSize(INIT_SIZE);
        ds.setMaxWait(MAX_WAIT);
    }

    /**
     * 2. 获取数据库连接对象
     * @return
     */
    public static synchronized Connection getConn() {
        try {
            //当连接池被关闭或者为null重新初始化
            if(ds == null || ds.isClosed()) {
                init();
            }
            //从连接池中获取一个连接并返回
            return ds.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 6.关闭资源
     *
     * @param rs
     * @param stat
     * @param conn
     */
    public static void close(ResultSet rs, Statement stat, Connection conn) {
        try {
            if (rs != null)
                rs.close();
            if (stat != null)
                stat.close();
            if (conn != null)
                conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 封装通用的更新操作:INSERT UPDATE DELETE
     *  使用同一个连接对象,避免出现事务的原子性问题(在传递该连接对象时,可以通过构造器进行传参)
     * @param sql
     * @param params Object[] params
     * @return
     */
    public static boolean exeUpdate(Connection conn,String sql, Object... params) {
        PreparedStatement ps = null;
        try {
            ps = conn.prepareStatement(sql);
            if (params != null) {
                for (int i = 0; i < params.length; i++) {
                    ps.setObject(i + 1, params[i]);
                }
            }
            return ps.executeUpdate() > 0;
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            close(null, ps, null);
        }
        return false;
    }

    /**
     * 封装通用的更新操作:INSERT UPDATE DELETE
     * 不需要使用到同一个连接对象时,调用该方法 :
     * 每调用一次:getConn()方法,就会创建一个新的connection对象,而事务中必须要满足原子性,即同一个连接对象,
     * 所以该方法不满足事务的要求
     * @param sql
     * @param params Object[] params
     * @return
     */
    public static boolean exeUpdate(String sql, Object... params) {
        Connection conn = getConn();
        PreparedStatement ps = null;
        try {
            ps = conn.prepareStatement(sql);
            if (params != null) {
                for (int i = 0; i < params.length; i++) {
                    ps.setObject(i + 1, params[i]);
                }
            }
            return ps.executeUpdate() > 0;
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            close(null, ps, conn);
        }
        return false;
    }

    /**
     * 封装通用查询单条数据的方法
     *
     * JDBC,反射,集合框架,lambda表达式,新增Objects类
     *
     * @param <T>
     * @param t
     * @param sql
     * @param params
     * @return
     */
    public static <T> T queryOne(Class<T> t, String sql, Object... params) {
        // 获取查询到到数据集合
        List<Map<String, Object>> list = queryMaps(sql, params);
        if (list.size() > 0) {
            // 获取一个Map对象
            Map<String, Object> map = list.get(0);
            // 将map集合转换为Javabean并返回
            return mapToBean(map, t);
        }
        return null;
    }

    /**
     * 封装通用查询多条数据的方法
     *
     * @param <T>
     * @param t
     * @param sql
     * @param params
     * @return
     */
    public static <T> List<T> queryList(Class<T> t, String sql, Object... params) {
        List<T> list = new ArrayList<T>();
        // 获取所有查询的到的数据
        List<Map<String, Object>> maps = queryMaps(sql, params);
        // 遍历集合中每一条数据(map)
        maps.forEach(m -> {
            // 将map转换为Javabean
            T obj = mapToBean(m, t);
            // 将Javabean装入list
            list.add(obj);
        });
        return list;
    }

    /**
     * 将Map集合转换为一个确定的类型
     *
     * @param <T>
     * @param map
     * @param t
     * @return
     */
    private static <T> T mapToBean(Map<String, Object> map, Class<T> t) {
//		T obj = null;
        try {
            // 根据提供的Class对象创建对应类型的Object
            T obj = t.newInstance();
            // 获取Class中的所有Field
//			Field[] fields = t.getDeclaredFields();
//			//遍历获取每一个属性对象
//			for (Field field : fields) {
//				//获取属性名
//				String fname = field.getName();
//				//获取属性值
//				Object value = map.get(fname);
//				if(Objects.nonNull(value)) {
//					//设置属性对象的可访问性
//					field.setAccessible(true);
//					//将从map中获取的值设置给属性  obj.name=XX
//					field.set(obj, value);
//				}
//			}
            map.forEach((k, v) -> {
                try {
                    // 根据Field名称获取字段对象
                    Field field = t.getDeclaredField(k);
                    // 设置字段的可访问性
                    field.setAccessible(true);
                    // 为字段设置值
                    field.set(obj, v);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            });
            return obj;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        // 返回对象
        return null;
    }

    /**
     * 执行相关查询并将结果返回为List<Map<String,Object>> 集合
     *
     * @param sql
     * @param params
     * @return
     */
    public static List<Map<String, Object>> queryMaps(String sql, Object... params) {
        // 声明动态数组用于存储每一个查询到的Map对象
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        // 获取连接
        Connection conn = getConn();
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            // 获取预处理sql命令的对象
            ps = conn.prepareStatement(sql);
            if (params != null) {
                for (int i = 0; i < params.length; i++) {
                    // 对指定位置的占位符填充值(预处理)
                    ps.setObject(i + 1, params[i]);
                }
            }
            // 执行查询获取结果集
            rs = ps.executeQuery();
            // 获取结果集的元数据对象ResultSetMetaData
            ResultSetMetaData rsmd = rs.getMetaData();
            // 获取总查询列数
            int columnCount = rsmd.getColumnCount();
            // 遍历结果集
            while (rs.next()) {
                // 声明map集合存储每一条数据(临时缓存)
                Map<String, Object> map = new HashMap<String, Object>();
                // 遍历获取每一列的信息
                for (int i = 1; i <= columnCount; i++) {
                    // 获取列名称(作为map集合的键)
                    String key = rsmd.getColumnName(i);
                    // 获取列标签
                    String label = rsmd.getColumnLabel(i);
                    // 获取列值(作为map集合的值)
                    Object value = rs.getObject(label);
                    if (Objects.nonNull(value)) {
                        // 将取到的每一列的列名与列值存储到map
                        map.put(key, value);
                    }
                }
                // 将map集合装入list
                list.add(map);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            close(rs, ps, conn);
        }
        return list;
    }

    /**
     * 根据提供的查询语句以及查询参数,返回符合条件的数目
     *
     * @param sql
     * @param params
     * @return
     */
    public static int queryCount(String sql, Object... params) {
        Connection conn = getConn();
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conn.prepareStatement(sql);
            if (params != null) {
                for (int i = 0; i < params.length; i++) {
                    ps.setObject(i + 1, params[i]);
                }
            }
            rs = ps.executeQuery();
            if(rs.next()) {
                return rs.getInt(1);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            close(rs, ps, conn);
        }
        return 0;
    }
}

  • 在使用的时候也是非常简单的:例如我给大家做一下简单的测试:
java">package com.softeem.day804.Utils;

import java.util.List;
import com.softeem.day804.VO.Emp;

public class Test {
	
	public static void main(String[] args) {
		
		String sql = "select * from emp";
		List<Emp> list = DBUtils.queryList(Emp.class, sql);
		list.forEach(l->System.out.println(l));
	}
}

  • 执行结果(返回的都是一个个Java对象):
java">Emp [eno=2, ename=阿卡丽, job=经理, hiredate=2017-04-01 00:00:00.0, age=31, sex=, sal=9800.0, dno=0]
Emp [eno=3, ename=露露, job=普通员工, hiredate=2020-03-22 00:00:00.0, age=22, sex=, sal=2200.0, dno=40]
Emp [eno=5, ename=阿木木, job=普通员工, hiredate=2017-11-22 00:00:00.0, age=27, sex=, sal=5000.0, dno=40]
Emp [eno=6, ename=阿德, job=普通员工, hiredate=2018-08-05 00:00:00.0, age=21, sex=, sal=3160.0, dno=30]
Emp [eno=7, ename=艾希, job=经理, hiredate=2015-03-03 00:00:00.0, age=29, sex=, sal=10500.0, dno=0]
Emp [eno=8, ename=易大师, job=经理, hiredate=2016-09-10 00:00:00.0, age=35, sex=, sal=8900.0, dno=30]
Emp [eno=9, ename=甄姬, job=普通员工, hiredate=2017-09-09 00:00:00.0, age=27, sex=, sal=9900.0, dno=0]
Emp [eno=10, ename=后裔, job=普通员工, hiredate=2020-01-01 00:00:00.0, age=30, sex=, sal=8400.0, dno=0]
Emp [eno=11, ename=猪八戒, job=普通员工, hiredate=2020-07-22 00:00:00.0, age=45, sex=, sal=3200.0, dno=0]
Emp [eno=12, ename=廉颇, job=普通员工, hiredate=2018-07-06 00:00:00.0, age=55, sex=, sal=6800.0, dno=40]
Emp [eno=13, ename=李青, job=普通员工, hiredate=2019-07-22 00:00:00.0, age=36, sex=, sal=6900.0, dno=50]
Emp [eno=14, ename=李白, job=经理, hiredate=2016-01-01 00:00:00.0, age=36, sex=, sal=16600.0, dno=40]
Emp [eno=15, ename=赵信, job=经理, hiredate=2018-09-11 00:00:00.0, age=38, sex=, sal=7500.0, dno=50]
Emp [eno=16, ename=安妮, job=普通员工, hiredate=2019-10-11 00:00:00.0, age=18, sex=, sal=3900.0, dno=60]
Emp [eno=17, ename=提莫, job=普通员工, hiredate=2019-10-12 00:00:00.0, age=19, sex=, sal=5600.0, dno=60]
Emp [eno=18, ename=韦鲁斯, job=经理, hiredate=2018-05-10 00:00:00.0, age=30, sex=, sal=7800.0, dno=60]
Emp [eno=19, ename=德莱文, job=普通员工, hiredate=2018-09-11 00:00:00.0, age=35, sex=, sal=9000.0, dno=50]
Emp [eno=20, ename=艾维利亚, job=普通员工, hiredate=2017-06-30 00:00:00.0, age=26, sex=, sal=2200.0, dno=30]
Emp [eno=123, ename=黄国志, job=null, hiredate=null, age=0, sex=null, sal=0.0, dno=0]

  • 以上就整个CRUD的简易封装了,如有错误还请指出

http://www.niftyadmin.cn/n/899492.html

相关文章

目前所学的Java零碎知识

字符串拼接、Math函数、包装类型 Integer和int、泛型、日期类型 字符串拼接 String String:不可变字符串,对其做的任何替换&#xff0c;查找&#xff0c;修改等操作都是 拷贝了原字符串&#xff0c;对拷贝的副本进行操作并返回 字符串的创建 //方式1&#xff1a;直接赋值St…

简易的表单验证

简易的后台登录界面 在这个给大家制作一个简易的后台登录界面&#xff0c;他使用到了&#xff1a;HTML&#xff0c;CSS,JS相关的知识&#xff0c;实现的大致功能就是&#xff1a;账户和密码不能为空&#xff0c;才能够登录&#xff08;实现的功能比较简易&#xff0c;所以在点…

servlet的简单应用应用以及动态的表单验证

在javaweb中&#xff0c;web服务器里面最重要的一部分莫过于Servlet了吧&#xff0c;今天就用一个简单的例子来说明Servlet的应用 首先&#xff0c;在写这个项目之前&#xff0c;先从我自己理解的角度来说一下服务器里面一些概念性的东西 web服务器&#xff08;web容器&#…

基于Servlet的BaseServlet封装

在web服务器中&#xff0c;每当客户端浏览器发送一个请求的时候&#xff0c;我们都要去创建一个servlet去完成相应的请求并返回响应&#xff0c;这样显得就很麻烦&#xff0c;有多少个请求就必须创建多少个servlet&#xff0c;其中的代码重复量太大了&#xff0c;所以&#xff…

图书管理面向对象滴

图书管理(控制台输入)练习 建一个book类 package com.booktest; //属性:编号 书名 作者 价格 书籍类型(如 玄幻 文学等) public class Book {private int number;private String bookname;private String author;private double price;private int count;private String type…

联系人管理

联系人管理 联系人管理: 1.联系人类:姓名 电话 地址 2.联系人管理类: a.通过首字母给联系人分组添加到通讯录中!b.通过电话查询联系人c.通过姓名删除联系人(注意,如果当前分组只剩下最后一个人需要将分组也删除)d.查看有几个分组,以及一共几个联系人e.通过姓名,修改联系人的电…

json解析与XML解析

log4j与json解析和XML解析 log4j的组成 日志记录器(logger):控制日志的级别 设置级别 日志会分级别去打印: 级别(从高到低) 1.off 2.fatal 3.error 4.warn 5.info 6.debug 7.all 注意:对我们而言,建议使用error warn info debug 输出端(Appender):控制日志输出的位置(控制台或…

XML解析题

XML解析题 XML解析题目 对照着Cartoon.xml里根节点有两个子节点 results和page根据字节点中的内容创建实体类 创建page实体 package com.pase;public class Page {private String pageNo;private String pageSize;private String totalCount;public Page() {}public Page(St…