连云港做网站优化,wordpress播放上传视频,比较好网站搭建公司,asp做网站搜索通用的增删改查1. 利用xml配置实体类和数据库表名的映射关系2. 根据xml设计#xff0c;用正确的数据结构映射类封装好xml信息3. 得到数据库连接前#xff0c;读取xml信息#xff0c;用map封装成映射数据4. 写dao时根据反射和map生成sql语句#xff0c;拿到属性值测试为了解…
通用的增删改查1. 利用xml配置实体类和数据库表名的映射关系2. 根据xml设计用正确的数据结构映射类封装好xml信息3. 得到数据库连接前读取xml信息用map封装成映射数据4. 写dao时根据反射和map生成sql语句拿到属性值测试为了解决上一篇文中实体类的局限性不可加字段实体名表名列的字段一样而且顺序一样上一篇反射实现dao层增删改查 本文实现结构
1. 利用xml配置实体类和数据库表名的映射关系
sql语句
create table ticket_info (ticket_id number primary key,ticket_name varchar(30) not null, ticket_price number(10, 2) not null
)
create sequence ticket_seqcreate table goods_info (goods_id number primary key, goods_name varchar(30) not null,goods_price number(10, 2) not null,goods_date date not null, goods_factory varchar(50) not null
)
create sequence goods_seqxml, 映射表属性和实体类列 goods.xml
?xml version1.0 encodingUTF-8?class namecom.lovely.entity.Goods tablegoods_infoid namegid columngoods_idsequencegoods_seq/sequence/idproperty namegname columngoods_name/propertyproperty namegprice columngoods_price/propertyproperty namegdate columngoods_date/propertyproperty namegfactory columngoods_factory/property
/class
ticket.xml
?xml version1.0 encodingUTF-8?!-- 实体类和表之间的映射关系 --
class namecom.lovely.entity.Ticket tableticket_info !-- 类名和表名的映射关系 --id nametid columnticket_id !-- 实体主键和表中主键列的映射关系 --sequenceticket_seq/sequence/idproperty nametname columnticket_name/property !-- 属性名和表名列的映射关系 --property nametprice columnticket_price/property/classgoods, 和 entity的实体类
package com.lovely.entity;import java.sql.Date;public class Goods {private Integer gid;private String gname;private Double gprice;private Date gdate;private String gfactory;public Goods() {}public Integer getGid() {return gid;}public void setGid(Integer gid) {this.gid gid;}public String getGname() {return gname;}public void setGname(String gname) {this.gname gname;}public Double getGprice() {return gprice;}public void setGprice(Double gprice) {this.gprice gprice;}public Date getGdate() {return gdate;}public void setGdate(Date gdate) {this.gdate gdate;}public String getGfactory() {return gfactory;}public void setGfactory(String gfactory) {this.gfactory gfactory;}}
package com.lovely.entity;public class Ticket {private Integer tid;private String tname;private Double tprice;public Ticket() {}public Ticket(Integer tid, String tname, Double tprice) {super();this.tid tid;this.tname tname;this.tprice tprice;}public Integer getTid() {return tid;}public void setTid(Integer tid) {this.tid tid;}public String getTname() {return tname;}public void setTname(String tname) {this.tname tname;}public Double getTprice() {return tprice;}public void setTprice(Double tprice) {this.tprice tprice;}Overridepublic String toString() {return Ticket [tid tid , tname tname , tprice tprice ]\n;}}
2. 根据xml设计用正确的数据结构映射类封装好xml信息
主键id
package com.lovely.base;public class MapperId {// 实体id 映射 数据库idprivate String idName;private String idColumn;private String seqName;public String getIdName() {return idName;}public void setIdName(String idName) {this.idName idName;}public String getIdColumn() {return idColumn;}public void setIdColumn(String idColumn) {this.idColumn idColumn;}public String getSeqName() {return seqName;}public void setSeqName(String seqName) {this.seqName seqName;}Overridepublic String toString() {return MapperId [idName idName , idColumn idColumn , seqName seqName ];}}
MapperData 映射数据类
package com.lovely.base;import java.util.LinkedHashMap;public class MapperData {// 映射文件类// 实体全类名private String className;// 表名private String tableName;private MapperId mapperId;// 存储除主键外 实体属性 - 数据表列 相关信息private LinkedHashMapString, String properties new LinkedHashMapString, String();public String getClassName() {return className;}public void setClassName(String className) {this.className className;}public String getTableName() {return tableName;}public void setTableName(String tableName) {this.tableName tableName;}public MapperId getMapperId() {return mapperId;}public void setMapperId(MapperId mapperId) {this.mapperId mapperId;}public LinkedHashMapString, String getProperties() {return properties;}public void setProperties(LinkedHashMapString, String properties) {this.properties properties;}Overridepublic String toString() {return MapperData [className className , tableName tableName , mapperId mapperId , properties properties ]\n;}}
3. 得到数据库连接前读取xml信息用map封装成映射数据
实体属性名和表的列名一样也封装在map里面了
package com.lovely.dao;import java.io.File;
import java.lang.reflect.Field;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;import com.lovely.base.MapperData;
import com.lovely.base.MapperId;public class BaseDao {static {try {Class.forName(oracle.jdbc.OracleDriver);} catch (ClassNotFoundException e) {e.printStackTrace();}}/*** key: 全路径类名 * value: 类和表的映射关系 MapperData*/public static HashMapString, MapperData map new HashMapString, MapperData();static {// 静态块解析xml映射文件try { Class? baseDaoClass Class.forName(com.lovely.dao.BaseDao);// 得到xml路径URL url baseDaoClass.getResource(/com/lovely/mapper);String path url.getFile();File file new File(path);// 拿到所有xml文件File[] files file.listFiles();for (int i 0; i files.length; i) {// 解析xml一个文件// System.out.println(files[i].getName());SAXReader reader new SAXReader();Document doc reader.read(files[i]);// 拿到 class结点Element root doc.getRootElement();MapperData mapperData new MapperData();// 保存实体类名mapperData.setClassName(root.attributeValue(name)); // 保存数据表名mapperData.setTableName(root.attributeValue(table));MapperId mapperId new MapperId();// 主键结点映射关系Element primaryKey root.element(id);// 实体类主键mapperId.setIdName(primaryKey.attributeValue(name));// 表的主键mapperId.setIdColumn(primaryKey.attributeValue(column));// 序列名称mapperId.setSeqName(primaryKey.elementText(sequence));// 保存主键结点映射关系mapperData.setMapperId(mapperId);SuppressWarnings(unchecked)// 所有 实体属性-表名结点映射关系ListElement property root.elements(property);LinkedHashMapString, String lhm new LinkedHashMapString, String();for (Element field : property) {lhm.put(field.attributeValue(name), field.attributeValue(column));}mapperData.setProperties(lhm);// 把实体类 与 xml中的映射数据一一对应map.put(root.attributeValue(name), mapperData);}} catch (Exception e) {e.printStackTrace();}}static {// 加载没有配置文件的实体类 try {Class? c BaseDao.class;// mapper下的路径String path c.getResource(/com/lovely/entity).getFile();File file new File(path);File[] files file.listFiles();for (int i 0; i files.length; i) {String fileName files[i].getName();String className com.lovely.entity. fileName.substring(0, fileName.indexOf(.));// 没有映射文件的解析 对于数据库表名字段顺序 和 实体的类名 字段 顺序一样。if (!map.containsKey(className)) {// 实体类的类型描述Class? cc Class.forName(className);MapperData value new MapperData();// 设置实体类名和表名value.setClassName(cc.getName());value.setTableName(cc.getSimpleName());Field[] fields cc.getDeclaredFields();Field.setAccessible(fields, true);// 拿到主键String primaryKeyName fields[0].getName();MapperId mapperId new MapperId();mapperId.setIdName(primaryKeyName);mapperId.setIdColumn(primaryKeyName);mapperId.setSeqName(seq_ cc.getSimpleName());// 属性 主键列名 序列名value.setMapperId(mapperId);LinkedHashMapString, String properties new LinkedHashMapString, String();// 设置除主键意外的属性for (int j 1; j fields.length; j) {properties.put(fields[j].getName(), fields[j].getName());}value.setProperties(properties);map.put(className, value);}}} catch(Exception e) {e.printStackTrace();}}public static void main(String[] args) {System.out.println(map);}public static Connection getConn() {Connection conn null;String url jdbc:oracle:thin:127.0.0.1:1521:orcl;try {conn DriverManager.getConnection(url, scott, scott);} catch (SQLException e) {e.printStackTrace();}return conn;}public static void closeAll(Connection conn, PreparedStatement ps, ResultSet rs) {try {if (rs ! null)rs.close();if (ps ! null)ps.close();if (conn ! null)conn.close();} catch (SQLException e) {e.printStackTrace();}}
}
4. 写dao时根据反射和map生成sql语句拿到属性值
curd实现
package com.lovely.dao;import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;import com.lovely.base.MapperData;
import com.lovely.base.MapperId;/*** * author echo lovely* * 万能增删改查**/
public class CommonDao {public int save(Object entity) {int count -1;Class? c entity.getClass();MapperData mapperData BaseDao.map.get(c.getName());StringBuffer sql new StringBuffer();sql.append(insert into );sql.append(mapperData.getTableName() values ();// insert into tableName values (seq_table.nextval, ?, ?, ?...)sql.append(mapperData.getMapperId().getSeqName() .nextval);LinkedHashMapString,String properties mapperData.getProperties();SetString keySet properties.keySet();// 除主键外的 实体属性名for (int i 0; i keySet.size(); i) {sql.append(, ?);}sql.append());System.out.println(sql);Connection conn BaseDao.getConn();PreparedStatement ps null;try {ps conn.prepareStatement(sql.toString());// 设置参数的值// 取实体列int index 1;for (String entityColumn : keySet) {// 反射根据属性名称拿值Field field c.getDeclaredField(entityColumn);field.setAccessible(true);ps.setObject(index, field.get(entity));index ;}count ps.executeUpdate();} catch (Exception e) {e.printStackTrace();} finally {BaseDao.closeAll(conn, ps, null);}return count;}public ListObject queryAll(Class? c) {ListObject list new ArrayListObject();// 拿到 实体类 与 表的列 映射关系MapperData mapperData BaseDao.map.get(c.getName());String sql select * from mapperData.getTableName();Connection conn BaseDao.getConn();PreparedStatement ps null;ResultSet rs null;LinkedHashMapString, String properties mapperData.getProperties();try {ps conn.prepareStatement(sql);rs ps.executeQuery();// 表主键列名String primaryKeyName mapperData.getMapperId().getIdColumn();String idName mapperData.getMapperId().getIdName();while (rs.next()) {Object entity c.newInstance();Object primaryKeyValue rs.getObject(primaryKeyName); // 主键属性Field primaryFiled c.getDeclaredField(idName);if (primaryFiled.getType() Integer.class)primaryKeyValue rs.getInt(primaryKeyName);primaryFiled.setAccessible(true);primaryFiled.set(entity, primaryKeyValue);SetEntryString,String entrySet properties.entrySet();for (EntryString, String entry : entrySet) {// 属性名称String filedName entry.getKey();// 表的列名String columnName entry.getValue();Object attributValue rs.getObject(columnName);// System.out.println(filedName \t columnName ...);// 除主键外的属性对象Field f c.getDeclaredField(filedName);if (f.getType() Double.class) {attributValue rs.getDouble(columnName);} else if (f.getType() java.sql.Timestamp.class) {attributValue rs.getTimestamp(columnName);}f.setAccessible(true);f.set(entity, attributValue);}list.add(entity); }} catch (Exception e) {e.printStackTrace();} finally {BaseDao.closeAll(conn, ps, rs);}return list;}public Object queryOne(Object obj) {Object entity null;Class? c obj.getClass();MapperData mapperData BaseDao.map.get(c.getName());String sql select * from mapperData.getTableName() where mapperData.getMapperId().getIdColumn() ?;System.out.println(sql);Connection conn BaseDao.getConn();PreparedStatement ps null;ResultSet rs null;try {MapperId mapperId mapperData.getMapperId();ps conn.prepareStatement(sql);// 拿到主键属性对象Field field c.getDeclaredField(mapperId.getIdName());field.setAccessible(true);ps.setObject(1, field.get(obj));rs ps.executeQuery(); LinkedHashMapString,String properties mapperData.getProperties();SetEntryString, String entrySet properties.entrySet();if (rs.next()) {// 记得反射创建对象...entity c.newInstance();Field idFiled c.getDeclaredField(mapperId.getIdName());idFiled.setAccessible(true);// 取到主键值Object idColumn rs.getObject(mapperId.getIdColumn());System.out.println(idColumn \t mapperId.getIdName() \t mapperId.getIdColumn());if (idFiled.getType() Integer.class) {idColumn rs.getInt(mapperId.getIdColumn());} idFiled.set(entity, idColumn);for (EntryString, String entry : entrySet) {Field f1 c.getDeclaredField(entry.getKey());f1.setAccessible(true);Object value rs.getObject(entry.getValue());if (f1.getType() Double.class)value rs.getDouble(entry.getValue());else if (f1.getType() Timestamp.class) {value rs.getTimestamp(entry.getValue());}f1.set(entity, value); }}} catch (Exception e) {e.printStackTrace();} finally {BaseDao.closeAll(conn, ps, rs);}return entity;}public int update(Object entity) {int count -1;Class? c entity.getClass();StringBuffer sql new StringBuffer();// 根据类的全路径 拿到MapperDataMapperData mapperData BaseDao.map.get(c.getName());// update tabName set * ?, * ?, * ? .... where id ?sql.append(update mapperData.getTableName() set );LinkedHashMapString,String properties mapperData.getProperties();// 除了主键外的所有属性集合SetString keySet properties.keySet();// 数据库中表 列的集合CollectionString cloumnNames properties.values();int cloumnSize cloumnNames.size();int index 0;for (String cloumnName : cloumnNames) {if (index cloumnSize - 1) sql.append(cloumnName ?, );else sql.append(cloumnName ?);index ; }sql.append( where mapperData.getMapperId().getIdColumn() ?);System.out.println(sql);Connection conn BaseDao.getConn();PreparedStatement ps null;try {ps conn.prepareStatement(sql.toString());int paramIndex 1;for (String fieldAttribute : keySet) {// 映射的键 - 实体属性对象Field field c.getDeclaredField(fieldAttribute);field.setAccessible(true);Object obj field.get(entity);ps.setObject(paramIndex, obj);paramIndex ;}// 主键属性Field field c.getDeclaredField(mapperData.getMapperId().getIdName());field.setAccessible(true);ps.setObject(paramIndex, field.get(entity));count ps.executeUpdate();} catch (Exception e) {e.printStackTrace();} finally {BaseDao.closeAll(conn, ps, null);}return count;}public int delete(Object obj) {int count -1;Class? c obj.getClass();MapperData mapperData BaseDao.map.get(c.getName());MapperId mapperId mapperData.getMapperId();String sql delete from mapperData.getTableName() where mapperId.getIdColumn() ?;Connection conn BaseDao.getConn();PreparedStatement ps null;try {ps conn.prepareStatement(sql);// 反射拿到实体类 主键属性对象Field field c.getDeclaredField(mapperId.getIdName());field.setAccessible(true);// 根据属性对象 取到 该对象的属性值ps.setObject(1, field.get(obj));count ps.executeUpdate();} catch (Exception e) {e.printStackTrace();} finally {BaseDao.closeAll(conn, ps, null);}return count; }}
测试
一句代码搞定查询。。。 package com.lovely.test;import com.lovely.dao.CommonDao;
import com.lovely.entity.Student;
import com.lovely.entity.Ticket;public class Test1 {public static void main(String[] args) {CommonDao dao new CommonDao();// 学生类的结构和表的结构一样System.out.println(dao.queryAll(Studdent.getClass()));// 配置了xml映射关系的System.out.println(dao.queryAll(Ticket.class));}}
[Student [sid46, snamejack, sgendermale, sbirth2020-07-02 20:24:01.0, saddressnull, sinfonull]
]
[Ticket [tid2, tname花木兰, tprice33.2]
, Ticket [tid3, tname阿凡达2, tprice50.5]
]