java 反射 数据库_数据库访问(Java 反射) + Json(数据对象)

一、Java 反射机制

二、利用反射实现数据库操作

三、数据对象与json的转换

一、Java 反射机制

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。

二、利用反射实现数据库操作

数据库操作,反射的好处:

(1) dao 层只需要编写一次基础数据库类操作代码(比如,增删改查等等),就可以充分利用继承关系实现不同模型的数据库操作。

(2) 修改数据库的表字段基本上不用大的修改 dao 层的代码(比如 sql 语句等等)

本例工程的目录组织结构大致如下:

89e2edd4e33b5c886924e96807e5877a.png

也可以将 LTBeanMapConverter.java 放到 dao.common 包中。

1、本实例使用 mysql 数据库。基础配置文件,请参考上一篇文章《MySQL + Tomcat 工程》 http://www.cnblogs.com/matchboxy/articles/4113834.html

2、编写 model 类,本例中为 LTNews.java 类。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecom.matchbox.model.news;2

3 importjava.io.Serializable;4

5 importjavax.persistence.Column;6 importjavax.persistence.GeneratedValue;7 importjavax.persistence.GenerationType;8 importjavax.persistence.Id;9 importjavax.persistence.Table;10

11

12 /**

13 *@authorMATCH14 * @date 14-12-2915 */

16

17

18 @Table(name="news")19 public class LTNews implementsSerializable20 {21 private longid;22 private longtime;23 privateString url;24 privateString imgUrl;25 privateString type;26 privateString title;27 privateString author;28 privateString source;29 privateString outline;30 private intlanguage;31 private intfavourite;32 private intcomment;33 private intclick;34

35 @Column(name="id")36 @Id37 @GeneratedValue(strategy =GenerationType.IDENTITY)38 public longgetId() {39 returnid;40 }41

42 public void setId(longid) {43 this.id =id;44 }45

46 @Column(name="time")47 public longgetTime() {48 returntime;49 }50

51 public void setTime(longtime) {52 this.time =time;53 }54

55 @Column(name="url")56 publicString getUrl() {57 returnurl;58 }59

60 public voidsetUrl(String url) {61 this.url =url;62 }63

64 @Column(name="imgUrl")65 publicString getImgUrl() {66 returnimgUrl;67 }68

69 public voidsetImgUrl(String imgUrl) {70 this.imgUrl =imgUrl;71 }72

73 @Column(name="type")74 publicString getType() {75 returntype;76 }77

78 public voidsetType(String type) {79 this.type =type;80 }81

82 @Column(name="title")83 publicString getTitle() {84 returntitle;85 }86

87 public voidsetTitle(String title) {88 this.title =title;89 }90

91 @Column(name="author")92 publicString getAuthor() {93 returnauthor;94 }95

96 public voidsetAuthor(String author) {97 this.author =author;98 }99

100 @Column(name="source")101 publicString getSource() {102 returnsource;103 }104

105 public voidsetSource(String source) {106 this.source =source;107 }108

109 @Column(name="outline")110 publicString getOutline() {111 returnoutline;112 }113

114 public voidsetOutline(String outline) {115 this.outline =outline;116 }117

118 @Column(name="language")119 public intgetLanguage() {120 returnlanguage;121 }122

123 public void setLanguage(intlanguage) {124 this.language =language;125 }126

127 @Column(name="favourite")128 public intgetFavourite() {129 returnfavourite;130 }131

132 public void setFavourite(intfavourite) {133 this.favourite =favourite;134 }135

136 @Column(name="comment")137 public intgetComment() {138 returncomment;139 }140

141 public void setComment(intcomment) {142 this.comment =comment;143 }144

145 @Column(name="click")146 public intgetClick() {147 returnclick;148 }149

150 public void setClick(intclick) {151 this.click =click;152 }153 }

LTNews.java

其中:@Table(name="news") 为 news 数据库表。

@Column(name="id")

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

为表中列名为 id 的列为主键,自增长类型。每一个 @Column(name="***") 写在 get 方法前面,对应数据表中的列名到相应的属性,一般来讲属性名最好与列名一致。

3、编写基础接口类 dao.common.LTGenericDao.java ,主要声明一些要实现的数据库操作。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecom.matchbox.dao.common;2

3 importjava.io.Serializable;4 importjava.util.List;5 importjava.util.Map;6

7

8 /**

9 *@authorMATCH10 * @date 14-12-3011 */

12

13

14 public interface LTGenericDao

15 {16 publicString getTableName();17 publicString getPk();18 public ListgetAll();19 public longgetCount();20

21 publicID insert(T object);22 public List insertBatch(ListlistObject);23

24 public intdelete(ID id);25 public int deleteBatch(ListlistIds);26

27 public intupdate(T object);28

29 publicT select(ID id);30 public List selectByIds(Listids);31 public List selectByMap(Mapmap);32 }

LTGenericDao.java

这里需要运用模板的知识,其中: T 为模型类的 class , ID 为模型类对应的表的主键类型。

4、编写基础实现类 dao.common.impl.LTGenericDaoImpl.java ,提供接口类的基础实现。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecom.matchbox.dao.common.impl;2

3 importjava.beans.BeanInfo;4 importjava.beans.IntrospectionException;5 importjava.beans.Introspector;6 importjava.beans.PropertyDescriptor;7 importjava.io.Serializable;8 importjava.sql.Connection;9 importjava.sql.PreparedStatement;10 importjava.sql.SQLException;11 importjava.sql.Statement;12 importjava.sql.Types;13 importjava.util.ArrayList;14 importjava.util.Arrays;15 importjava.util.Date;16 importjava.util.HashMap;17 importjava.util.List;18 importjava.util.Map;19

20 importjavax.persistence.Column;21 importjavax.persistence.GeneratedValue;22 importjavax.persistence.GenerationType;23 importjavax.persistence.Id;24 importjavax.persistence.Table;25 importjavax.persistence.Transient;26

27 importorg.apache.commons.beanutils.BeanUtils;28 importorg.apache.commons.lang.StringUtils;29 importorg.springframework.core.annotation.AnnotationUtils;30 importorg.springframework.jdbc.core.JdbcTemplate;31 importorg.springframework.jdbc.core.PreparedStatementCreator;32 importorg.springframework.jdbc.core.support.JdbcDaoSupport;33 importorg.springframework.jdbc.support.GeneratedKeyHolder;34 importorg.springframework.jdbc.support.KeyHolder;35

36 importcom.matchbox.dao.common.LTGenericDao;37 importcom.matchbox.dao.common.LTModelPropertyRowMapper;38 importcom.matchbox.utility.LTBeanMapConverter;39

40

41 /**

42 *@authorMATCH43 * @date 14-12-3044 */

45

46

47 public abstract class LTGenericDaoImpl

48 extends JdbcDaoSupport implements LTGenericDao

49 {50 private ClasspersistentClass;51 private String tableName = "";52 private String pk = "";53 privateGenerationType strategy;54 private Map property2ColumnMap = new HashMap();55 private Map column2PropertyMap = new HashMap();56 protected List transientPropertys = new ArrayList();57

58 protected LTGenericDaoImpl(ClasstClass)59 {60 this.persistentClass =tClass;61

62 Table table = AnnotationUtils.findAnnotation(tClass, Table.class);63 if(null ==table)64 {65 //throw new DaoException(persistentClass.getName() + "没有定义@table");

66 }67

68 this.tableName = (table==null) ?tClass.getName() : table.name();69

70 BeanInfo beanInfo = null;71 try

72 {73 beanInfo =Introspector.getBeanInfo(persistentClass);74 }75 catch(IntrospectionException e)76 {77 //throw new DaoException(e);

78 }79

80 PropertyDescriptor[] pds =beanInfo.getPropertyDescriptors();81 for(PropertyDescriptor pd : pds)82 {83 Id id = AnnotationUtils.findAnnotation(pd.getReadMethod(), Id.class);84 if(null !=id)85 {86 Column idColumn = AnnotationUtils.findAnnotation(pd.getReadMethod(), Column.class);87 this.pk = (idColumn == null) ?pd.getName() : idColumn.name();88

89 GeneratedValue gv = AnnotationUtils.findAnnotation(pd.getReadMethod(), GeneratedValue.class);90 this.strategy = (gv == null) ?GenerationType.IDENTITY : gv.strategy();91 }92

93 Column column = AnnotationUtils.findAnnotation(pd.getReadMethod(), Column.class);94 property2ColumnMap.put(pd.getName(), (column == null) ?pd.getName() : column.name());95 column2PropertyMap.put((column == null) ?pd.getName() : column.name(), pd.getName());96

97 Transient transient_ = AnnotationUtils.findAnnotation(pd.getReadMethod(), Transient.class);98 if (null !=transient_)99 {100 transientPropertys.add(pd.getName());101 }102 }103

104 if ("".equals(this.getPk()))105 {106 //throw new DaoException(persistentClass.getName() + "中没有在get方法上定义@Id");

107 }108 }109

110

111 @Override112 publicString getTableName()113 {114 return this.tableName;115 }116

117 @Override118 publicString getPk()119 {120 return this.pk;121 }122

123 @Override124 public ListgetAll()125 {126 return null;127 }128

129 @Override130 public longgetCount()131 {132 StringBuilder sb = new StringBuilder("select count(*) from ");133 sb.append(this.getTableName());134 return this.getJdbcTemplate().queryForObject(sb.toString(), Long.class);135 }136

137 /**

138 * 插入一条数据139 */

140 @Override141 publicID insert(T object)142 {143 if (null ==object)144 {145 //throw new DaoException("模型对象为空!保存失败");

146 }147

148 Map map =toModelMap(object);149 for(String proterty : transientPropertys)150 {151 map.remove(proterty);152 }153

154 ID id = this.insertReturnIdByMap(map);155 if(strategy.equals(GenerationType.IDENTITY))156 {157 try

158 {159 BeanUtils.setProperty(object, column2PropertyMap.get(pk), id);160 }161 catch(Exception e)162 {163 //log.error(persistentClass.getName() + "解析异常!", e);

164 }165 }166 returnid;167 }168

169 /**

170 * 根据列名与对应的属性值,添加一条记录。171 * 返回添加的主键id172 */

173 @SuppressWarnings("unchecked")174 protected ID insertReturnIdByMap(Mapmap)175 {176 if (map == null || map.size() == 0)177 return null;178

179 if (this.strategy.equals(GenerationType.IDENTITY))180 {181 map.remove(this.getPk());182 }183

184 StringBuilder sb = new StringBuilder("insert into ");185 sb.append(this.getTableName());186

187 List columns = new ArrayList();188 List values = new ArrayList();189

190 for (Map.Entrye : map.entrySet())191 {192 columns.add(e.getKey());193 values.add(e.getValue());194 }195

196 sb.append("(`");197 sb.append(StringUtils.join(columns, "`,`"));198 sb.append("`) values(");199 String[] paras = newString[values.size()];200 Arrays.fill(paras, "?");201 sb.append(StringUtils.join(paras, ','));202 sb.append(")");203

204 if(this.strategy.equals(GenerationType.IDENTITY)) //主键自增长

205 {206 ID id = this.insertBySqlValuesIdentity(sb.toString(), values);207 return(ID) id;208 }209 else if(this.strategy.equals(GenerationType.AUTO)) //主键由程序控制

210 {211 int count = this.insertBySqlValuesAuto(sb.toString(), values);212 if(count != 0)213 {214 return (ID) map.get(this.getPk());215 }216 else

217 {218 return null;219 }220 }221 return null;222 }223

224 /**

225 * 根据sql和相关列值,插入一条记录。226 * 主键自增长227 * 返回主键值228 */

229 @SuppressWarnings("unchecked")230 //@Override

231 public ID insertBySqlValuesIdentity(final String sql, final Listvalues)232 {233 JdbcTemplate template = this.getJdbcTemplate();234 KeyHolder keyHolder = newGeneratedKeyHolder();235

236 template.update(newPreparedStatementCreator()237 {238 public PreparedStatement createPreparedStatement(Connection con) throwsSQLException239 {240 int i = 0;241 PreparedStatement ps =con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);242 for (i = 0; i < values.size(); i++)243 {244 Object value =values.get(i);245 if (value != null)246 {247 if (value instanceofInteger) {248 ps.setInt(i + 1, (Integer) value);249 } else if (value instanceofLong) {250 ps.setLong(i + 1, (Long) value);251 } else if (value instanceofDate) {252 ps.setDate(i + 1, newjava.sql.Date(((Date) value).getTime()));253 ps.setTimestamp(i + 1, newjava.sql.Timestamp(((Date) value).getTime()));254 } else if (value instanceofString) {255 ps.setString(i + 1, value.toString());256 } else if (value instanceofDouble) {257 ps.setDouble(i + 1, (Double) value);258 } else if (value instanceofByte) {259 ps.setByte(i + 1, (Byte) value);260 } else if (value instanceofCharacter) {261 ps.setString(i + 1, value.toString());262 } else if (value instanceofFloat) {263 ps.setFloat(i + 1, (Float) value);264 } else if (value instanceofBoolean) {265 ps.setBoolean(i + 1, (Boolean) value);266 } else if (value instanceofShort) {267 ps.setShort(i + 1, (Short) value);268 } else{269 ps.setObject(i + 1, value);270 }271 }272 else

273 {274 ps.setNull(i + 1, Types.NULL);275 }276 }277 returnps;278 }279 }, keyHolder);280

281 return(ID) (Long) keyHolder.getKey().longValue();282 }283

284 /**

285 * 根据sql和相关列值,插入一条记录。286 * 主键值由程序设定287 * 返回受影响的行数288 */

289 protected int insertBySqlValuesAuto(final String sql, Listvalues)290 {291 if(StringUtils.isEmpty(sql))292 return 0;293

294 if (values == null)295 values = new ArrayList();296

297 return this.getJdbcTemplate().update(sql, values.toArray());298 }299

300 /**

301 * 插入一组数据302 */

303 @Override304 public List insertBatch(ListlistObject)305 {306 List listID = new ArrayList();307 ID id;308

309 if(null ==listObject)310 returnlistID;311

312 for(T object : listObject)313 {314 id = this.insert(object);315 if(null !=id)316 listID.add(id);317 }318

319 returnlistID;320 }321

322 /**

323 * 根据 id 删除一条数据324 */

325 @Override326 public intdelete(ID id)327 {328 if(null ==id)329 return 0;330

331 StringBuilder sb = new StringBuilder("delete from ");332 sb.append(this.getTableName());333 sb.append(" where ");334 sb.append(this.getPk());335 sb.append("=?");336

337 List values = new ArrayList();338 values.add(id);339

340 return this.deleteBySqlValues(sb.toString(), values);341 }342

343 /**

344 * 删除一组数据345 */

346 @Override347 public int deleteBatch(ListlistIds)348 {349 if((null == listIds) ||listIds.isEmpty())350 return 0;351

352 StringBuilder sb = new StringBuilder("delete from ");353 sb.append(this.getTableName());354 sb.append(" where ");355 sb.append(this.getPk());356 sb.append(" in (");357 Serializable[] ss = newSerializable[listIds.size()];358 Arrays.fill(ss, "?");359 sb.append(StringUtils.join(ss, ','));360 sb.append(")");361 List values = new ArrayList();362 values.addAll(listIds);363

364 return this.deleteBySqlValues(sb.toString(), values);365 }366

367 /**

368 * 根据sql和相关列值,删除一条记录。369 * 返回受影响的行数370 */

371 protected int deleteBySqlValues(final String sql, final Listvalues)372 {373 return this.getJdbcTemplate().update(sql, values.toArray());374 }375

376 /**

377 * 修改一条数据378 */

379 @Override380 public intupdate(T object)381 {382 if (null ==object)383 {384 //throw new DaoException("模型对象为空!");

385 }386

387 Map map = null;388 try

389 {390 map =toModelMap(object);391 for(String proterty : transientPropertys)392 {393 map.remove(proterty);394 }395 }396 catch(Exception e)397 {398 //throw new DaoException(persistentClass.getName() + "解析异常!", e);

399 }400

401 int count = this.updateReturnIdByMap(map);402 if(count == 0)403 {404 //throw new DaoException(persistentClass.getName() + "更新失败" + object);

405 }406 returncount;407 }408

409 /**

410 * 根据列名与对应的属性值,更新一条记录。411 * 返回更新的主键id412 */

413 protected int updateReturnIdByMap(Mapmap)414 {415 if((null == map) || (map.size() == 0))416 return 0;417

418 Serializable id = (Serializable) map.get(this.getPk());419 if ((null == id) || "".equals(id))420 return 0;421

422 List values = new ArrayList();423

424 StringBuilder sb = new StringBuilder("update ");425 sb.append(this.getTableName());426 sb.append(" set ");427

428 map.remove(this.getPk());429

430 for (Map.Entrye : map.entrySet())431 {432 sb.append('`').append(e.getKey()).append('`');433 sb.append("=?, ");434 values.add(e.getValue());435 }436 deleteLastStr(sb, ",");437 sb.append(" where ");438 sb.append(this.getPk());439 sb.append("=?");440 values.add(id);441 map.put(this.getPk(), id);442

443 return this.updateBySqlValues(sb.toString(), values);444 }445

446 /**

447 * 根据sql和相关列值,更新一条记录448 * 返回受影响的行数449 */

450 protected int updateBySqlValues(final String sql, Listvalues)451 {452 if(StringUtils.isEmpty(sql))453 return 0;454

455 if (null ==values)456 values = new ArrayList();457

458 return this.getJdbcTemplate().update(sql, values.toArray());459 }460

461 /**

462 * 根据id查找一条数据463 * 返回这条数据464 */

465 @Override466 publicT select(ID id)467 {468 if(null ==id)469 return null;470

471 StringBuilder sb = new StringBuilder("select * from ");472 sb.append(this.getTableName());473 sb.append(" where ");474 sb.append(this.getPk());475 sb.append("=?");476

477 List values = new ArrayList();478 values.add(id);479

480 List list = this.selectBySqlValues(sb.toString(), values);481 if (list == null || list.size() == 0)482 return null;483 else

484 return list.get(0);485 }486

487 /**

488 * 根据一组id,查找相应一组数据。489 * 返回找到的数据490 */

491 @Override492 public List selectByIds(Listids)493 {494 if((null == ids) ||ids.isEmpty())495 return (new ArrayList());496

497 StringBuilder sb = new StringBuilder("select * from ");498 sb.append(this.getTableName());499 sb.append(" where ");500 sb.append(this.getPk());501 sb.append(" in (");502

503 Serializable[] ss = newSerializable[ids.size()];504 Arrays.fill(ss, "?");505 sb.append(StringUtils.join(ss, ','));506 sb.append(")");507

508 List values = new ArrayList();509 values.addAll(ids);510

511 return this.selectBySqlValues(sb.toString(), values);512 }513

514 /**

515 * 根据给定的属性与属性值对查找记录516 * 返回找到的数据517 */

518 @Override519 public List selectByMap(Mapmap)520 {521 if (map == null ||map.isEmpty())522 return null;523

524 @SuppressWarnings("unchecked")525 ID id = (ID) map.get(this.getPk());526 if (id != null)527 {528 map.remove(id);529 }530

531 List removekeys = new ArrayList();532 for (Map.Entryentry : map.entrySet())533 {534 if (entry.getValue() == null)535 {536 removekeys.add(entry.getKey());537 }538 }539

540 for(String key : removekeys)541 {542 map.remove(key);543 }544

545 List values = new ArrayList();546 StringBuilder sb = new StringBuilder("select * from ");547 sb.append(this.getTableName());548 if (map.size() != 0)549 {550 sb.append(" where ");551 for (Map.Entryentry : map.entrySet())552 {553 sb.append('`').append(entry.getKey()).append('`');554 sb.append("=? ");555 values.add(entry.getValue());556 sb.append(" and ");557 }558 this.deleteLastStr(sb, "and");559 }560 return this.selectBySqlValues(sb.toString(), values);561 }562

563 /**

564 * 根据sql和相关列值,选择数据565 * 返回受影响的行数566 */

567 protected List selectBySqlValues(final String sql, Listvalues)568 {569 if(StringUtils.isEmpty(sql))570 return new ArrayList();571

572 if (values == null)573 values = new ArrayList();574

575 List list = this.getJdbcTemplate().query(sql, values.toArray(),576 new LTModelPropertyRowMapper(this.persistentClass, property2ColumnMap));577

578 return (list == null) ? new ArrayList() : list;579 }580

581

582 /**

583 * 删除给定字符之后的字符串584 *585 *@paramsb586 *@paramstr587 */

588 private voiddeleteLastStr(StringBuilder sb, String str)589 {590 int index =sb.lastIndexOf(str);591 if (index != -1)592 {593 sb.delete(index, index +str.length());594 }595 }596

597 /**

598 * 用于将Model转变成Map,key为属性对应的列名,value为属性对应的值。599 *600 *@paramobject601 *@return

602 */

603 private MaptoModelMap(T object) {604 Map modelMap = null;605 try

606 {607 Map map =LTBeanMapConverter.convertMapFromBean(object);608 modelMap = new HashMap();609 for (Map.Entrye : map.entrySet())610 {611 modelMap.put(property2ColumnMap.get(e.getKey()), e.getValue());612 }613 }614 catch(Exception e)615 {616 //throw new DaoException(persistentClass.getName() + "解析异常!", e);

617 }618 returnmodelMap;619 }620 }

LTGenericDaoImpl.java

public abstract class LTGenericDaoImpl

extends JdbcDaoSupport implements LTGenericDao

抽象类,继承 JdbcDaoSupport ,实现接口 LTGenericDao 。

这里只提供最基础的一些操作实现,其他复杂操作,可针对项目的需求,在接口里面添加方法,然后在这里实现。具体方法实现,可参考本类中其他方法。

5、步骤 4 中的实现类里面,需要有两个类的支持:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecom.matchbox.utility;2

3 importjava.beans.BeanInfo;4 importjava.beans.IntrospectionException;5 importjava.beans.Introspector;6 importjava.beans.PropertyDescriptor;7 importjava.lang.reflect.InvocationTargetException;8 importjava.lang.reflect.Method;9 importjava.util.HashMap;10 importjava.util.Map;11

12 public classLTBeanMapConverter13 {14 /**

15 * 静态方法,将 model bean 转化为 map16 */

17 public static MapconvertMapFromBean(Object bean)18 throwsIntrospectionException, IllegalAccessException,19 IllegalArgumentException, InvocationTargetException20 {21 if(null ==bean)22 {23 return (new HashMap());24 }25

26 BeanInfo info =Introspector.getBeanInfo(bean.getClass());27 PropertyDescriptor[] descriptors =info.getPropertyDescriptors();28

29 Map description = new HashMap();30 Object value;31

32 for (int i = 0; i < descriptors.length; i++)33 {34 String name =descriptors[i].getName();35 Method reader =descriptors[i].getReadMethod();36 if (reader != null)37 {38 //Object[] os = new Object[0];39 //value = reader.invoke(bean, os);

40

41 value =reader.invoke(bean);42 description.put(name, value);43 }44 }45 description.remove("class");46 returndescription;47 }48 }

LTBeanMapConverter.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecom.matchbox.dao.common;2

3 importjava.beans.PropertyDescriptor;4 importjava.sql.ResultSet;5 importjava.sql.ResultSetMetaData;6 importjava.sql.SQLException;7 importjava.util.HashMap;8 importjava.util.HashSet;9 importjava.util.Map;10 importjava.util.Set;11

12 importorg.springframework.beans.BeanUtils;13 importorg.springframework.beans.BeanWrapper;14 importorg.springframework.beans.NotWritablePropertyException;15 importorg.springframework.beans.PropertyAccessorFactory;16 importorg.springframework.beans.TypeMismatchException;17 importorg.springframework.jdbc.core.RowMapper;18 importorg.springframework.jdbc.support.JdbcUtils;19

20

21 /**

22 *@authorMATCH23 * @date 14-12-3124 */

25

26

27 public class LTModelPropertyRowMapper implements RowMapper

28 {29 private ClassmappedClass;30 private MapmappedFields;31 private SetmappedProperties;32

33 public LTModelPropertyRowMapper(Class mappedClass, Mapproperty2ColumnMap)34 {35 initialize(mappedClass, property2ColumnMap);36 }37

38 protected void initialize(Class mappedClass, Mapproperty2ColumnMap)39 {40 this.mappedClass =mappedClass;41 this.mappedFields = new HashMap();42 this.mappedProperties = new HashSet();43 PropertyDescriptor[] pds =BeanUtils.getPropertyDescriptors(mappedClass);44

45 for(PropertyDescriptor pd : pds)46 {47 if(pd.getWriteMethod() != null)48 {49 this.mappedFields.put(pd.getName().toLowerCase(), pd);50 String underscoredName =underscoreName(pd.getName());51 if(!pd.getName().toLowerCase().equals(underscoredName))52 {53 this.mappedFields.put(underscoredName, pd);54 }55 mappedFields.put(property2ColumnMap.get(pd.getName()), pd);56 this.mappedProperties.add(pd.getName());57 }58 }59 }60

61 /**

62 * 将实例的属性,转变为带有下标的形式。63 *@paramname64 *@return

65 */

66 privateString underscoreName(String name)67 {68 StringBuilder result = newStringBuilder();69 if ((null != name) && (name.length() > 0))70 {71 result.append(name.substring(0, 1).toLowerCase());72 for (int i=1; i

81 {82 result.append(s);83 }84 }85 }86 returnresult.toString();87 }88

89 /**

90 * 必须要重写的方法,指定查找的某行数据91 */

92 public T mapRow(ResultSet rs, int rowNumber) throwsSQLException93 {94 T mappedObject = BeanUtils.instantiate(this.mappedClass);95 BeanWrapper bw =PropertyAccessorFactory.forBeanPropertyAccess(mappedObject);96

97 ResultSetMetaData rsmd =rs.getMetaData();98 int columnCount =rsmd.getColumnCount();99

100 for (int index = 1; index <= columnCount; index++) {101 String column =JdbcUtils.lookupColumnName(rsmd, index);102 PropertyDescriptor pd = this.mappedFields.get(column.replaceAll(" ", "").toLowerCase());103 if(pd != null)104 {105 try

106 {107 Object value =getColumnValue(rs, index, pd);108 if(value == null)109 {110 continue;111 }112 try

113 {114 bw.setPropertyValue(pd.getName(), value);115 }116 catch(TypeMismatchException e)117 {118 //throw new DaoException("模型类"+this.mappedClass.getName()+"的属性匹配异常", e);

119 }120 }121 catch(NotWritablePropertyException ex)122 {123 //throw new DaoException("模型类"+this.mappedClass.getName()+"中没有定义"+pd.getName()+"的set方法", ex);

124 }125 }126 }127 returnmappedObject;128 }129

130 protected Object getColumnValue(ResultSet rs, intindex, PropertyDescriptor pd)131 throwsSQLException132 {133 returnJdbcUtils.getResultSetValue(rs, index, pd.getPropertyType());134 }135 }

LTModelPropertyRowMapper.java

其中: LTBeanMapConverter 类是 model bean 和 map 的转换。 LTModelPropertyRowMapper 类是 select 方法需要的,将一行数据转化为 model 。

6、编写 news 数据处理接口类 dao.news.LTNewsDao.java ,向外部提供操作 news 数据模型类的接口。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecom.matchbox.dao.news;2

3 importjava.util.List;4

5 importcom.matchbox.model.news.LTNews;6

7

8 /**

9 *@authorMATCH10 * @date 14-12-3011 */

12

13

14 public interfaceLTNewsDao15 {16 public longinsertNews(LTNews news);17 public List insertNewsBatch(ListlistNews);18

19 public int deleteNews(longid);20 public int deleteNewsBatch(ListlistIds);21

22 public intupdateNews(LTNews news);23

24 public LTNews selectNews(longid);25 public List selectNewsBatch(ListlistIds);26 }

LTNewsDao.java

7、编写 news 数据处理实现类 dao.news.impl.LTNewsDaoImpl.java ,提供 news 模型类操作的实现。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecom.matchbox.dao.news.impl;2

3 importjava.util.List;4

5 importcom.matchbox.dao.common.impl.LTGenericDaoImpl;6 importcom.matchbox.dao.news.LTNewsDao;7 importcom.matchbox.model.news.LTNews;8

9

10 /**

11 *@authorMATCH12 * @date 14-12-3013 */

14

15

16 public class LTNewsDaoImpl extends LTGenericDaoImpl implementsLTNewsDao17 {18 protectedLTNewsDaoImpl()19 {20 super(LTNews.class);21 }22

23 @Override24 public longinsertNews(LTNews news)25 {26 return this.insert(news);27 }28

29 @Override30 public List insertNewsBatch(ListlistNews)31 {32 return this.insertBatch(listNews);33 }34

35 @Override36 public int deleteNews(longid)37 {38 return this.delete(id);39 }40

41 @Override42 public int deleteNewsBatch(ListlistIds)43 {44 return this.deleteBatch(listIds);45 }46

47 @Override48 public intupdateNews(LTNews news)49 {50 return this.update(news);51 }52

53 @Override54 public LTNews selectNews(longid)55 {56 return this.select(id);57 }58

59 @Override60 public List selectNewsBatch(ListlistIds)61 {62 return this.selectByIds(listIds);63 }64 }

LTNewsDaoImpl.java

其中: public class LTNewsDaoImpl extends LTGenericDaoImpl implements LTNewsDao { ... }

需要指定扩展类的模板 表示数据模型为 LTNews 类,主键为 Long 类型的。

8、编写 api 转发类 LTNewsController.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecom.matchbox.api;2

3 importjavax.servlet.http.HttpServletRequest;4 importjavax.servlet.http.HttpServletResponse;5

6 importorg.springframework.beans.factory.annotation.Autowired;7 importorg.springframework.stereotype.Controller;8 importorg.springframework.http.HttpStatus;9 importorg.springframework.web.bind.annotation.PathVariable;10 importorg.springframework.web.bind.annotation.RequestMapping;11 importorg.springframework.web.bind.annotation.RequestMethod;12 importorg.springframework.web.bind.annotation.ResponseBody;13 importorg.springframework.web.bind.annotation.ResponseStatus;14

15 importcom.matchbox.dao.news.LTNewsDao;16 importcom.matchbox.model.news.LTNews;17

18

19 //rootPath =http://127.0.0.1:8080/api

20 @Controller21 @RequestMapping("/news") //rootPath += "/news"

22 public classLTNewsController23 {24 @Autowired25 privateLTNewsDao newsDao;26

27 //rootPath += "/insert"

28 @RequestMapping(value="/insert", method=RequestMethod.GET)29 @ResponseStatus(HttpStatus.OK)30 @ResponseBody31 publicString insert()32 {33 //time, url, imgUrl, type, title, author, source, outline, language, favourite, comment, click

34

35 LTNews news = newLTNews();36 news.setTime(1419927688);37 news.setUrl("http://insertByNewsController/url_1");38 news.setImgUrl("");39 news.setType("1,2,3");40 news.setTitle("题目 insertByNewsController1");41 news.setAuthor("");42 news.setSource("来源");43 news.setOutline("

内容 insertByNewsController1");44 news.setLanguage(1);45 news.setFavourite(0);46 news.setComment(0);47 news.setClick(0);48

49 return "insert test id: " + this.newsDao.insertNews(news);50 }51

52 //rootPath += "/delete"

53 @RequestMapping(value="/delete/{newsId}", method=RequestMethod.GET)54 @ResponseStatus(HttpStatus.OK)55 @ResponseBody56 publicString deleteById(@PathVariable String newsId)57 {58 this.newsDao.deleteNews(Long.valueOf(newsId));59

60 return "delete id: " +newsId;61 }62

63 //rootPath += "/update"

64 @RequestMapping(value="/update", method=RequestMethod.GET)65 @ResponseStatus(HttpStatus.OK)66 @ResponseBody67 publicString update()68 {69 //time, url, imgUrl, type, title, author, source, outline, language, favourite, comment, click

70

71 long id = 5;72

73 LTNews news = newLTNews();74 news.setId(id);75 news.setTime(1419927688);76 news.setUrl("http://insertByNewsController/url_1修改");77 news.setImgUrl("修改");78 news.setType("1,2,3");79 news.setTitle("题目 修改222222");80 news.setAuthor("修改");81 news.setSource("来源修改");82 news.setOutline("

内容 insertByNewsController1");83 news.setLanguage(1);84 news.setFavourite(0);85 news.setComment(0);86 news.setClick(0);87

88 this.newsDao.updateNews(news);89

90 return "update by id: " +id;91 }92

93 //rootPath += "/select"

94 @RequestMapping(value="/select/{newsId}", method=RequestMethod.GET)95 @ResponseStatus(HttpStatus.OK)96 @ResponseBody97 publicLTNews select(@PathVariable String newsId)98 {99 LTNews news = this.newsDao.selectNews(Long.valueOf(newsId));100

101 returnnews;102 }103 }

LTNewsController.java

@Autowired

private LTNewsDao newsDao;

表示要自动装配 LTNewsDao bean 类,需要在配置文件中进行配置,如下。

9、修改配置文件 spring-api.xml 、 spring-dao.xml

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 <?xml version="1.0" encoding="UTF-8"?>

2

3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

4 xmlns:context="http://www.springframework.org/schema/context"

5 xmlns:mvc="http://www.springframework.org/schema/mvc"

6 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

7

8

9

10

11

12

13

14

15

16

17

18 text/plain;charset=UTF-8

19

20

21

22

23

24

25

26

27

28

29

spring-api.xml

表示在 com.match.api 这个包下面寻找 servlet 的入口 uri 。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 <?xml version="1.0" encoding="UTF-8"?>

2

3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

4 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

5

6

7

8

9

10

11

12

spring-dao.xml

要把 dao bean 类添加进去,这样才能正常运行。后面添加其他的 dao 类时,要同样添加进去。

10、修改数据库,建立 news 表

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 --database

2 CREATE DATABASE

3 IF NOT EXISTS bishe_db DEFAULT CHARACTER

4 SETutf8;5

6 USEbishe_db;7

8

9

10 --table news

11 DROP TABLE IF EXISTSnews;12

13 CREATE TABLE

14 IF NOT EXISTSnews (15 id BIGINT NOT NULL auto_increment PRIMARY KEY,16 time BIGINT,17 url VARCHAR (200),18 imgUrl VARCHAR (200),19 type VARCHAR (100),20 title TEXT,21 author VARCHAR (100),22 source VARCHAR (100),23 outline TEXT,24 language int,25 favourite int,26 comment int,27 click int

28 ) auto_increment = 1;

create table news

11、启动 mysql 服务器和 tomcat 服务器,可以通过浏览器访问 uri 来操作数据库 news 类。

三、数据对象与json的转换

其实 @ResponseBody 这项工作就已经自动将模型对象与 json 文本数据进行转化了,但是前提是需要添加一些配置, spring-api.xml 中已经添加过了,步骤二中的第九步,已经将 json 数据转化 xml 配置过了,同时还需要添加一些包的支持, maven 的 pom.xml 中也已经添加过 json 的支持包。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JSON 数据导入数据库的一般流程如下: 1. 读取 JSON 数据 2. 解析 JSON 数据Java 对象 3. 连接数据库 4. 将 Java 对象转换为数据库中的记录 5. 插入记录到数据库中 下面是一个示例代码,假设 JSON 数据格式如下: ```json [ { "id": 1, "name": "Alice", "age": 20 }, { "id": 2, "name": "Bob", "age": 25 } ] ``` Java 代码如下: ```java import java.io.FileReader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.util.List; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; public class Main { public static void main(String[] args) throws Exception { // 1. 读取 JSON 数据 FileReader reader = new FileReader("data.json"); // 2. 解析 JSON 数据Java 对象 Gson gson = new Gson(); List<Person> persons = gson.fromJson(reader, new TypeToken<List<Person>>() {}.getType()); // 3. 连接数据库 Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456"); // 4. 将 Java 对象转换为数据库中的记录 PreparedStatement stmt = conn.prepareStatement("INSERT INTO persons (id, name, age) VALUES (?, ?, ?)"); for (Person person : persons) { stmt.setInt(1, person.getId()); stmt.setString(2, person.getName()); stmt.setInt(3, person.getAge()); stmt.executeUpdate(); } // 5. 插入记录到数据库中 stmt.close(); conn.close(); } } class Person { private int id; private String name; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } ``` 这个示例代码使用了 Google Gson 库来解析 JSON 数据Java 对象,使用了 JDBC 来连接 MySQL 数据库。请根据自己的需求修改连接字符串、账号密码等参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值