https://www.jetbrains.com/idea/download/other.html 靠下位置有,已经下载到“下载目录”
https://www.oracle.com/java/technologies/downloads/#java8 考下位置有,已经下载到“下载目录”
Help -> Edit Custom VM Options
来通过 IDEA 修改 idea.vmoptions
文件, 在末尾添加解补丁:-javaagent:D:\\IDEA30TRIAL\FineAgent.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:\IDEA30TRIAL\ActivationCode.txt的注册码复制填进去
破解完成。
注明:自动导入包和删包: 文件-设置-编辑-常规-自动导入
https://tomcat.apache.org/download-80.cgi
解压即安装:安装目录 D:\install\apache-tomcat-8.5.78-windows-x64\apache-tomcat-8.5.78
启动 start.bat
停止 stop.bat
把你的war包放在 D:\install\apache-tomcat-8.5.78-windows-x64\apache-tomcat-8.5.78\webapps 目录下即可
1、tomcat窗口中内容中文乱码解决:
找到tomcat下conf文件夹下的logging.properties文件,打开后找到
java.util.logging.ConsoleHandler.encoding = UTF-8,将其修改为
java.util.logging.ConsoleHandler.encoding = GBK
注明: 直接把这个安装目录上传到linux上,页可以使用,使用sh启停。
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项目
右键工程
Open module setging 模块设置
Libraries
+java
打开目录D:\install\apache-tomcat-8.5.78-windows-x64\apache-tomcat-8.5.78\lib
添加jsp-api.jar和servlet-api.jar两个包
起名Name:lib
Apply - OK
新建包: 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); } }
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>servlet001servlet-name> <servlet-class>com.trey.servlet.Servlet001servlet-class> servlet> <servlet-mapping> <servlet-name>servlet001servlet-name> <url-pattern>/hellourl-pattern> servlet-mapping> web-app>
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:\go\src\webdemo\out\artifacts\webdemo)
(Directory Content好像不用做)
4、选择项目的 WebRoot目录 ,点击 ok
(Directory Content好像不用做)
5、回到主页面,点击 Build -> 选择 Build Artifacts -> 选择刚刚生成的artifact -> 点击 build
6、等待build结束,在指定的输出路径中拿到war包
(D:\go\src\webdemo\out\artifacts\webdemo\webdemo.war)
7、把war包上传到tomcat的webapps目录即可
如上
- WEB-INF 下新建目录 lib
- 把D:\jdbc\mysql\mysql-connector-java-5.1.42-bin.jar 复制到 lib
- 后续动作如上(添加tomcat的jar包)。
- 新建包 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正常。
/*
select * from mysql.user;
flush privileges;
*/
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; //实体类
注明:自动生成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<Student> findAll(){
ArrayList<Student> 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:\install\apache-tomcat-8.5.78-windows-x64\jakarta-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<Student> 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);
}
}
<%--
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" %>
添加记录
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();
}
}
}
@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() {
}
}
包 : 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();
}
}
}
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<Student> findAll(){
ArrayList<Student> 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);
}
}
}
<table>
<th>编号</th>
<th>姓名</th>
<th>成绩</th>
<th>注册日期</th>
<th>操作</th>
<c:forEach items="${list}" var="student">
<tr>
<td>${student.id}</td>
<td>${student.name}</td>
<td>${student.age}</td>
<td>${student.register}</td>
<td>
<a href="/student?method=delete&id=${student.id}">删除</a>
<a>修改</a>
</td>
</tr>
</c:forEach>
</table>
@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<Student> 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;
}
}
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);
}
}
学生管理系统
编号
姓名
成绩
注册日期
操作
${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<Student> 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;
}
}
<body>
<h1>修改记录</h1>
<form action="/student" method="post">
编号:<input type="text" name="id" value="${student.id}" readonly/><br/>
姓名:<input type="text" name="name" value="${student.name}"/><br/>
成绩:<input type="text" name="age" value="${student.age}"/><br/>
成绩:<input type="text" name="age" value="${student.register }" readonly/><br/>
<input type="hidden" name="method" value="update"/>
<input type="submit" value="修改">
</form>
</body>
网页操作,修改
@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;
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:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\1653302798049.png)]
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.<init>(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.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.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 进制值
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,则数据库就可以支持中文对象名。
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');
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();
}
}
}
简单省略
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
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
见上文过滤器
InformixDIR=/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'
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.gb
当以下两个条件都为真时,客户机应用程序自动在客户机和数据库代码集之间执行代码集转换:
客户机应用程序开始执行时,它会比较客户机和数据库语言环境的名称,以确定是否执行代码集转换。如果设置了 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"
数据库不能够脱离字符集独立存在,它一定属于某种字符集。
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;"
环境变量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);
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的校验,这样就不会遇到'汪'字不能插入的问题。(入库时的校验只是为了出库时的正常,值校验并不实际转换。)
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
需要对应。
这种校验是好事, 如果你不校验,那么你的数据是什么编码会很乱,且无法维护统一编码。
所以很简单:
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编码的数据:“汪伟”能插入,“汪”不能插入。
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