https://www.jetbrains.com/idea/download/other.html 靠下位置有,已经下载到“下载目录”
下载JDK8https://www.oracle.com/java/technologies/downloads/#java8 考下位置有,已经下载到“下载目录”
安装JDK8- 卸载jdk18步骤:
- 删除目录 D:installjdk-18; 我这里直接改名: D:installjdk-18太新了不用
- 删除JAVA_HOME
- 删除PATH (JDK18的只有jdk/bin目录,没有jre/并目录)
- 安装jdk8步骤:
- 安装软件到 D:installjdk8
- 添加 JAVA_HOME D:installjdk8
- 添加PATH D:installjdk8bin D:installjdk8jrebin
- 删除PATH C:Program Files (x86)Common FilesOracleJavajavapath
- 参考破解网址: http://www.itmind.net/10705.html
- 卸载IDEA2022
- 安装IDEA2021.2.3.exe
- 安装目录: D:installIDEA2021.2.3 (勾选桌面图标 和 .java)
- 启动IDEA
- Start trial : 注册JETBRAINS账号使用github账号wangwei129, WANG WEI 密码 a&89Uiojkl
- 新建java项目 :参考 http://www.itmind.net/5859.html
- 然后依次点击菜单 Help -> Edit Custom VM Options 来通过 IDEA 修改 idea.vmoptions 文件, 在末尾添加解补丁:
-javaagent:D:\IDEA30TRIALFineAgent.jar
9. 补丁FineAgent.jar可获取 :
补丁安装教程:http://www.itmind.net/10701.html 补丁网盘链接: https://pan.baidu.com/s/1E7URZ_bTe3XTvyUOEBsYIw 提取码: cv5c 备用链接: https://pan.baidu.com/s/1gERUKH934jiZekIligoP-Q 提取码: 3v6a 长按扫描下方二维码加我微信,私信我 888 拉你入群,第一时间获取更新信息~~ #补丁已经保存到我的网盘2022目录下
10. 关闭IDEA
-
启动IDEA
-
现在注册码注册
-
把中D:IDEA30TRIALActivationCode.txt的注册码复制填进去
-
破解完成。
注明:自动导入包和删包: 文件-设置-编辑-常规-自动导入
https://tomcat.apache.org/download-80.cgi
解压即安装:安装目录 D:installapache-tomcat-8.5.78-windows-x64apache-tomcat-8.5.78
启动 start.bat
停止 stop.bat
把你的war包放在 D:installapache-tomcat-8.5.78-windows-x64apache-tomcat-8.5.78webapps 目录下即可
1、tomcat窗口中内容中文乱码解决:
找到tomcat下conf文件夹下的logging.properties文件,打开后找到
java.util.logging.ConsoleHandler.encoding = UTF-8,将其修改为
java.util.logging.ConsoleHandler.encoding = GBK
注明: 直接把这个安装目录上传到linux上,页可以使用,使用sh启停。
JAVA web项目实战流程 新建web项目
1. File - New - Project 2. Java - Next 3. 不选择任何模板 4. 给项目取名字webdemo 5. 选中创建好的项目 - 右键 - Add Framework Support - Java Web 6. Run - Edit Configurations - Edit configuration templates... - Tomcat Server - Local - Application Server: - Configure... - 选择Tomcat的安装目录 7. Run - Edit Configurations - + - Tomcat Server - 选择打包内容 修改打包名(即是war包名或路径名) 8. 运行Web项目第一个Servlet页面 1. 添加tomcat的jar包
2. src
右键工程
Open module setging 模块设置
Libraries
+java
打开目录D:installapache-tomcat-8.5.78-windows-x64apache-tomcat-8.5.78lib
添加jsp-api.jar和servlet-api.jar两个包
起名Name:lib
Apply - OK
3. web.xml新建包: com.trey.servlet
新建类: Servlet001.java
继承: extends HttpServlet
重写方法: doGet / doPost
public class Servlet001 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); PrintWriter writer = resp.getWriter(); writer.println(""); String s = "Hello servlet Web"; writer.println(s); writer.println(""); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } }
4. 启动项目 5. 访问网站
servlet001 com.trey.servlet.Servlet001 servlet001 /hello
打包IDEA项目成war包 打包和发布http://localhost:8080/webdemo_war/ 项目主页
http://localhost:8080/webdemo_war/hello 第一个servlet页
1、进入Project Structre (文件 - 项目结构) 2、找到Atrtifacts模块 —> 点击左上角添加 —> Web Application: Archive —> For " " (工件 - 添加 - web应用程序:归档 - for"Web名称") 3、指定名称和输出路径;点击下方 + 号,选择 Directory Content (打包取名: webdemo) (输出路径: D:gosrcwebdemooutartifactswebdemo) (Directory Content好像不用做) 4、选择项目的 WebRoot目录 ,点击 ok (Directory Content好像不用做) 5、回到主页面,点击 Build -> 选择 Build Artifacts -> 选择刚刚生成的artifact -> 点击 build 6、等待build结束,在指定的输出路径中拿到war包 (D:gosrcwebdemooutartifactswebdemowebdemo.war) 7、把war包上传到tomcat的webapps目录即可
Servlet+JSP+JDBC综合案例 新建WEB项目
如上
添加数据库驱动包测试一下jdbc
- WEB-INF 下新建目录 lib
- 把D:jdbcmysqlmysql-connector-java-5.1.42-bin.jar 复制到 lib
- 后续动作如上(添加tomcat的jar包)。
在mysql中创建表user
- 新建包 com.trey.testjdbc
- 新建类 TestJdbc
package com.trey.testjdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class TestJdbc { public static void main(String[] args) { try { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://1.1.1.3:3306/bookdb?useUnicode=true&characterEncoding=UTF-8"; String user = "root"; String password = "Passwd123"; Connection connection = DriverManager.getConnection(url,user,password); System.out.println(connection); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } }
- 运行测试类,能够正常拿到connection没有任何报错,证明jdbc正常。
DROp TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(9) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`age` int,
`register` datetime,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact
;
insert into user(name,age,register) values('张三',36,'2022-05-22 08:00:00');
insert into user(name,age,register) values('李四',36,'2022-05-22 08:00:00');
insert into user(name,age,register) values('王五',36,'2022-05-22 08:00:00');
select * from user;
包类规划
package com.trey.entity; //实体包 Student //实体类 package com.trey.repository; //储藏包 StudentRepository //储藏类 package com.trey.servlet; //控制包 StudentServlet //控制类 package com.trey.filter; //过滤器包 CharacterFilter //过滤器类 package com.trey.entity; //实体类 package com.trey.entity; //实体类java 查询 mysql
注明:自动生成getter和setter的快捷键是alt+insert,然后选中所有字段即可。
实体类package com.trey.entity;
import java.util.Date;
public class Student {
private Integer id;
private String name;
private Double age;
private Date register;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getAge() {
return age;
}
public void setAge(Double age) {
this.age = age;
}
public Date getRegister() {
return register;
}
public void setRegister(Date register) {
this.register = register;
}
public Student(Integer id, String name, Double age, Date register) {
this.id = id;
this.name = name;
this.age = age;
this.register = register;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + ''' +
", age=" + age +
", register=" + register +
'}';
}
}
储藏类
package com.trey.repository;
import com.trey.entity.Student;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class StudentRepository {
public List findAll(){
ArrayList list = new ArrayList<>();
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://1.1.1.3:3306/bookdb?useUnicode=true&characterEncoding=UTF-8";
String user = "root";
String password = "Passwd123";
connection = DriverManager.getConnection(url,user,password);
String sql = "select * from user;";
preparedStatement = connection.prepareStatement(sql);
resultSet = preparedStatement.executeQuery();
Student student = null;
while (resultSet.next()) {
int id = resultSet.getInt(1);
String name = resultSet.getString(2);
double age = resultSet.getDouble(3);
Date date = resultSet.getDate(4);
student = new Student(id, name, age, date);
list.add(student);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
connection.close();
preparedStatement.close();
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return list;
}
public static void main(String[] args) {
StudentRepository studentRepository = new StudentRepository();
System.out.println(studentRepository.findAll());
}
}
控制类
jsp接收数据,还需要两个包: jstl.jar 和standard.jar
(我下载好了,放到了 D:installapache-tomcat-8.5.78-windows-x64jakarta-taglibs-standard-1.1.2 )
package com.trey.servlet;
import com.trey.entity.Student;
import com.trey.repository.StudentRepository;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@WebServlet("/student")
public class StudentServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//返回试图+数据
StudentRepository studentRepository = new StudentRepository();
List list = studentRepository.findAll();
System.out.println(list);
req.setAttribute("list",list); //数据
req.getRequestDispatcher("index.jsp").forward(req,resp); //视图
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
试图index.jsp
<%--
Created by IntelliJ IDEA.
User: Lenovo
Date: 2022/5/22
Time: 17:23
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
$Title$
学生管理系统
| 编号 | 姓名 | 成绩 | 注册日期 |
|---|---|---|---|
| ${student.id} | ${student.name} | ${student.age} | ${student.register} |
启动项目
打开网页 : http://1.1.1.1:8080/student
学生管理系统查询结果
| 编号 | 姓名 | 成绩 | 注册日期 |
|---|---|---|---|
| 5 | 张三 | 36.0 | 2022-05-22 |
| 6 | 李四 | 36.0 | 2022-05-22 |
| 7 | 王五 | 36.0 | 2022-05-22 |
在web下面新建
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
添加记录
实现储藏类Repository的add方法
public void add(String name,Double age){
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://1.1.1.3:3306/bookdb?useUnicode=true&characterEncoding=UTF-8";
String user = "root";
String password = "Passwd123";
connection = DriverManager.getConnection(url,user,password);
String sql = "insert into user(name,age,register) values (?,?,?)";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,name);
preparedStatement.setDouble(2,age);
preparedStatement.setDate(3,new Date(System.currentTimeMillis()));
preparedStatement.executeUpdate();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
connection.close();
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
实现Servlet的doPost方法
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//处理汉字乱码方法1,此方法中把req转化成UTF-8编码
req.setCharacterEncoding("UTF-8");
//处理汉字乱码方法2,过滤器
//CharacterFilter.java
//读取表单数据
String name = req.getParameter("name");
String ageStr = req.getParameter("age");
Double age = Double.parseDouble(ageStr);
//执行insert
studentRepository.add(name,age);
//返回重定向到查询页面
resp.sendRedirect("/student");
}
过滤器
注明:选中类名ctrl+i实现接口 。 如果什么都不写,就统统拦截
package com.trey.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
//拦截
@WebFilter("/student")
//实现Filter接口
public class CharacterFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("UTF-8");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
优化 JDBCTools 提取封装
新建包类 JDBCTools
包 : com.trey.tuil
类 : JDBCTools
package com.trey.util;
import java.sql.*;
public class JDBCTools {
private static Connection connection;
private static String url = "jdbc:mysql://1.1.1.3:3306/bookdb?useUnicode=true&characterEncoding=UTF-8";
private static String user = "root";
private static String password = "Passwd123";
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection(){
try {
connection = DriverManager.getConnection(url,user,password);
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
public static void release(Connection connection, Statement statement, ResultSet resultSet){
try {
if (connection != null) {
connection.close();
}
if (statement != null) {
statement.close();
}
if (resultSet != null) {
resultSet.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
修改Repository储藏类
package com.trey.repository;
import com.trey.entity.Student;
import com.trey.util.JDBCTools;
import java.sql.*;
import java.util.ArrayList;
import java.util.Currency;
import java.util.List;
public class StudentRepository {
public List findAll(){
ArrayList list = new ArrayList<>();
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = JDBCTools.getConnection();
String sql = "select * from user;";
preparedStatement = connection.prepareStatement(sql);
resultSet = preparedStatement.executeQuery();
Student student = null;
while (resultSet.next()) {
int id = resultSet.getInt(1);
String name = resultSet.getString(2);
double age = resultSet.getDouble(3);
Date date = resultSet.getDate(4);
student = new Student(id, name, age, date);
list.add(student);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCTools.release(connection, preparedStatement, resultSet);
}
return list;
}
public static void main(String[] args) {
StudentRepository studentRepository = new StudentRepository();
System.out.println(studentRepository.findAll());
}
public void add(String name,Double age){
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = JDBCTools.getConnection();
String sql = "insert into user(name,age,register) values (?,?,?)";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,name);
preparedStatement.setDouble(2,age);
preparedStatement.setDate(3,new Date(System.currentTimeMillis()));
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCTools.release(connection,preparedStatement,null);
}
}
}
java 删除 mysql
修改index.jsp (提供页面操作入口)
| 编号 | 姓名 | 成绩 | 注册日期 | 操作 |
|---|---|---|---|---|
| ${student.id} | ${student.name} | ${student.age} | ${student.register} | 删除 修改 |
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getParameter("method");
if (method == null) {
method = "findAll";
}
switch (method) {
case "findAll":
//返回试图+数据
List list = studentRepository.findAll();
req.setAttribute("list",list); //数据
req.getRequestDispatcher("index.jsp").forward(req,resp); //视图
break;
case "delete":
String idStr = req.getParameter("id");
int id = Integer.parseInt(idStr);
studentRepository.deleteById(id);
resp.sendRedirect("/student");
break;
}
}
实现储藏类delete方法
public void deleteById(Integer id){
Connection connection = null;
PreparedStatement preparedStatement = null;
connection = JDBCTools.getConnection();
String sql = "delete from user where id = ?";
try {
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,id);
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCTools.release(connection, preparedStatement, null);
}
}
java 修改 mysql
修改index.jsp(提供页面操作入口) 取id
学生管理系统
| 编号 | 姓名 | 成绩 | 注册日期 | 操作 |
|---|---|---|---|---|
| ${student.id} | ${student.name} | ${student.age} | ${student.register} | 删除 修改 |
根据id取出Student对象
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getParameter("method");
if (method == null) {
method = "findAll";
}
switch (method) {
case "findAll":
//返回试图+数据
List list = studentRepository.findAll();
req.setAttribute("list",list); //数据
req.getRequestDispatcher("selectAll.jsp").forward(req,resp); //视图
break;
case "deleteById":
String idStr = req.getParameter("id");
int id = Integer.parseInt(idStr);
studentRepository.deleteById(id);
resp.sendRedirect("/student");
break;
case "findById":
idStr = req.getParameter("id");
id = Integer.parseInt(idStr);
req.setAttribute("student",studentRepository.findById(id));
req.getRequestDispatcher("update.jsp").forward(req,resp);
break;
}
}
根据Student对象填写update.jsp页面
修改记录
修改update.jsp里面的值
网页操作,修改
将新值传入update.sql语句,并执行,并返回新全表数据页面 @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getParameter("method");
switch (method) {
case "update":
String idStr = req.getParameter("id");
int id = Integer.parseInt(idStr);
name = req.getParameter("name");
ageStr = req.getParameter("age");
age = Double.parseDouble(ageStr);
studentRepository.update(id,name,age);
//返回重定向到查询页面
resp.sendRedirect("/student");
break;
执行update.sql语句
public void update(Integer id, String name, Double age){
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = JDBCTools.getConnection();
String sql = "update user set name = ? , age = ? , register = ? where id = ?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,name);
preparedStatement.setDouble(2,age);
preparedStatement.setDate(3,new Date(System.currentTimeMillis()));
preparedStatement.setInt(4,id);
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCTools.release(connection,preparedStatement,null);
}
}
后续汇总
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CiBxPwSY-1659011883309)(C:UsersLenovoAppDataRoamingTyporatypora-user-images1653302798049.png)]
informix报错情况 数据库没有启动java.sql.SQLException: com.gbasedbt.asf.IfxASFException: Attempt to connect to database server (g31) failed. at com.gbasedbt.jdbc.IfxSqliConnect.字符集不匹配(IfxSqliConnect.java:1611) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
java.sql.SQLException: Unable to load locale categories. at com.gbasedbt.jdbc.IfxSqliConnect.表不存在(IfxSqliConnect.java:1436) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
java.sql.SQLException: com.gbasedbt.asf.IfxASFException: Attempt to connect to database server (g31) failed. at com.gbasedbt.jdbc.IfxSqliConnect.insert语句中出现非法字符(IfxSqliConnect.java:1611) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
#环境 dbvis DB字符集gbk
jdbc:gbasedbt-sqli://1.1.1.3:9031/gbk:GBASEDBTSERVER=g31;DB_LOCALE=zh_CN.GB18030-2000;CLIENT_LOCALE=zh_CN.GB18030-2000;NEWCODESET=utf8,GB18030-2000,5488;IFX_LOCK_MODE_WAIT=30
#语句
insert into user(name,age) values('汪',1); --这一句报错
insert into user(name,age) values('伟',1); --这一句报错
insert into user(name,age) values('汪伟',1); --这一句不报错
这里的报错和报错说明,utf8->gb18030的字符转换有问题。
如果此时关闭过滤器,那么java中insert就不会报错,插入的汪是:c3 a6 c2 b1 c2 aa
汪 utf8: e6 b1 aa 对应字符 f 1 *
汪 gbk : cd f4 对应字符 M t
#报错
[Code: -202, SQL State: IX000] An illegal character has been found in the statement.
#处理:把NEWCODESET设置为jbk即可,但是这f样如果之前入口的数据库是utf8的就存在不一致编码数据
jdbc:gbasedbt-sqli://1.1.1.3:9031/gbk:GBASEDBTSERVER=g31;DB_LOCALE=zh_CN.GB18030-2000;CLIENT_LOCALE=zh_CN.GB18030-2000;NEWCODESET=GB18030,GB18030-2000,5488;IFX_LOCK_MODE_WAIT=30
Java里面也会遇到insert语句中出现非法字符
java.sql.SQLException: An illegal character has been found in the statement. at com.gbasedbt.util.IfxErrMsg.getSQLException(IfxErrMsg.java:408) at com.gbasedbt.jdbc.IfxSqli.a(IfxSqli.java:3572) at com.gbasedbt.jdbc.IfxSqli.D(IfxSqli.java:3852) at com.gbasedbt.jdbc.IfxSqli.dispatchMsg(IfxSqli.java:2738)Java里面遇到了不能解码的数据select语句
java.sql.SQLException: Encoding or code set not supported. at com.gbasedbt.util.IfxErrMsg.getSQLException(IfxErrMsg.java:408) at com.gbasedbt.jdbc.IfxVarChar.fromIfx(IfxVarChar.java:195) at com.gbasedbt.jdbc.IfxRowColumn.a(IfxRowColumn.java:335)字符集不存在
Error -23101 Unable to load locale categories
当设置的 DB_LOCALE 和 CLIENT_LOCALE 的字符集对应的以下文件不存在时,出现该错误。
- $InformixDIR/gls/lc11/DB_LOCALE's( 语言 _ 地区 )/(db 的 16 进制编码 ).lco
- $InformixDIR/gls/lc11/CLIENT_LOCALE's( 语言 _ 地区 )/( db 的 16 进制编码 ).lco
- $InformixDIR/gls/lc11/CLIENT_LOCALE's( 语言 _ 地区 )/( client 的 16 进制编码 ).lco
字符集不能转换
Error -23104 Error opening required code-set conversion object file 当设置的 DB_LOCALE 和 CLIENT_LOCALE 的字符集对应的以下转换文件不存在时,会出现该错误。当然只有当 DB_LOCALE 和 CLIENT_LOCALE 的字符集不一致时才会需要转换,如果一致则不会出现 -23104 错误。 - $InformixDIR/gls/cv9/ccccdddd.cvo - $InformixDIR/gls/cv9/ddddcccc.cvo 其中:cccc 为 CLIENT_LOCALE 字符集编码对应的 16 进制值 dddd 为 DB_LOCALE 字符集编码对应的 16 进制值字符集DB_LOCALE不匹配
Error -23197 Database locale information mismatch
当出现如下情况时,出现 -23197 错误。
定义的 DB_LOCALE 值与数据库的使用的值(数据库创建时使用的 DB_LOCALE 值)不一致;
通过 SET COLLATION 语句定义 DB_LOCALE 值与数据库的使用值不一致 ;
字符集存在非法字符
Error -201,-202 数据库提示语法错误 Error -201,-202 数据库提示语法错误,不支持中文对象名,如中文表名、字段别名、视图名。该类错误提示原因是当前数据库的 DB_LOCALE 设置问题。 如果数据库的 DB_LOCALE 设置为 zh_cn.GB18030-2000,则数据库就可以支持中文对象名。Servlet + JSP + JDBC 把库换成GBasedb8s informix 创建user表
DROp TABLE IF EXISTS user;
CREATE TABLE user (
id serial not null ,
name varchar(9) not null,
age int,
register datetime year to second,
PRIMARY KEY (id)
) extent size 64 next size 128
;
insert into user(name,age,register) values('张三',36,'2022-05-22 08:00:00');
insert into user(name,age,register) values('李四',36,'2022-05-22 08:00:00');
insert into user(name,age,register) values('王五',36,'2022-05-22 08:00:00');
新建JDBCToolsGBase类
package com.trey.util;
import java.sql.*;
public class JDBCToolsGBase {
private static Connection connection;
//DB是utf8库编码
//DB_LOCALE=zh_CN.utf8
//dbs_dbsname utf8
//dbs_collate zh_CN.57372
private static String urlutf8 = "jdbc:gbasedbt-sqli://1.1.1.3:9031/utf8:GBASEDBTSERVER=g31;DB_LOCALE=zh_CN.utf8;CLIENT_LOCALE=zh_CN.utf8;IFX_LOCK_MODE_WAIT=30";
//DB是819库编码
//DB_LOCALE=en_US.819
//dbs_dbsname sysmaster
//dbs_collate en_US.819
private static String url819utf8 = "jdbc:gbasedbt-sqli://1.1.1.3:9031/sysmaster:GBASEDBTSERVER=g31;DB_LOCALE=en_US.819;NEWCODESET=utf8,8859-1,819;IFX_LOCK_MODE_WAIT=30";
private static String url819gbk = "jdbc:gbasedbt-sqli://1.1.1.3:9031/sysmaster:GBASEDBTSERVER=g31;DB_LOCALE=en_US.819;NEWCODESET=GB18030-2000,8859-1,819;IFX_LOCK_MODE_WAIT=30";
//DB是gbk库编码
//DB_LOCALE=zh_CN.GB18030-2000
//dbs_dbsname gbk
//dbs_collate zh_CN.5488
//这样可以正常处理utf8终端插入的汉字,再次证明解铃还须系铃人,NEWCODESET=jdk编码集.校验字符集.校验字符编号。
// (注意这时如果关闭过滤器:会出现页面insert的数据是乱码的问题,应为这时页面以gbk的数据把数据存入了gbk的库,但是你读取的时候又把jbk的数据转成了utf8)
// (后来发现如果关闭过滤器,插入如的数据,是什么编码,情况比上面我说的还要复杂,它并不是gbk,也不是utf8.他1个汉字就占6个字符。)
//private static String urlgbk = "jdbc:gbasedbt-sqli://1.1.1.3:9031/gbk:GBASEDBTSERVER=g31;DB_LOCALE=zh_CN.GB18030-2000;CLIENT_LOCALE=zh_CN.GB18030-2000;NEWCODESET=utf8,GB18030-2000,5488;IFX_LOCK_MODE_WAIT=30";
//而这样可以正常处理gbk终端插入的汉字,正确。
//private static String urlgbk = "jdbc:gbasedbt-sqli://1.1.1.3:9031/gbk:GBASEDBTSERVER=g31;DB_LOCALE=zh_CN.GB18030-2000;CLIENT_LOCALE=zh_CN.GB18030-2000;NEWCODESET=GB18030,GB18030-2000,5488;IFX_LOCK_MODE_WAIT=30";
//NEWCODESET可以省略
private static String urlgbk = "jdbc:gbasedbt-sqli://1.1.1.3:9031/gbk:GBASEDBTSERVER=g31;DB_LOCALE=zh_CN.GB18030-2000;CLIENT_LOCALE=zh_CN.GB18030-2000;IFX_LOCK_MODE_WAIT=30";
//一句话: NEWCODESET的第一个字段是你的数据存储表中的编码,它等于你的终端的编码,或者说它等于你的jdk的编码。
//两句话: 我们平常说的数据库的字符集,其实准确的说是数据库校验字符集,它是做校验的,它不是实际存储的表的字符集。
//三句话: 推荐校验字符集和终端字符集保持统一字符集,那么就不需要NEWCODESET了。
//四句话: 为了防止终端字符集把不同的数据编码存入表中,可以开启NEWCODESET,它保证了读写表的字符集。
//五句话: 如果没有设置NEWCODESET那么,默认终端或jdk保证了表的字符集。
//最后一句: 过滤器不能关,关了表里的编码很乱。要保证过滤器的字符集和校验字符集一致,这样就避免了NEWCODESET的校验,这样就不会遇到'汪'字不能插入的问题。(入库时的校验只是为了出库时的正常,并不实际转换。)
private static String user = "gbasedbt";
private static String password = "GBase123";
static {
try {
Class.forName("com.gbasedbt.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection(){
try {
//connection = DriverManager.getConnection(urlutf8,user,password);
//connection = DriverManager.getConnection(url819,user,password);
connection = DriverManager.getConnection(urlgbk,user,password);
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
public static void release(Connection connection, Statement statement, ResultSet resultSet){
try {
if (connection != null) {
connection.close();
}
if (statement != null) {
statement.close();
}
if (resultSet != null) {
resultSet.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
把储藏类连接数据可类换成此类即可
简单省略
INFOMRIX 和 JDK的字符集设置 创建utf8编码的数据库export DB_LOCALE=zh_CN.utf8 export CLIENT_LOCALE=zh_CN.utf8 echo "create database gbk in datadbs01 with log;" |dbaccess sysmaster echo "select * from sysdbslocale;" |dbaccess sysmaster创建gbk编码的数据库
export DB_LOCALE=zh_CN.GB18030-2000 export CLIENT_LOCALE=zh_CN.GB18030-2000 echo "create database gbk in datadbs01 with log;" |dbaccess sysmaster echo "select * from sysdbslocale;" |dbaccess sysmaster我java项目用的是utf8编码
见上文过滤器
informix GLS 编码和转换 编码对照表-注册registryInformixDIR=/opt/gbase330 cat $InformixDIR/gls/cm3/registry #查看 GLS 字符名称、编码对照表。 gbasedbt:g31[/opt/gbase330/gls]$cat $InformixDIR/gls/cm3/registry |grep 18030 gbasedbt:g31[/opt/gbase330/gls]$cat $InformixDIR/gls/cm3/registry |grep -i utf8 gbasedbt:g31[/opt/gbase330/gls]$cat $InformixDIR/gls/cm3/registry |grep -i e00d #结果 #字符集名称 编码 十六进制编码 GB18030-2000 5488 # 0x1570 Simplified Chinese GB18030-2000 utf8 57372 # 0xe01c 注意:utf8是72 gb 57357 # 0xe00d 注意: gb是57 GB2312-80 57357 # 0xe00d cp936 57357 # 0xe00d Simplified Chinese Microsoft Windows Guobiao2312 57357 # 0xe00d gbasedbt:g31[/opt/gbase330/gls]$一个字符集可以有多个名称
GLS 环境中不同字符集名称可能对应同一个字符集编码,但一个字符集只能有一个编码,也就是说字符集编码才是唯一的。
字符集存放在不同的目录 GLS 环境中按照语言和地区把所支持的字符集分成不同的目录。 I n f o r m i x D I R / g l s / l c 11 / 语 言 地 区 / ,如中文大陆地区的目录为: InformixDIR/gls/lc11/ 语言 _ 地区 /,如中文大陆地区的目录为: InformixDIR/gls/lc11/语言地区/,如中文大陆地区的目录为:InformixDIR/gls/lc11/zh_cn/,该目录下有如下两个文件:1570.lco e00d.lco ,说明我们在设置字符集时,我们可以使用 zh_cn.GB18030-2000 zh_cn.gb zh_cn.GB2312-80 三个不同的名称。这里(zh_cn.gb 与 zh_cn.GB2312-80 对应相同的字符集)。
那些字符集直接可以转换 GLS 环境中不同的字符集可以正确的进行转换,查看那些字符集可以正确转换的方法,查看目录 $InformixDIR/gls/cv9 目录下的是否存在指定字符集互相转换的文件。如该目录下有文件 e01ce00d.cvo 和 e00de01c.cvo 两个文件,表示 GLS 通过这两个转换文件支持 UTF-8 与 GB 之间的字符转换。
InformixDIR=/opt/gbase330 ls -l $InformixDIR/gls/cv9 #查看utf8可以转换成那些字符集 ls -l $InformixDIR/gls/cv9 |grep ' e01c' #查看那些字符集可以转换成utf8 ls -l $InformixDIR/gls/cv9 |grep 'e01c.' #查看utf8和GB18030-2000能否相互转换(注明:可以) ls -l $InformixDIR/gls/cv9 |grep 'e01c'|grep '1570' #查看utf8和gb能否相互转换(注明:可以) ls -l $InformixDIR/gls/cv9 |grep 'e01c'|grep 'e00d'DB_LOCALE 和 CLIENT_LOCALE
Informix 通过 DB_LOCALE 和 CLIENT_LOCALE 来设置数据库的语言本地化支持设置。DB_LOCALE 和 CLIENT_LOCALE 的值由四部分组成 ( 第 4 部分为可选 ),字符集不区分大小写。
1 2 3 4 < 语言 >_< 国家和地区 >.< 字符集名 / 字符集编码 >[@modifier]
举例说明 :
CLIENT_LOCALE=en_us.8859-1 CLIENT_LOCALE=en_us.819 # 以上两个为同一字符集:819 为 8859-1 的编码 DB_LOCALE=zh_cn.gbDB_LOCALE 环境变量用途
- 在客户机应用程序和数据库服务器交换字符数据时,如果 DB_LOCALE 环境变量(在客户机计算机上)的值与 CLIENT_LOCALE 的值不同,客户机应用程序将执行代码集转换。 代码集转换防止这两种代码集不同时发生数据破坏。
- 在客户机应用程序请求连接时,它将包括 DB_LOCALE(如果已设置)的信息发送至数据库服务器。
- 在确定如何设置服务器处理语言环境的数据库信息时,数据库服务器使用 DB_LOCALE。
- 在客户机应用程序尝试打开数据库时,数据库服务器将客户机应用程序传递的 DB_LOCALE 环境变量的值与数据库中存储的数据库语言环境进行比较。
- 当数据库服务器存取与语言环境相关的数据类型的列时,数据库服务器使用 DB_LOCALE 指定的语言环境。
- 当数据库服务器创建新数据库时,它将检查数据库语言环境(DB_LOCALE),以确定如何在数据库的系统目录中存储字符信息。此信息包括诸如如何处理正则表达式、比较字符串以及确保代码集的正确使用的操作。
- 在客户机应用程序和数据库服务器交换字符数据时,如果 CLIENT_LOCALE 环境变量的代码集与 DB_LOCALE(在客户机计算机上)的代码集不同,客户机应用程序将执行代码集转换。代码集转换防止这两种代码集不同时发生数据破坏。
- 在客户机应用程序请求连接时,它将包括 CLIENT_LOCALE 的信息发送至数据库服务器。
- 在确定如何设置服务器处理语言环境的客户机应用程序信息时,数据库服务器将使用 CLIENT_LOCALE。
- 在 Informix ESQL/C 的预处理器处理源文件时,它接受以 CLIENT_LOCALE 的代码集编写的 C 源代码。 在 Informix ESQL/C 客户机应用程序执行时,将检查 CLIENT_LOCALE 以获得客户机语言环境的名称,该语言环境将对操作系统文件名、文本文件的内容以及日期、时间和数字数据的格式产生影响。
- 在数据库实用程序创建文件时,文件名和文件内容位于 CLIENT_LOCALE 指定的代码集中。在查找特定于产品的消息文件时,客户机应用程序将检查与客户机语言环境关联的消息目录。
当以下两个条件都为真时,客户机应用程序自动在客户机和数据库代码集之间执行代码集转换:
- 客户机和数据库语言环境的代码集不匹配。
- 客户机和数据库代码集之间的转换存在有效的目标代码集转换。
客户机应用程序开始执行时,它会比较客户机和数据库语言环境的名称,以确定是否执行代码集转换。如果设置了 CLIENT_LOCALE 和 DB_LOCALE 环境变量,那么客户机应用程序使用这些语言环境名称来分别确定客户机和数据库的代码集。如果未设置 CLIENT_LOCALE(且未设置 DBNLS),那么客户机应用程序假定客户机语言环境为缺省语言环境。如果未设置 DB_LOCALE(且未设置 DBNLS),那么客户机应用程序假定数据库语言环境与客户机语言环境(CLIENT_LOCALE 设置的值)相同。
CLIENT_LOCALE( 未设置将采用默认 en_us.819);
DB_LOCALE( 未设置则不发送,默认与CLIENT_LOCALE设置的值相同 )
时间格式问题Informix 数据库的时间格式由数据库服务器端环境变量 GL_DATE GL_DATETIME 控制,默认的字符集下默认的时间格式为:
GL_DATE="%m/%d/%iy" DATETIME="%iY-%m-%d %H:%M:%S"
但是,当我们设置了 DB_LOCALE 为 zh_cn.gb 的情形下,而没有设置 GL_DATE,DATETIME,则时间格式会采用 CLIENT_LOCALE 的值,在 zh_cn.gb 情况下,会出现:“2009 年 10 月 2 日”的日期格式,如果我们之前系统采用默认的时间格式的情况下,就会出现时间格式不匹配的错误。如果我们仍然需要采用默认的时间格式,我们需要在数据库服务端修改时间格式环境变量即可:
GL_DATE="%m/%d/%iy" DATETIME="%iY-%m-%d %H:%M:%S"换成unicode
数据库不能够脱离字符集独立存在,它一定属于某种字符集。
CSDK2.7 版本,IDS 默认情况下使用 Garbage In, Garbage Out 模式处理中文字符,若数据库服务器上的 DB_LOCALE 采用默认的 en_us.8859-1 字符集,能够正常支持中文字符。但是升级到 CSDK2.8 及以上版本时,不再支持 Garbage In, Garbage Out 模式,将出现乱码问题。iso-8859_1字符集的数据库只支持单字节。虽然可以往里面保存多字节的数据,但是数据库本身只是简单的认为这些数据只是单字节的数据。无论你存入的是双字节的中文,还是4字节的unicode数据,数据库本身只是把它当为单字节而已。
客户端通过jdbc连接上数据库,并提取数据后,数据按照数据库默认的编码方式被提取到客户端。客户端要将其转换成unicode。因为jdbc是基于java的,而java内部全部是unicode编码。那么在客户端进行转换的时候,就有问题了,到底按哪种格式转?
如果保存在数据库中的数据都是iso-8859_1中包含的字符,那么这样操作没错。但是如果是数据中有中文,那么这样操作就错了。
例如,汉字“中文”的ascii码为0xD6 0xD0 0xCE 0xC4,而常用的汉字codeset为cp936。如果按照cp936转unicode,则转换的结果是0xE4 0xB8 0xAD 0xE6 0x96 0x87;如果按照iso-8859_1转换则结果是0xC3 0x96 0xC3 0x90 0xC3 0x8E 0xC3 0x84.
你看,同样的数据,就是因为指定不同的原始字符集,导致转换成unicode的时候,结果截然不同。所以在用jdbc连接数据库的时候,有必要把这个转换关系给说清楚。
在informix jdbc中是通过newcodeset来说明问题的。
在这里,我们就要说清楚,数据库是按什么字符集存放数据的,取到客户端java时,这些数据需要按照什么样的字符集转换成unicode。
再或者更改数据库的字符集(设置 DB_LOCALE=zh_cn.GB18030-2000,重新创建数据库),然后按本文中描述的方法进行 DB_LOCALE 与 CLIENT_LOCALE 的设置方法进行处理。若在实际环境下重建数据库成本太高,可以考虑如下步骤进行解决 ODBC 支持中文的问题。
数据库服务器端:
1. 设置环境变量: IFMX_UNDOC_B168163=1
2. 将 en_us.8859-1 字符集文件拷贝到 zh_cn 目录下
cd $INFORMIXDIR/gls/lc11
cp ./en_us/0333.lco ./zh_cn
3. 重新启动 IDS
客户端:
设置语言环境:
l DB_LOCALE=zh_cn.GB18030-2000
l CLIENT_LOCALE=zh_cn.GB18030-2000
对于 JDBC 我们可以通过 NEWCODESET 来解决该问题:
newcodeset的格式如下: newcodeset=jdk codeset, ifx codeset,ifx codenum jdbc的URL链接信息如下: URLString = "jdbc:Informix-sqli://9.125.66.130:6346/dbname:InformixSERVER=servername; NEWCODESET=GB18030-2000,8859-1,819; CLIENT_LOCALE=en_US.8859-1; DB_LOCALE=en_US.8859-1;"数据库编码对照表 和 jdbc-url
| 环境变量DB_LOCALE | DB名称 | DB校对dbs_collate | NEWCODESET | |
|---|---|---|---|---|
| zh_CN.utf8 | utf8 | zh_CN.57372 | 可以空 utf8,utf8,57372 强换 GB18030-2000,utf8,57372 | |
| en_US.819 | sysmaster | en_US.819 | 不能空 utf8,8859-1,819 或 GB18030-2000,8859-1,819 | |
| zh_CN.GB18030-2000 | gbk | zh_CN.5488 | 可以空GB18030-2000,GB18030-2000,5488 强转utf8,GB18030-2000,5488 |
servletRequest.setCharacterEncoding("UTF-8");
filterChain.doFilter(servletRequest,servletResponse);
utf8 + 8859-1 + GB18030
private static String urlutf8 = "jdbc:gbasedbt-sqli://1.1.1.3:9031/utf8:GBASEDBTSERVER=g31;DB_LOCALE=zh_CN.utf8;CLIENT_LOCALE=zh_CN.utf8;IFX_LOCK_MODE_WAIT=30";
private static String urlutf8gbk = "jdbc:gbasedbt-sqli://1.1.1.3:9031/utf8:GBASEDBTSERVER=g31;DB_LOCALE=zh_CN.utf8;CLIENT_LOCALE=zh_CN.utf8;NEWCODESET=GB18030-2000,utf8,57372;IFX_LOCK_MODE_WAIT=30";
private static String url819utf8 = "jdbc:gbasedbt-sqli://1.1.1.3:9031/sysmaster:GBASEDBTSERVER=g31;DB_LOCALE=en_US.819;NEWCODESET=utf8,8859-1,819;IFX_LOCK_MODE_WAIT=30";
private static String url819gbk = "jdbc:gbasedbt-sqli://1.1.1.3:9031/sysmaster:GBASEDBTSERVER=g31;DB_LOCALE=en_US.819;NEWCODESET=GB18030-2000,8859-1,819;IFX_LOCK_MODE_WAIT=30";
private static String urlgbk = "jdbc:gbasedbt-sqli://1.1.1.3:9031/gbk:GBASEDBTSERVER=g31;DB_LOCALE=zh_CN.GB18030-2000;CLIENT_LOCALE=zh_CN.GB18030-2000;IFX_LOCK_MODE_WAIT=30";
private static String urlgbkutf8 = "jdbc:gbasedbt-sqli://1.1.1.3:9031/gbk:GBASEDBTSERVER=g31;DB_LOCALE=zh_CN.GB18030-2000;CLIENT_LOCALE=zh_CN.GB18030-2000;NEWCODESET=utf8,GB18030-2000,5488;IFX_LOCK_MODE_WAIT=30";
字符转换测试小结
//一句话: NEWCODESET的第一个字段是JDK存取数据的编码,它等于你的终端的编码,或者说它等于你的jdk的编码。
//两句话: 我们平常说的数据库的字符集,其实准确的说是数据库校验字符集,它是做校验的,它尽量是实际存储的表的字符集。
//三句话: 推荐校验字符集和终端字符集保持统一字符集,那么就不需要NEWCODESET了。
//四句话: 为了防止终端字符集把不同的数据编码存入表中,可以开启NEWCODESET,但要三个字段相同。
//五句话: 如果没有设置NEWCODESET那么,默认终端或jdk字符集。
//最后一句: 过滤器不能关,关了表里的编码很乱。要保证过滤器的字符集和校验字符集一致,这样就避免了NEWCODESET的校验,这样就不会遇到'汪'字不能插入的问题。(入库时的校验只是为了出库时的正常,值校验并不实际转换。)
这种报错就是jdk的编码和jdbc里面设置的NEWCODESET的校验码不一致
java.sql.SQLException: An illegal character has been found in the statement. at com.gbasedbt.util.IfxErrMsg.getSQLException(IfxErrMsg.java:408) at com.gbasedbt.jdbc.IfxSqli.a(IfxSqli.java:3572) at com.gbasedbt.jdbc.IfxSqli.D(IfxSqli.java:3852) at com.gbasedbt.jdbc.IfxSqli.dispatchMsg(IfxSqli.java:273
//servletRequest.setCharacterEncoding("UTF-8");
servletRequest.setCharacterEncoding("GB18030-2000");
和
//NEWCODESET=utf8,GB18030-2000,5488
NEWCODESET=GB18030-2000,utf8,57372
需要对应。
这种校验是好事, 如果你不校验,那么你的数据是什么编码会很乱,且无法维护统一编码。
所以很简单:
- 来啦一个数要存,我设置了NEWCODESET,那么把这个数据从JDK中取到,把他从NEWCODE转成校验字符集给到表存储。
- 来啦一个要取数,我设置了NEWCODESET, 那么我把你存储的这个字符取出来,把他从校验字符集转换成NEWCODE给到JDK结束。
- CLIENT_LOCALE对于jdbc不起作用,可以省略,或保持和DB_LOCLAE一致。
String url = "jdbc:Informix-sqli://10.127.1.11:8001/testdb: InformixSERVER=servername;user=user;password=password; DB_LOCALE=zh_CN.gb;CLIENT_LOCALE=zh_CN.gb";破坏测试-往jbk库里面插入utf8编码的数据
//这样可以往jbk库里面插入utf8编码的数据:“汪伟”能插入,“汪”不能插入。 jdbc:gbasedbt-sqli://1.1.1.3:9031/gbk:GBASEDBTSERVER=g31;DB_LOCALE=zh_CN.GB18030-2000;CLIENT_LOCALE=zh_CN.GB18030-2000;NEWCODESET=utf8,GB18030-2000,5488;IFX_LOCK_MODE_WAIT=30



