生活随笔
收集整理的這篇文章主要介紹了
利用反射和xml配置文件手写一个小型的框架
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
通用的增刪改查
- 1. 利用xml配置實體類和數據庫表名的映射關系
- 2. 根據xml設計,用正確的數據結構映射類封裝好xml信息
- 3. 得到數據庫連接前,讀取xml信息,用map封裝成映射數據
- 4. 寫dao時根據反射和map生成sql語句,拿到屬性值
- 測試
- 為了解決上一篇文中實體類的局限性:不可加字段;實體名,表名,列的字段一樣,而且順序一樣
- 上一篇反射實現dao層增刪改查
- 本文實現結構
1. 利用xml配置實體類和數據庫表名的映射關系
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_seq
create 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_seq
-
xml, 映射表屬性和實體類列
-
goods.xml
<?xml version
="1.0" encoding
="UTF-8"?
><class name
="com.lovely.entity.Goods" table="goods_info"><id name
="gid" column="goods_id"><sequence
>goods_seq
</sequence
></id
><property name
="gname" column="goods_name"></property
><property name
="gprice" column="goods_price"></property
><property name
="gdate" column="goods_date"></property
><property name
="gfactory" column="goods_factory"></property
>
</class
>
<?xml version
="1.0" encoding
="UTF-8"?
><!
<class name
="com.lovely.entity.Ticket" table="ticket_info"> <!<id name
="tid" column="ticket_id"> <!<sequence
>ticket_seq
</sequence
></id
><property name
="tname" column="ticket_name"></property
> <!<property name
="tprice" column="ticket_price"></property
></class
>
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信息
package com
.lovely
.base
;public class MapperId {private 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
+ "]";}}
package com
.lovely
.base
;import java
.util
.LinkedHashMap
;public class MapperData {private String className
;private String tableName
;private MapperId mapperId
;private LinkedHashMap
<String, String> properties
= new LinkedHashMap<String, 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 LinkedHashMap
<String, String> getProperties() {return properties
;}public void setProperties(LinkedHashMap
<String, String> properties
) {this.properties
= properties
;}@Overridepublic String
toString() {return "MapperData [className=" + className
+ ", tableName="+ tableName
+ ", mapperId=" + mapperId
+ ", properties="+ properties
+ "]\n";}}
3. 得到數據庫連接前,讀取xml信息,用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();}}public static HashMap
<String, MapperData> map
= new HashMap<String, MapperData>();static {try { Class
<?> baseDaoClass
= Class
.forName("com.lovely.dao.BaseDao");URL url
= baseDaoClass
.getResource("/com/lovely/mapper");String path
= url
.getFile();File file
= new File(path
);File
[] files
= file
.listFiles();for (int i
= 0; i
< files
.length
; i
++) {SAXReader reader
= new SAXReader();Document doc
= reader
.read(files
[i
]);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")List
<Element> property
= root
.elements("property");LinkedHashMap
<String, String> lhm
= new LinkedHashMap<String, String>();for (Element field
: property
) {lhm
.put(field
.attributeValue("name"), field
.attributeValue("column"));}mapperData
.setProperties(lhm
);map
.put(root
.attributeValue("name"), mapperData
);}} catch (Exception e
) {e
.printStackTrace();}}static {try {Class
<?> c
= BaseDao
.class;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
);LinkedHashMap
<String, String> properties
= new LinkedHashMap<String, 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語句,拿到屬性值
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
;
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 (");sql
.append(mapperData
.getMapperId().getSeqName() + ".nextval");LinkedHashMap
<String,String> properties
= mapperData
.getProperties();Set
<String> 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 List
<Object> queryAll(Class
<?> c
) {List
<Object> list
= new ArrayList<Object>();MapperData mapperData
= BaseDao
.map
.get(c
.getName());String sql
= "select * from " + mapperData
.getTableName();Connection conn
= BaseDao
.getConn();PreparedStatement ps
= null
;ResultSet rs
= null
;LinkedHashMap
<String, 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
);Set
<Entry
<String,String>> entrySet
= properties
.entrySet();for (Entry
<String, String> entry
: entrySet
) {String filedName
= entry
.getKey();String columnName
= entry
.getValue();Object attributValue
= rs
.getObject(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(); LinkedHashMap
<String,String> properties
= mapperData
.getProperties();Set
<Entry
<String, 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 (Entry
<String, 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();MapperData mapperData
= BaseDao
.map
.get(c
.getName());sql
.append("update " + mapperData
.getTableName() + " set ");LinkedHashMap
<String,String> properties
= mapperData
.getProperties();Set
<String> keySet
= properties
.keySet();Collection
<String> 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()));System
.out
.println(dao
.queryAll(Ticket
.class));}}
[Student
[sid
=46, sname
=jack
, sgender
=male
, sbirth
=2020-07-02 20:24:01.0, saddress
=null
, sinfo
=null
]
]
[Ticket
[tid
=2, tname
=花木蘭
, tprice
=33.2]
, Ticket
[tid
=3, tname
=阿凡達
2, tprice
=50.5]
]
總結
以上是生活随笔為你收集整理的利用反射和xml配置文件手写一个小型的框架的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。