JDBC操作题目
JDBC代码
- import java.sql.*;
- import java.util.ArrayList;
- import java.util.List;
- public class JDBC {
- public static void main(String[] args) {
- Connection connection = null;
- PreparedStatement preparedStatement = null;
- ResultSet resultSet = null;
- try {
- //加载驱动
- Class.forName("com.mysql.jdbc.Driver");
- //创建连接
- connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", " root", " root");
- //写sql语句
- String sql = "select * from user where username = ?";
- //获取预处理对象
- preparedStatement = connection.prepareStatement(sql);
- //设置参数
- preparedStatement.setString(1, "tom");
- //执行sql,获取结果集
- resultSet = preparedStatement.executeQuery();
- //封装结果集
- List<User> userList = new ArrayList<>();
- while (resultSet.next()) {
- User user = new User();
- int id = resultSet.getInt("id");
- String username = resultSet.getString("username");
- user.setId(id);
- user.setUsername(username);
- userList.add(user);
- }
- System.out.println(userList);
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- } catch (SQLException e) {
- e.printStackTrace();
- } finally {
- //关闭资源
- if (resultSet != null) {
- try {
- resultSet.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- if (preparedStatement != null) {
- try {
- preparedStatement.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- if (connection != null) {
- try {
- connection.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
复制代码 JDBC题目总结
- 频繁创建、释放数据库连接,造成系统资源浪费
- sql语句在代码中硬编码,不易维护
- 传参存在硬编码,修改sql还要修改代码
- 手动解析结果集
JDBC题目办理思绪
- 利用数据库连接池初始化连接资源
- 将sql语句抽取到xml配置文件中
- 利用反射技能,将实体属性与表字段自动映射
自定义框架设计
利用端
提供核心配置文件:
sqlMapConfig.xml:存放数据源信息,引入Mapper.xml的全路径
Mapper.xml:sql语句的配置文件信息
框架端
读取后以流的情势存在于内存中,后创建JavaBean存储
Configuration:存放数据库的根本信息、Map<唯一标识,Mapper>
唯一标识:namespace+“.”+id
MappedStatement:sql语句、statement类型、输入参数类型、输出参数类型
创建SqlSessionFactoryBuilder类
方法:SqlSessionFactory build()
利用dom4j解析配置文件,将解析出来的内容封装到Configuration和MappedStatement
创建SqlSessionFactory的实现类DefaultSqlSessionFactory。
方法:openSession():获取sqlSession接口的实现类的实例对象
方法:selectOne(String statementId,Object… params)
selectList(String statementId,Object… params)
封装JDBC代码实现CRUD
** 设计模式:制作者模式、工厂模式、代理模式**
自定义框架实现
在利用端创建配置文件
- <configuration>
- <dataSource>
- <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
- <property name="jdbcUrl" value="jdbc:mysql:///test"></property>
- <property name="username" value="root"></property>
- <property name="password" value="@wdlm212027"></property>
- </dataSource>
- <mapper resource="UserMapper.xml"></mapper>
- </configuration>
复制代码- <mapper namespace="user">
- <select id="selectList" resultType="com.wdlm.pojo.User">
- select * from user
- </select>
- <select id="selectOne" resultType="com.wdlm.pojo.User" parameterType="com.wdlm.pojo.User">
- select * from user where id=#{id} and username=#{username}
- </select>
- </mapper>
复制代码 在利用端创建实体类
- public class User {
- private Integer id;
- private String username;
- public User() {
- }
- public User(Integer id, String username) {
- this.id = id;
- this.username = username;
- }
- public Integer getId() {
- return id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getUsername() {
- return username;
- }
- public void setUsername(String username) {
- this.username = username;
- }
- }
复制代码 在框架端导入Maven依赖
- <?xml version="1.0" encoding="UTF-8"?>
- <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.wdlm.imybatis</groupId>
- <artifactId>Imybatis</artifactId>
- <version>1.0-SNAPSHOT</version>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
- <java.version>1.8</java.version>
- <maven.compiler.source>1.8</maven.compiler.source>
- <maven.compiler.target>1.8</maven.compiler.target>
- </properties>
- <dependencies>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>5.1.17</version>
- </dependency>
- <dependency>
- <groupId>c3p0</groupId>
- <artifactId>c3p0</artifactId>
- <version>0.9.1.2</version>
- </dependency>
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>1.2.12</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.10</version>
- </dependency>
- <dependency>
- <groupId>dom4j</groupId>
- <artifactId>dom4j</artifactId>
- <version>1.6.1</version>
- </dependency>
- <dependency>
- <groupId>jaxen</groupId>
- <artifactId>jaxen</artifactId>
- <version>1.1.6</version>
- </dependency>
- </dependencies>
- </project>
复制代码 在框架端创建配置类
- import javax.sql.DataSource;
- import java.util.HashMap;
- import java.util.Map;
- public class Configuration {
- private DataSource dataSource;
- Map<String, MappedStatement> mappedStatementMap = new HashMap<String, MappedStatement>();
- public DataSource getDataSource() {
- return dataSource;
- }
- public void setDataSource(DataSource dataSource) {
- this.dataSource = dataSource;
- }
- public Map<String, MappedStatement> getMappedStatementMap() {
- return mappedStatementMap;
- }
- public void setMappedStatementMap(Map<String, MappedStatement> mappedStatementMap) {
- this.mappedStatementMap = mappedStatementMap;
- }
- }
复制代码- public class MappedStatement {
- private String id;
- private String resultType;
- private String parameterType;
- private String sql;
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- public String getResultType() {
- return resultType;
- }
- public void setResultType(String resultType) {
- this.resultType = resultType;
- }
- public String getParameterType() {
- return parameterType;
- }
- public void setParameterType(String paramterType) {
- this.parameterType = paramterType;
- }
- public String getSql() {
- return sql;
- }
- public void setSql(String sql) {
- this.sql = sql;
- }
- }
复制代码 在框架端创建配置文件读取类
- public class Resources {
- public static InputStream getResourceAsStream(String path) {
- InputStream resource = Resources.class.getClassLoader().getResourceAsStream(path);
- return resource;
- }
- }
复制代码 在框架端创建SqlSessionFactoryBuilder
- public class SqlSessionFactoryBuilder {
- public SqlSessionFactory build(InputStream resource) throws PropertyVetoException, DocumentException {
- XMLConfigBuilder xmlConfigBuilder = new XMLConfigBuilder();
- Configuration configuration = xmlConfigBuilder.parseConfig(resource);
- DefaultSqlSessionFactory defaultSqlSessionFactory = new DefaultSqlSessionFactory(configuration);
- return defaultSqlSessionFactory;
- }
- }
复制代码 在框架端创建解析类
- public class XMLConfigBuilder {
- private Configuration configuration;
- public XMLConfigBuilder() {
- configuration = new Configuration();
- }
- public Configuration parseConfig(InputStream resource) throws DocumentException, PropertyVetoException {
- Document document = new SAXReader().read(resource);
- Element rootElement = document.getRootElement();
- List<Element> list = rootElement.selectNodes("//property");
- Properties properties = new Properties();
- for (Element element : list) {
- String name = element.attributeValue("name");
- String value = element.attributeValue("value");
- properties.setProperty(name, value);
- }
- ComboPooledDataSource dataSource = new ComboPooledDataSource();
- dataSource.setDriverClass(properties.getProperty("driverClass"));
- dataSource.setJdbcUrl(properties.getProperty("jdbcUrl"));
- dataSource.setUser(properties.getProperty("username"));
- dataSource.setPassword(properties.getProperty("password"));
- configuration.setDataSource(dataSource);
- List<Element> mapperList = rootElement.selectNodes("//mapper");
- for (Element element : mapperList) {
- String mapperPath = element.attributeValue("resource");
- InputStream mapperResource = Resources.getResourceAsStream(mapperPath);
- XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(configuration);
- xmlMapperBuilder.parse(mapperResource);
- }
- return configuration;
- }
- }
复制代码- public class XMLMapperBuilder {
- private Configuration configuration;
- public XMLMapperBuilder(Configuration configuration) {
- this.configuration = configuration;
- }
- public void parse(InputStream resource) throws DocumentException {
- Document document = new SAXReader().read(resource);
- Element rootElement = document.getRootElement();
- List<Element> list = rootElement.selectNodes("//select");
- String namespace = rootElement.attributeValue("namespace");
- for (Element element : list) {
- String id = element.attributeValue("id");
- String resultType = element.attributeValue("resultType");
- String parameterType = element.attributeValue("parameterType");
- String sql = element.getTextTrim();
- MappedStatement mappedStatement = new MappedStatement();
- mappedStatement.setId(id);
- mappedStatement.setParameterType(parameterType);
- mappedStatement.setResultType(resultType);
- mappedStatement.setSql(sql);
- String key = namespace + "." + id;
- configuration.getMappedStatementMap().put(key, mappedStatement);
- }
- }
- }
复制代码 在框架端创建SqlSessionFactory接口及着实现类
- public interface SqlSessionFactory {
- public SqlSession openSession();
- }
复制代码- public class DefaultSqlSessionFactory implements SqlSessionFactory {
- private Configuration configuration;
- public DefaultSqlSessionFactory(Configuration configuration) {
- this.configuration = configuration;
- }
- @Override
- public SqlSession openSession() {
- return new DefaultSqlSession(configuration);
- }
- }
复制代码 在框架端创建SqlSession接口及着实现类
- public interface SqlSession {
- public <E> List<E> selectList(String statementId, Object... params);
- public <T> T selectOne(String statementId, Object... params) throws Exception;
- }
复制代码- public class DefaultSqlSession implements SqlSession {
- private Configuration configuration;
- public DefaultSqlSession(Configuration configuration) {
- this.configuration = configuration;
- }
- @Override
- public <E> List<E> selectList(String statementId, Object... params) throws Exception {
- SimpleExecutor simpleExecutor = new SimpleExecutor();
- MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
- List<Object> list = simpleExecutor.query(configuration, mappedStatement, params);
- return (List<E>) list;
- }
- @Override
- public <T> T selectOne(String statementId, Object... params) throws Exception {
- List<Object> objects = selectList(statementId, params);
- if (objects.size()==1){
- return (T) objects.get(0);
- }else {
- throw new RuntimeException("查询结果为空或者过多");
- }
- }
- }
复制代码 在框架端创建Executor接口及着实现类
- public interface Executor {
- public <E>List<E> query(Configuration configuration, MappedStatement mappedStatement,Object... params);
- }
复制代码- public class SimpleExecutor implements Executor {
- @Override
- public <E> List<E> query(Configuration configuration, MappedStatement mappedStatement, Object... params) throws Exception {
- DataSource dataSource = configuration.getDataSource();
- Connection connection = dataSource.getConnection();
- String sql = mappedStatement.getSql();
- BoundSql boundSql = getBoundSql(sql);
- PreparedStatement preparedStatement = connection.prepareStatement(boundSql.getSql());
- List<ParameterMapping> parameterMappingList = boundSql.getParameterMappingList();
- String parameterType = mappedStatement.getParameterType();
- Class<?> parameterClass = getClassType(parameterType);
- for (int i = 0; i < parameterMappingList.size(); i++) {
- ParameterMapping parameterMapping = parameterMappingList.get(i);
- String content = parameterMapping.getContent();
- Field declaredField = parameterClass.getDeclaredField(content);
- declaredField.setAccessible(true);
- Object o = declaredField.get(params[0]);
- preparedStatement.setObject(i + 1, o);
- }
- ResultSet resultSet = preparedStatement.executeQuery();
- String resultType = mappedStatement.getResultType();
- Class<?> resultTypeClass = getClassType(resultType);
- Object o = resultTypeClass.newInstance();
- ArrayList<Object> objects = new ArrayList<>();
- while (resultSet.next()) {
- ResultSetMetaData metaData = resultSet.getMetaData();
- for (int i = 1; i <= metaData.getColumnCount(); i++) {
- String columnName = metaData.getColumnName(i);
- Object value = resultSet.getObject(columnName);
- PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName, resultTypeClass);
- Method writeMethod = propertyDescriptor.getWriteMethod();
- writeMethod.invoke(o,value);
- objects.add(o);
- }
- }
- return (List<E>) objects;
- }
- private BoundSql getBoundSql(String sql) {
- ParameterMappingTokenHandler parameterMappingTokenHandler = new ParameterMappingTokenHandler();
- GenericTokenParser genericTokenParser = new GenericTokenParser("#{", "}", parameterMappingTokenHandler);
- String parseSql = genericTokenParser.parse(sql);
- List<ParameterMapping> parameterMappings = parameterMappingTokenHandler.getParameterMappings();
- BoundSql boundSql = new BoundSql(parseSql, parameterMappings);
- return boundSql;
- }
- private Class<?> getClassType(String parameterType) throws ClassNotFoundException {
- if (parameterType != null) {
- return Class.forName(parameterType);
- }
- return null;
- }
- }
复制代码 在框架端创建Sql解析类
- public class BoundSql {
- private String sql;
- private List<ParameterMapping> parameterMappingList = new ArrayList<>();
- public BoundSql() {
- }
- public BoundSql(String sql, List<ParameterMapping> parameterMappingList) {
- this.sql = sql;
- this.parameterMappingList = parameterMappingList;
- }
- public String getSql() {
- return sql;
- }
- public void setSql(String sql) {
- this.sql = sql;
- }
- public List<ParameterMapping> getParameterMappingList() {
- return parameterMappingList;
- }
- public void setParameterMappingList(List<ParameterMapping> parameterMappingList) {
- this.parameterMappingList = parameterMappingList;
- }
- }
复制代码 在框架端创建Sql解析工具类
- public interface TokenHandler {
- String handleToken(String content);
- }
复制代码- public class GenericTokenParser {
- private final String openToken; //开始标记
- private final String closeToken; //结束标记
- private final com.wdlm.utils.TokenHandler handler; //标记处理器
- public GenericTokenParser(String openToken, String closeToken, com.wdlm.utils.TokenHandler handler) {
- this.openToken = openToken;
- this.closeToken = closeToken;
- this.handler = handler;
- }
- /**
- * 解析${}和#{}
- * @param text
- * @return
- * 该方法主要实现了配置文件、脚本等片段中占位符的解析、处理工作,并返回最终需要的数据。
- * 其中,解析工作由该方法完成,处理工作是由处理器handler的handleToken()方法来实现
- */
- public String parse(String text) {
- // 验证参数问题,如果是null,就返回空字符串。
- if (text == null || text.isEmpty()) {
- return "";
- }
- // 下面继续验证是否包含开始标签,如果不包含,默认不是占位符,直接原样返回即可,否则继续执行。
- int start = text.indexOf(openToken, 0);
- if (start == -1) {
- return text;
- }
- // 把text转成字符数组src,并且定义默认偏移量offset=0、存储最终需要返回字符串的变量builder,
- // text变量中占位符对应的变量名expression。判断start是否大于-1(即text中是否存在openToken),如果存在就执行下面代码
- char[] src = text.toCharArray();
- int offset = 0;
- final StringBuilder builder = new StringBuilder();
- StringBuilder expression = null;
- while (start > -1) {
- // 判断如果开始标记前如果有转义字符,就不作为openToken进行处理,否则继续处理
- if (start > 0 && src[start - 1] == '\\') {
- builder.append(src, offset, start - offset - 1).append(openToken);
- offset = start + openToken.length();
- } else {
- //重置expression变量,避免空指针或者老数据干扰。
- if (expression == null) {
- expression = new StringBuilder();
- } else {
- expression.setLength(0);
- }
- builder.append(src, offset, start - offset);
- offset = start + openToken.length();
- int end = text.indexOf(closeToken, offset);
- while (end > -1) {存在结束标记时
- if (end > offset && src[end - 1] == '\\') {//如果结束标记前面有转义字符时
- // this close token is escaped. remove the backslash and continue.
- expression.append(src, offset, end - offset - 1).append(closeToken);
- offset = end + closeToken.length();
- end = text.indexOf(closeToken, offset);
- } else {//不存在转义字符,即需要作为参数进行处理
- expression.append(src, offset, end - offset);
- offset = end + closeToken.length();
- break;
- }
- }
- if (end == -1) {
- // close token was not found.
- builder.append(src, start, src.length - start);
- offset = src.length;
- } else {
- //首先根据参数的key(即expression)进行参数处理,返回?作为占位符
- builder.append(handler.handleToken(expression.toString()));
- offset = end + closeToken.length();
- }
- }
- start = text.indexOf(openToken, offset);
- }
- if (offset < src.length) {
- builder.append(src, offset, src.length - offset);
- }
- return builder.toString();
- }
- }
复制代码- public class ParameterMapping {
- private String content;
- public ParameterMapping(String content) {
- this.content = content;
- }
- public String getContent() {
- return content;
- }
- public void setContent(String content) {
- this.content = content;
- }
- }
复制代码- public class ParameterMappingTokenHandler implements com.wdlm.utils.TokenHandler {
- private List<ParameterMapping> parameterMappings = new ArrayList<ParameterMapping>();
- // context是参数名称 #{id} #{username}
- public String handleToken(String content) {
- parameterMappings.add(buildParameterMapping(content));
- return "?";
- }
- private ParameterMapping buildParameterMapping(String content) {
- ParameterMapping parameterMapping = new ParameterMapping(content);
- return parameterMapping;
- }
- public List<ParameterMapping> getParameterMappings() {
- return parameterMappings;
- }
- public void setParameterMappings(List<ParameterMapping> parameterMappings) {
- this.parameterMappings = parameterMappings;
- }
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |