Java 5에서 String Concatenation과 StringBuffer의 속도 비교
JDK 1.4에서와 JDK 1.5에서 문자열을 결합할 경우 똑같은 상황이 올까요? ^^
1. 예제 소스
package client;
public class StringTest
{
public interface Repeatable {
void iteration(long loopId);
}
public static long repeat(int times, Repeatable repeatable) {
long initial = System.currentTimeMillis();
for (long c = 1; c <= times; c++)
repeatable.iteration(c);
long elapsed = System.currentTimeMillis() - initial;
return elapsed;
}
private static Repeatable stringBufferTest = new Repeatable()
{
public void iteration(long loopId) {
String alias = "a";
StringBuffer query = new StringBuffer(300);
query.append("SELECT ");
query.append(alias).append(".userName, ");
query.append(alias).append(".registerDate, ");
query.append("sum(").append(alias).append(".duration), ");
query.append(alias).append(".id FROM ");
query.append(StringTest.class.getName())
.append(" as ").append(alias);
query.append(" ORDER BY ")
.append(alias).append(".registerDate desc ");
String result = query.toString();
}
};
private static Repeatable stringConcatenationTest = new Repeatable()
{
public void iteration(long loopId) {
String query =
"SELECT " +
"a.userName, " +
"a.registerDate, " +
"sum(a.duration), " +
"a.id " +
"FROM " +
StringTest.class.getName() +
" as a " + "ORDER BY " +
"a.registerDate desc";
String result = query;
}
};
public static void main(String[] args) {
int times = 1000000;
long stringBuffElapsed, stringConcatElapsed;
for (int loopCount = 1; loopCount <= 5; loopCount++)
{
stringBuffElapsed = repeat(times, stringBufferTest);
stringConcatElapsed = repeat(times, stringConcatenationTest);
System.out.println("반복 횟수 " + loopCount);
System.out.println("StringBuffer 처리 시간 : " + stringBuffElapsed);
System.out.println("String Concatenation 처리 시간 : " +
stringConcatElapsed + "\n");
}
}
}
2. 예제 결과
3. 의견
- String객체는 immutable, StringBuffer는 mutable
- Stringr constant expression... 컴파일시에 결정되어, StringBuffer non-constant expression..런타임에 결정된다.
위의 String Concatenation이 StringBuffer보다 두배이상 빠르게 나오네요. 변수의 값이 런타임에 결정되는 것일 경우 StringBuffer, 아닐 경우는 String Concatenation을 사용하세요.
Top 125 Blogs for Development Managers
| Nr | Site / Author | PR | TA | AR | Hits | Cmts |
| 1 | Joel on Software Joel Spolsky | 7 | 2357 | 40364 | 6090 | |
| 2 | Coding Horror Jeff Atwood | 6 | 3472 | 54474 | 3870 | 1916 |
| 3 | Seth's Blog Seth Godin | 7 | 8757 | 93669 | 14600 | |
| 4 | Paul Graham: Essays Paul Graham | 6 | 2382 | 49839 | 2750 | |
| 5 | blog.pmarca.com Marc Andreesen | 7 | 1169 | 95439 | 3350 | |
| 6 | Rough Type Nicholas Carr | 7 | 1114 | 109196 | 4910 | 111 |
| 7 | Scott Hanselman's Computer Zen Scott Hanselman | 5 | 1284 | 51568 | 4040 | 155 |
| 8 | Martin Fowler's Bliki Martin Fowler | 6 | 376 | 79142 | 2240 | |
| 9 | Rands in Repose Michael Lopp | 6 | 565 | 199191 | 1610 | 401 |
| 10 | Stevey's Blog Rants Steve Yegge | 7 | 182 | 201319 | 1270 | 912 |
| 11 | Bokardo: Social Design Joshua Porter | 6 | 448 | 105072 | 1990 | 122 |
| 12 | Eric.Weblog() Eric Sink | 6 | 161 | 219875 | 1820 | 183 |
| 13 | Lambda the Ultimate (various) | 6 | 197 | 172624 | 2150 | 90 |
| 14 | Otaku, Cedric's Weblog Cedric | 7 | 107 | 209562 | 942 | 274 |
| 15 | PragDave Dave Thomas | 6 | 56 | 1700 | 158 | |
| 16 | High Scalability (various) | 6 | 611 | 67614 | 749 | 57 |
| 17 | The Berkun Blog Scott Berkun | 6 | 224 | 150787 | 1120 | 42 |
| 18 | UIE Brain Sparks Jared Spool | 6 | 128 | 73839 | 913 | 34 |
| 19 | Raganwald Reginald Braithwaite | 5 | 286 | 295168 | 591 | 120 |
| 20 | J.D. Meier's Blog J.D. Meier | 6 | 106 | 446 | 32 | |
| 21 | Stack Overflow Jeff Atwood | 6 | 234 | 99548 | 119 | 292 |
| 22 | Stevenf.com Steven Frank | 5 | 211 | 431730 | 711 | |
| 23 | secretGeek Leon Bambrick | 5 | 109 | 279144 | 382 | 78 |
| 24 | CodeBetter.Com (various) | 5 | 804 | 55474 | 140 | 53 |
| 25 | Interoperability Happens Ted Neward | 6 | 155 | 871230 | 570 | 42 |
| 26 | Gray's Matter Justice Gray | 5 | 89 | 302785 | 607 | 38 |
| 27 | Mike Cohn's Blog: Succeeding with Agile Mike Cohn | 5 | 401141 | 264 | 116 | |
| 28 | Object Mentor Blog (various) | 5 | 83 | 281113 | 248 | 84 |
| 29 | James Bach’s Blog James Bach | 5 | 45 | 657727 | 503 | 159 |
| 30 | Managing Product Development Johanna Rothman | 6 | 50 | 710781 | 1020 | 22 |
| 31 | Google Testing Blog (various) | 5 | 151 | 308629 | 216 | 45 |
| 32 | Alistair Cockburn Alistair Cockburn | 5 | 636969 | 426 | ||
| 33 | Tyner Blain Scott Sehlhorst | 5 | 63 | 873747 | 594 | 40 |
| 34 | Artima Weblogs (various) | 5 | 250 | 41092 | 97 | 21 |
| 35 | It's Just a Bunch of Stuff That Happens Eric Burke | 5 | 401 | 338795 | 109 | 51 |
| 36 | { |one, step, back| } Jim Weirich | 5 | 92 | 699777 | 315 | |
| 37 | Dr. Dobb's CodeTalk (various) | 6 | 249123 | 732 | 6 | |
| 38 | Petzold Book Blog Charles Petzold | 5 | 23 | 400444 | 362 | 67 |
| 39 | {Codesqueeze} Max Pool | 5 | 77 | 432030 | 172 | 56 |
| 40 | Signal vs. Noise (various) | 4 | 72462 | 211 | 220 | |
| 41 | Curious Cat John Hunter | 5 | 44 | 96174 | 1030 | 4 |
| 42 | Knowing.NET Larry O'Brien | 5 | 48 | 601544 | 482 | 12 |
| 43 | Agile Management Blog David Anderson | 5 | 26 | 655893 | 1200 | 15 |
| 44 | /\ndy Andy Hunt | 6 | 28 | 1717994 | 769 | 21 |
| 45 | James Shore: Successful Software James Shore | 5 | 71 | 1331837 | 221 | 28 |
| 46 | Object Technology Jeff Sutherland | 6 | 85 | 500221 | 186 | 6 |
| 47 | Better Projects Craig Brown | 5 | 38 | 1080915 | 251 | 21 |
| 48 | Evolving Web Jim Benson | 5 | 42 | 1681730 | 708 | 16 |
| 49 | Meme Agora Neal Ford | 5 | 63 | 2160111 | 247 | 28 |
| 50 | Agility@Scale Scott W. Ambler | 5 | 70 | 68 | ||
| 51 | David Chelimsky David Chelimsky | 5 | 838069 | 103 | 62 | |
| 52 | Pure Danger Tech Alex Miller | 5 | 70 | 596549 | 163 | 9 |
| 53 | Elegant Code (various) | 5 | 96 | 497139 | 72 | 18 |
| 54 | Exploring Solutions Spaces C. Keith Ray | 6 | 13 | 1392656 | 329 | |
| 55 | The Braidy Tester Micahel | 5 | 21 | 344 | 9 | |
| 56 | Destraynor Des Traynor | 5 | 16 | 966603 | 169 | 58 |
| 57 | Project Shrink Bas de Baar | 4 | 40 | 141635 | 237 | 18 |
| 58 | Stephans Blog Stephan Schmidt | 5 | 32 | 659770 | 56 | 87 |
| 59 | Agile Advice (various) | 5 | 64 | 899353 | 339 | 2 |
| 60 | LeadingAnswers Mike Griffiths | 4 | 38 | 1254375 | 456 | 30 |
| 61 | Wide Awake Developers Michael Nygard | 5 | 292 | 1072770 | 149 | 4 |
| 62 | Bit-Player Brian Hayes | 6 | 12 | 3504554 | 240 | 65 |
| 63 | Word Aligned Thomas Guest | 5 | 57 | 536114 | 43 | 21 |
| 64 | Testing Hotlist Update Bret Pettichord | 5 | 14 | 1409810 | 231 | 29 |
| 65 | NOOP.NL: Managing Software Development Jurgen Appelo | 4 | 73 | 692206 | 181 | 19 |
| 66 | Caffeinated Coder Russell Ball | 5 | 52 | 1558998 | 46 | 86 |
| 67 | GrokCode Jess | 4 | 109 | 524914 | 46 | 74 |
| 68 | Lean Software Engineering Corey Ladas | 4 | 42 | 1112902 | 322 | 19 |
| 69 | Exploration Through Example Brian Marick | 5 | 31 | 3491602 | 224 | 27 |
| 70 | Herding Cats Glen Alleman | 5 | 51 | 1434425 | 70 | 23 |
| 71 | Legends of the Sun Pig Martin Sutherland | 7 | 4 | 1453763 | 399 | 14 |
| 72 | Agile Developer Venkat's Blog Venkat Subramaniam | 5 | 34 | 1152021 | 187 | 9 |
| 73 | The Third Bit Esan | 5 | 44 | 1084414 | 321 | 1 |
| 74 | Implementing Scrum Mike Vizdos | 5 | 53 | 946336 | 206 | 3 |
| 75 | Collaborative Software Testing Jonathan Kohl | 5 | 26 | 3279595 | 296 | |
| 76 | Test Obsessed Elisabeth Hendrickson | 4 | 34 | 2117127 | 256 | 41 |
| 77 | 10x Software Development Steve McConnell | 4 | 0 | 533 | 108 | |
| 78 | Joel Pobar's Weblog Joel Pobar | 5 | 21 | 6854408 | 139 | 94 |
| 79 | Creative Chaos Matthew Heusser | 5 | 28 | 3038531 | 294 | 11 |
| 80 | Jcooney.NET Joseph Cooney | 5 | 33 | 2194958 | 161 | 15 |
| 81 | All About Agile Kelly Waters | 4 | 31 | 408534 | 223 | 10 |
| 82 | Project Management 2.0 Andrew Filev | 5 | 12 | 272 | 5 | |
| 83 | Agile Commons (various) | 5 | 686263 | 148 | 4 | |
| 84 | The Cutter Blog (various) | 5 | 6 | 778348 | 304 | 7 |
| 85 | Chris Spagnuolo's GeoScrum Chris Spagnuolo | 5 | 51 | 2259995 | 198 | 4 |
| 86 | Aligning Technology, Strategy, People & Projects Eric Brown | 4 | 44 | 1245105 | 206 | 12 |
| 87 | Agile Software Development (various) | 4 | 62 | 331003 | 100 | 7 |
| 88 | Clarke Ching - More Chilli Please Clarke Ching | 5 | 36 | 2456889 | 280 | 3 |
| 89 | Musings of a Software Development Manager Ed Gibbs | 4 | 11 | 1538525 | 252 | 29 |
| 90 | Notes from a Tool User Mark Levison | 4 | 23 | 1383460 | 134 | 24 |
| 91 | Silk and Spinach Kevin Rutherford | 5 | 9 | 1117088 | 121 | 14 |
| 92 | Focused Performance Frank Patrick | 4 | 7 | 729258 | 1140 | 6 |
| 93 | Hot Needle of Inquiry Ron Jeffries | 4 | 11 | 273831 | 694 | 0 |
| 94 | Mistaeks I Hav Made Nat Pryce | 5 | 18 | 187328 | 94 | 0 |
| 95 | Agile Thoughts Tobias Mayer | 4 | 21 | 1782189 | 80 | 101 |
| 96 | Agile Chronicles (various) | 5 | 2680922 | 131 | 9 | |
| 97 | Steve Rowe's Blog Steve Rowe | 4 | 20 | 119 | 20 | |
| 98 | Kevin Dente's Blog Kevin Dente | 4 | 22 | 40 | 92 | |
| 99 | Agile CMMI Blog Hillel Glazer | 5 | 8 | 3340384 | 164 | 12 |
| 100 | Andrew Tokeley Andrew Tokeley | 4 | 28 | 1348226 | 64 | 20 |
| 101 | Information Technology Dark Side David Christiansen | 4 | 41 | 1838236 | 93 | 16 |
| 102 | Jonathan Babcock Jonathan Babcock | 4 | 12 | 356837 | 59 | 14 |
| 103 | Wayne Allen's Weblog Wayne Allen | 4 | 32 | 82 | 12 | |
| 104 | Brad Appleton's ACME Blog Brad Appleton | 4 | 19 | 2819226 | 505 | 5 |
| 105 | Agile in Action Simon Baker | 4 | 32 | 1866089 | 116 | 10 |
| 106 | Red Squirrel Reflections Dave Hoover | 5 | 8 | 2332736 | 106 | |
| 107 | You'd think with all my video game experience... Jason Yip | 5 | 21 | 5287734 | 195 | 2 |
| 108 | PierG Piergiorgio Grossi | 5 | 8 | 3549551 | 113 | 9 |
| 109 | Raven's Brain Raven Young | 4 | 44 | 5041095 | 342 | 0 |
| 110 | Software Project Management Pawel Brodzinski | 4 | 23 | 1694265 | 95 | 8 |
| 111 | HTMList.com (various) | 3 | 18 | 395560 | 53 | 19 |
| 112 | Effective Software Development Dave Nicolette | 4 | 18 | 184 | 1 | |
| 113 | Jeff Patton's Holistic Product Design & Development Jeff Patton | 4 | 1391393 | 92 | ||
| 114 | I.M. Wright’s “Hard Code” Eric Brechner | 4 | 0 | 66 | 51 | |
| 115 | /var/log/mind Dhananjay Nene | 2 | 13 | 676449 | 6 | 94 |
| 116 | George Dinwiddie's Blog George Dinwiddie | 4 | 11 | 6163238 | 123 | 16 |
| 117 | Agile Software Process Improvement Jason Gorman | 4 | 20 | 865398 | 75 | 0 |
| 118 | Thoughts On... William Caputo | 4 | 13 | 4397849 | 113 | 5 |
| 119 | Cauvin Roger L. Cauvin | 4 | 7 | 2583163 | 98 | 8 |
| 120 | You Want IT When? Bill Miller | 4 | 2039808 | 57 | 7 | |
| 121 | Steve Freeman Steve Freeman | 4 | 12 | 5584864 | 45 | 19 |
| 122 | Jbrains.ca J.B. Rainsberger | 5 | 0 | 15073372 | 117 | |
| 123 | Leading Agile Mike Cottmeyer | 3 | 10 | 4452233 | 125 | 6 |
| 124 | Corporate Coder Eric Landes | 4 | 2 | 60 | 2 | |
| 125 | Ivar Jacobson's Blog Ivar Jacobson | 3 | 3 | 16938712 | 42 | 17 |
OPML을 다운 받으실려면 여기를 클릭하세요.
jfreechart로 차트 기능 구현
1. jfreechart 다운 로드
- http://www.jfree.org/jfreechart/
- jfreechart-X.X.X.jar, jcommon-X.X.X.jar를 어플리케이션 밑의 /WEB-INF/lib 폴더에 복사해 줌.
2. 환경 설정
<servlet>
<servlet-name>DisplayChart</servlet-name>
<servlet-class>org.jfree.chart.servlet.DisplayChart</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DisplayChart</servlet-name>
<url-pattern>/DisplayChart</url-pattern>
</servlet-mapping>
3. 구현 코드
- Chart.java
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.OutputStream;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.entity.StandardEntityCollection;
import org.jfree.chart.servlet.ServletUtilities;
public class Chart
{
protected String type;
protected String title;
protected String yaxis;
protected String varId;
protected int id = -1;
protected boolean displayChart;
protected boolean savetofile;
protected JFreeChart _chart;
protected Log log = LogFactory.getLog(this.getClass());
public Chart(String type, String title, String yaxis, String varId,
boolean displayChart, boolean savetofile) {
this.type = type; //차트 종류
this.title = title; // 차트 제목
this.yaxis = yaxis; //y범례title
this.varId = varId; //x범례title
this.displayChart = displayChart;
this.savetofile = savetofile;
}
public String getType() {
return type;
}
public JFreeChart getChart () {
return _chart;
}
public void initXYSeries (String variableid, int variableindex, int flag) {
// The XY charts need to implement this
}
public void addValue (double tpsd, String variableid,
String variableindex, int flag) {
// All charts need to implement this
}
public void addSeries(int flag) {
// The XY charts need to implement this
}
public void createChart() {
// All charts need to implement this
}
// 파일로 저장한 차트
public String saveChart(String outfileprefix, int width, int height)
{
String filename = null;
String fullpath = "/www/test";
try {
if (_chart == null) {
log.info("Chart.saveChart: Chart has not been created");
filename = "public_error_700x300.png";
return filename;
}
if (savetofile && outfileprefix != null) {
filename = fullpath + File.separator + outfileprefix + "." + type + ".jpg";
File imgfile = new File (filename);
ChartUtilities.saveChartAsJPEG(imgfile,
_chart, width, height);
}
} catch (Exception e) {
e.printStackTrace();
log.error(e);
}
return filename;
}
//response chart 결과 출력
public void displayChart(HttpServletResponse response, int width, int height)
{
BufferedImage image = null;
ByteArrayOutputStream stream = null;
OutputStream os = null;
try {
if (displayChart && _chart != null) {
image = _chart.createBufferedImage(width, height);
stream = new ByteArrayOutputStream();
ChartUtilities.writeBufferedImageAsJPEG(stream, image);
response.setDateHeader("Expires", 1);
byte[] data = stream.toByteArray();
response.setContentLength(data.length);
response.setContentType("image/jpeg");
os = response.getOutputStream();
os.write(data);
}
} catch (Exception e) {
e.printStackTrace();
log.error(e);
} finally {
try {
if (os != null) {
os.flush();
os.close();
}
} catch (Throwable t) {
// ignore
}
}
}
// session에 결과 출력
public String displayChart(HttpSession session, PrintWriter pw,
int width, int height)
{
ChartRenderingInfo info = null;
String filename = null;
try {
if (displayChart && _chart != null) {
info = new ChartRenderingInfo(new StandardEntityCollection());
filename = ServletUtilities.saveChartAsJPEG(_chart, width, height,
info, session);
}
} catch (Exception e) {
e.printStackTrace();
log.error(e);
filename = "public_error_700x300.png";
} finally {
info = null;
}
return filename;
}
}
- ChartFactory.java
public class ChartFactory
{
public static String[] SUPPORTED_CHARTS = {"BarChart3D", "XYLine", "XYScatter",
"RatioBarChart3D", "RatioXYLine", "RatioXYScatter", "Line"};
private static final int BARCHART3D = 0;
private static final int XYLINE = 1;
private static final int XYSCATTER = 2;
private static final int RATIOBARCHART3D = 3;
private static final int RATIOXYLINE = 4;
private static final int RATIOXYSCATTER = 5;
private static final int LINECHART = 6;
public static Chart createChart (String type,
String title, String yaxis, String varId,
boolean displayChart, boolean savetofile) {
int id = 0;
for (int i=0; i<SUPPORTED_CHARTS.length; i++) {
if (type.equalsIgnoreCase (SUPPORTED_CHARTS[i])) {
id = i;
break;
}
}
switch (id) {
case BARCHART3D:
return new BarChart3D (type, title, yaxis, varId, displayChart,
savetofile);
case RATIOBARCHART3D:
return new RatioBarChart3D (type, title, yaxis, varId,
displayChart, savetofile);
case XYLINE:
return new XYLineChart (type, title, yaxis, varId,
displayChart, savetofile);
case XYSCATTER:
return new XYScatterChart (type, title, yaxis, varId,
displayChart, savetofile);
case RATIOXYLINE:
return new RatioXYLineChart (type, title, yaxis, varId,
displayChart, savetofile);
case RATIOXYSCATTER:
return new RatioXYScatterChart (type, title, yaxis, varId,
displayChart, savetofile);
case LINECHART:
return new LineChart(type, title, yaxis, varId,
displayChart, savetofile);
}
return null;
}
}
- LineChart.java
import java.awt.Color;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
public class LineChart extends Chart
{
protected DefaultCategoryDataset dataset;
public LineChart(String type, String title, String yaxis/*y범례title*/,
String varId/*x범례title*/, boolean displayChart, boolean savetofile) {
super (type, title, yaxis, varId, displayChart, savetofile);
dataset = new DefaultCategoryDataset();
}
public void addValue (double tpsd, String variableid, String variableindex,
int flag) {
dataset.addValue(tpsd/* y */, variableid, variableindex/* x */);
}
public void createChart()
{
CategoryPlot categoryplot = null;
NumberAxis numberaxis = null;
LineAndShapeRenderer lineandshaperenderer = null;
try {
_chart = org.jfree.chart.ChartFactory.createLineChart(title, varId, yaxis,
(CategoryDataset)dataset, PlotOrientation.VERTICAL/*라인orientation*/,
true/*범례설정여부*/, true/*도움말설정여부*/, false/*urls설정여부*/);
_chart.setBackgroundPaint(Color.white);
_chart.setAntiAlias(true);
categoryplot = (CategoryPlot) _chart.getPlot();
categoryplot.setRangeGridlinePaint(Color.lightGray);
numberaxis = (NumberAxis) categoryplot.getRangeAxis();
numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
numberaxis.setAutoRangeIncludesZero(false);
numberaxis.setUpperMargin(0.12D);
lineandshaperenderer = (LineAndShapeRenderer) categoryplot.getRenderer();
lineandshaperenderer.setBaseShapesVisible(true);
lineandshaperenderer.setDrawOutlines(true);
lineandshaperenderer.setUseFillPaint(true);
lineandshaperenderer.setBaseFillPaint(Color.white);
lineandshaperenderer.setBaseItemLabelsVisible(true);
lineandshaperenderer.setBaseItemLabelGenerator(
new StandardCategoryItemLabelGenerator());//속도 안나옴
} catch (Exception e) {
log.error(e);
}
}
}
- Controller에 위 클래스 사용 예
public ModelAndView handleRequest(HttpServletRequest req,
HttpServletResponse resp) throws Exception
{
ModelAndView mv = null;
String fromdate = null;
String todate = null;
DateUtil du = null;
Chart charts = null;
PrintWriter pw = null;
String filename = null;
String graphURL = null;
try {
fromdate = StringUtils.defaultIfEmpty(
req.getParameter("fromdate"), StringUtils.EMPTY);
todate = StringUtils.defaultIfEmpty(req.getParameter("todate"),
StringUtils.EMPTY);
if (StringUtils.isEmpty(fromdate) || StringUtils.isEmpty(todate)) {
du = new DateUtil();
fromdate = du.addDays(du.getShortDateString(), -8, "yyyyMMdd");
todate = du.addDays(du.getShortDateString(), -1, "yyyyMMdd");
}
charts = ChartFactory.createChart("Line", "일별 가입자 수 통계", "가입자 수",
"가입 일자", false, true);
charts.addValue(5, "성년 가입자수", "2008.09.09", 1);
charts.addValue(2, "미성년 가입자수", "2008.09.09", 1);
charts.addValue(9, "성년 가입자수", "2008.09.10", 1);
charts.addValue(1, "미성년 가입자수", "2008.09.10", 1);
charts.addValue(4, "성년 가입자수", "2008.09.11", 1);
charts.addValue(3, "미성년 가입자수", "2008.09.11", 1);
charts.addValue(7, "성년 가입자수", "2008.09.12", 1);
charts.addValue(3, "미성년 가입자수", "2008.09.12", 1);
charts.addValue(7, "성년 가입자수", "2008.09.13", 1);
charts.addValue(4, "미성년 가입자수", "2008.09.13", 1);
charts.addValue(2, "성년 가입자수", "2008.09.14", 1);
charts.addValue(5, "미성년 가입자수", "2008.09.14", 1);
charts.addValue(10, "성년 가입자수", "2008.09.15", 1);
charts.addValue(1, "미성년 가입자수", "2008.09.15", 1);
charts.addValue(18, "성년 가입자수", "2008.09.16", 1);
charts.addValue(1, "미성년 가입자수", "2008.09.16", 1);
charts.createChart();
filename = charts.saveChart("Signup", 700, 300);
graphURL = "/upload_img/" + filename;
log.info(graphURL);
mv = new ModelAndView();
mv.addObject("graphurl", graphURL);
mv.addObject("filename", "#" + filename);
mv.setViewName("register-statistics");
} catch (Exception e) {
e.printStackTrace();
log.error(e);
} finally {
}
return mv;
}
- vm(Velocity)파일에서 사용 예
<div id="bodyWrapper">
<p class="more"><img src="$!{graphurl}"
width=700 height=300 border=0 usemap="$!{filename}"></p>
</div>
4. 구현 결과 화면

5. 팁
- http://mimul.com/examples/jfree/jfreechart-1.0.10-demo.jnlp을 다운 받아서 실행하면 샘플 예제들과 소스를 확인 할 수 있어 개발하는 데 많은 도움을 받을 수 있습니다.
- DisplayChart를 활용해서 이미지를 렌더링 할 경우 차트의 속성을 자세하게 설정하고 데이터를 차트에 할당 할 경우 이미지 로딩 속도가 현저하게 떨어지는 경우가 있습니다. 이럴 경우는 차트이미지를 파일로 만들어서 로딩하면 됩니다. 아직 성능 이슈가 좀 있긴 하네요.
[안내] Sun Tech Day 2008
2008년 9월 24일 메일을 통해 Sun Tech Day 2008 행사를 한다고 합니다. 다행히 초청장을 보내주셔서 유료 세미나인데도 무료로 참석할 수 있는 기회를 주셔서 감사하게 생각합니다.
여러분도 시간이 허락하시면 관심이 있는 세션을 들어보심이 어떨까요?
자세한 건 여기 사이트에 가시면 주요 세션 정보를 보실 수 있습니다.
hibernate.dialect
- DB2 : org.hibernate.dialect.DB2Dialect
- DB2 AS/400 : org.hibernate.dialect.DB2400Dialect
- DB2 OS390 : org.hibernate.dialect.DB2390Dialect
- PostgreSQL : org.hibernate.dialect.PostgreSQLDialect
- MySQL : org.hibernate.dialect.MySQLDialect
- MySQL with InnoDB : org.hibernate.dialect.MySQLInnoDBDialect
- MySQL with MyISAM : org.hibernate.dialect.MySQLMyISAMDialect
- Oracle (any version) : org.hibernate.dialect.OracleDialect
- Oracle 9i/10g : org.hibernate.dialect.Oracle9Dialect
- Sybase : org.hibernate.dialect.SybaseDialect
- Sybase Anywhere : org.hibernate.dialect.SybaseAnywhereDialect
- Microsoft SQL Server : org.hibernate.dialect.SQLServerDialect
- SAP DB : org.hibernate.dialect.SAPDBDialect
- Informix : org.hibernate.dialect.InformixDialect
- HypersonicSQL : org.hibernate.dialect.HSQLDialect
- Ingres : org.hibernate.dialect.IngresDialect
- Progress : org.hibernate.dialect.ProgressDialect
- Mckoi SQL : org.hibernate.dialect.MckoiDialect
- Interbase : org.hibernate.dialect.InterbaseDialect
- Pointbase : org.hibernate.dialect.PointbaseDialect
- FrontBase : org.hibernate.dialect.FrontbaseDialect
- Firebird : org.hibernate.dialect.FirebirdDialect
MySQL Error Codes
| 1000 | SQLSTATE: HY000 (ER_HASHCHK) hashchk |
| 1001 | SQLSTATE: HY000 (ER_NISAMCHK) isamchk |
| 1002 | SQLSTATE: HY000 (ER_NO) NO |
| 1003 | SQLSTATE: HY000 (ER_YES) YES |
| 1004 | SQLSTATE: HY000 (ER_CANT_CREATE_FILE) Can't create file '%s' (errno: %d) |
| 1005 | SQLSTATE: HY000 (ER_CANT_CREATE_TABLE) Can't create table '%s' (errno: %d) |
| 1006 | SQLSTATE: HY000 (ER_CANT_CREATE_DB) Can't create database '%s' (errno: %d) |
| 1007 | SQLSTATE: HY000 (ER_DB_CREATE_EXISTS) Can't create database '%s'; database exists |
| 1008 | SQLSTATE: HY000 (ER_DB_DROP_EXISTS) Can't drop database '%s'; database doesn't exist |
| 1009 | SQLSTATE: HY000 (ER_DB_DROP_DELETE) Error dropping database (can't delete '%s', errno: %d) |
| 1010 | SQLSTATE: HY000 (ER_DB_DROP_RMDIR) Error dropping database (can't rmdir '%s', errno: %d) |
| 1011 | SQLSTATE: HY000 (ER_CANT_DELETE_FILE) Error on delete of '%s' (errno: %d) |
| 1012 | SQLSTATE: HY000 (ER_CANT_FIND_SYSTEM_REC) Can't read record in system table |
| 1013 | SQLSTATE: HY000 (ER_CANT_GET_STAT) Can't get status of '%s' (errno: %d) |
| 1014 | SQLSTATE: HY000 (ER_CANT_GET_WD) Can't get working directory (errno: %d) |
| 1015 | SQLSTATE: HY000 (ER_CANT_LOCK) Can't lock file (errno: %d) |
| 1016 | SQLSTATE: HY000 (ER_CANT_OPEN_FILE) Can't open file: '%s' (errno: %d) |
| 1017 | SQLSTATE: HY000 (ER_FILE_NOT_FOUND) Can't find file: '%s' (errno: %d) |
| 1018 | SQLSTATE: HY000 (ER_CANT_READ_DIR) Can't read dir of '%s' (errno: %d) |
| 1019 | SQLSTATE: HY000 (ER_CANT_SET_WD) Can't change dir to '%s' (errno: %d) |
| 1020 | SQLSTATE: HY000 (ER_CHECKREAD) Record has changed since last read in table '%s' |
| 1021 | SQLSTATE: HY000 (ER_DISK_FULL) Disk full (%s); waiting for someone to free some space... |
| 1022 | SQLSTATE: 23000 (ER_DUP_KEY) Can't write; duplicate key in table '%s' |
| 1023 | SQLSTATE: HY000 (ER_ERROR_ON_CLOSE) Error on close of '%s' (errno: %d) |
| 1024 | SQLSTATE: HY000 (ER_ERROR_ON_READ) Error reading file '%s' (errno: %d) |
| 1025 | SQLSTATE: HY000 (ER_ERROR_ON_RENAME) Error on rename of '%s' to '%s' (errno: %d) |
| 1026 | SQLSTATE: HY000 (ER_ERROR_ON_WRITE) Error writing file '%s' (errno: %d) |
| 1027 | SQLSTATE: HY000 (ER_FILE_USED) '%s' is locked against change |
| 1028 | SQLSTATE: HY000 (ER_FILSORT_ABORT) Sort aborted |








