某日, mySql(5.1.30-community)如此报错, 用phpMyAdmin强行插入, 亦是如此:
但如直接指定Auto-Increment的 Field, 就可顺利插入.
修改该自增Filed的属性, 先将其自增属性点掉:
保存后, 再点选其自增, 再保存, 问题暂时解决.
英文水平有限, 暂不深究….
首先将MySQL数据库导出, 可使用PhpMyAdmin等工具,
打开WorkBench, File > import > Reverse Enginner MySQL Create Script…
选择导出的mysql文件, 确定即可.
支持数据库:
SQL Server, MySQL, PostgreSQL, Oracle, DB2, ANSI SQL, ODBC
地址:http://www.petefreitag.com/tools/sql_reserved_words_checker/
演示:
1. Java – JDBC – MySql
1. 装好MySql, 启动服务.
2. 将mysql-connector-java-5.1.7-bin.jar 拖入WEB-INF/lib下.
搞定.
2. Java端BlazeDS配置
1. Java端:
将BlazeDS压缩包内的WEB-INF里面的东西拷贝工程内的WEB-INF下的相应位置中.[ Flex目录下有四个xml配置文件, lib下是需要使用的jar] 包括web.xm
2. 配置services-config.xml中channels标签中的内容:
false true 4
其中, http://localhost:8080/DepartmentManagement/ 是该Web工程的地址 [可在web-content下建立一空index.html, 运行后查看地址便可]
3. 编写Java类, 并配置remoting-config.xml文件的<service>标签下, 增加服务, 如下:
com.insprise.guoliang.DepartmentManagement
3. Flex端建立工程
1. 建立 Flex与Java通信载体RemoteObject
为方便在整个工程中使用, 可建立一个Singleton – 关于AS中的Singleton可见: http://liguoliang.com/2008/10/128/
在该类中建立RemoteObject.
首先需要确定RemoteObject的destination, 在本例中 为”DepartmentManagement”; – 在remoting-config.xml中已配置.
其次需要确定ro的channel – 本例中为:”http://localhost:8080/DepartmentManagement/messagebroker/amf"; - 在services-config.xml中已配置
代码:
public static const DEFAULT_DEST:String = "DepartmentManagement"; public static const DEFAULT_CHANNEL_URL:String = "http://localhost:8080/DepartmentManagement/messagebroker/amf"; private static var _ro:RemoteObject; /** * Constractor - Singleton */ public function AppContext():void { throw new Error("AppContext is Singleton!"); } /** * Get RemoteObject */ public static function getRemoteObject():RemoteObject { if(_ro == null) { _ro = createRemoteObject(DEFAULT_DEST, DEFAULT_CHANNEL_URL); } return _ro; } /** * Constructs a new remote object with new channel. * @param roDestination Destination of the RemoteObject; should match a destination name in the services-config.xml file. * @param channelURI the URI used to create the whole endpoint URI for this channel; this uri can be relative uri (to the folder containing the SWF). * @param channelId the id of the channel, if set to null, a random Id will be assigned. */ protected static function createRemoteObject(roDestination:String, channelURI:String, channelId:String = null):RemoteObject { var channelSet:ChannelSet = new ChannelSet(); var channel:AMFChannel = new AMFChannel(channelId == null ? "channel-" : channelId, channelURI); //Create new Channel channelSet.addChannel(channel); var ro:RemoteObject = new RemoteObject(roDestination); ro.channelSet = channelSet; return ro; }
4 配置完成,.
在Java端建立相关的Class,
启动服务器.
在Flex端通过 Appcontext.getRemoteObject.getOperation(“方法名称”)来调用服务器端方法.
具体实例:
Java端的Class – 通过JDBC 读取 MySql中数据:
/** * Load all Department and return an ArrayList * @return */ public ArrayList loadDepartments() { ArrayList departmentsAL = new ArrayList(); log.info("Loading Departments..."); try { //Get Connection Connection conn = JdbcUtilities.getConnection(); //Create statement String sql = " SELECT * FROM Department d ORDER BY d.Department_ID"; PreparedStatement ps = conn.prepareStatement(sql); ResultSet res = ps.executeQuery(); log.debug("Exectuing: " + sql); while (res.next()) { int id = res.getInt("Department_ID"); String name = res.getString("name"); Department dp = new Department(); dp.setId(id); dp.setName(name); departmentsAL.add(dp); log.debug("从数据库获得部门: " + dp); } JdbcUtilities.closeConn(res, ps, conn); log.info("加载部门信息结束, 共加载部门: " + departmentsAL.size()); } catch (Exception e) { log.error("SQL Error", e); throw new Error(e); } return departmentsAL; }
Flex端的代码:
/** * Load the Department's Employee */ private var op:AbstractOperation; public function loadEmployees():void { op = AppContext.getRemoteObject().getOperation("loadEmployees"); //获得Operation op.arguments = [id]; //设定参数 var at:AsyncToken = op.send(); //Send at.addResponder(this); //为本实例增加responder }
Flex端responder剩余代码见:http://liguoliang.com/2009/02/777/
运行Flex工程, Flex取得RemoteObject, 然后通过channel建立到destination的连接,由Java读取数据库中信息, 并返回给Flex.
编写SQL语句, 尤其是要插入多个Filed时, 是一件非常BT的事情, 至少让我很不爽, 使用preparedstatement可以使代码变得更优雅一些, 虽然会有些长, 但会更条理, 而且preparedstatement更高于SQL语句 – 相对来说不太容易随着数据库版本改变而变动. 另外preparedstatement效率更高, 安全性更好
下面是恐怖的SQL:
Statement statement = (Statement) conn.createStatement(); String sql = "INSERT INTO `DEP`.`employee` " + "( `name` , `age` , `address` , `isMale` , `level` , `Department_ID` ) " + "VALUES (" + "'" + emp.getName() + "', " + emp.getAge() + ", " + JdbcUtilities.getSqlForString(emp.getAddress()) + ", " + emp.getIsMale() + ", " + emp.getLevel() + ", " + emp.getDepartment_ID() + ");" ; log.debug("Executing sql :" + sql); statement.executeUpdate(sql); ResultSet rs = statement.executeQuery("SELECT last_insert_id();");// .execute("SELECT last_insert_id();"); if(rs.next()) { System.out.println(rs.getInt("1")); }
这里是使用PreparedStatement后的语句:
String psql = "INSERT INTO Employee (name, age, address, isMale, level, Department_ID) VALUES (?, ?, ?, ?, ?, ?)"; PreparedStatement ps = conn.prepareStatement(psql,Statement.RETURN_GENERATED_KEYS); ps.setString(1, emp.getName()); ps.setInt(2, emp.getAge()); ps.setString(3, emp.getAddress()); ps.setInt(4, emp.getIsMale()); ps.setInt(5, emp.getLevel()); ps.setInt(6, emp.getDepartment_ID()); ps.executeUpdate(); ResultSet keys = ps.getGeneratedKeys(); // equivalent to "SELECT last_insert_id();" if(keys.next()) { System.out.println(keys.getInt(1)); }
PreparedStatement的使用步骤:
声明 PreparedStatement。
PreparedStatement prepStmt;
将一条 SQL 语句指派给 PreparedStatement 对象。
prepStmt = conn.prepareStatement( "INSERT INTO MyTable(MyColumn) values (?)");
为该语句指派输入参数值。
以下代码显示一个字符串参数。
String newValue; // assign value prepStmt.setStringParameter(1, newValue);
执行该语句。
返回值表示受该语句影响的行数。
long rowsInserted = prepStmt.executeStatement();
如果禁用了 [自动提交],请提交更改。
conn.commit();
获得组后插入的ID, 在上面代码中已经包括.
// Proudly powered by Apache, PHP, MySQL, WordPress, Bootstrap, etc,.